From a1596438a68921d2c9b1fdec70a720d38c85ca7d Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Fri, 25 May 2012 21:21:44 +0530 Subject: ext4fs ls load support Signed-off-by: Uma Shankar Signed-off-by: Manjunatha C Achar Signed-off-by: Iqbal Shareef Signed-off-by: Hakgoo Lee --- Makefile | 12 +- common/Makefile | 6 + common/cmd_ext2.c | 219 +----------- common/cmd_ext4.c | 96 +++++ common/cmd_ext_common.c | 259 ++++++++++++++ fs/Makefile | 5 +- fs/ext2/Makefile | 52 --- fs/ext2/dev.c | 131 ------- fs/ext2/ext2fs.c | 919 ------------------------------------------------ fs/ext4/Makefile | 54 +++ fs/ext4/dev.c | 145 ++++++++ fs/ext4/ext4_common.c | 875 +++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/ext4_common.h | 63 ++++ fs/ext4/ext4fs.c | 228 ++++++++++++ include/ext2fs.h | 81 ----- include/ext4fs.h | 132 +++++++ include/ext_common.h | 197 +++++++++++ 17 files changed, 2085 insertions(+), 1389 deletions(-) create mode 100644 common/cmd_ext4.c create mode 100644 common/cmd_ext_common.c delete mode 100644 fs/ext2/Makefile delete mode 100644 fs/ext2/dev.c delete mode 100644 fs/ext2/ext2fs.c create mode 100644 fs/ext4/Makefile create mode 100644 fs/ext4/dev.c create mode 100644 fs/ext4/ext4_common.c create mode 100644 fs/ext4/ext4_common.h create mode 100644 fs/ext4/ext4fs.c delete mode 100644 include/ext2fs.h create mode 100644 include/ext4fs.h create mode 100644 include/ext_common.h diff --git a/Makefile b/Makefile index 73c8e39..1c95833 100644 --- a/Makefile +++ b/Makefile @@ -245,9 +245,15 @@ ifeq ($(CONFIG_OF_EMBED),y) LIBS += dts/libdts.o endif LIBS += arch/$(ARCH)/lib/lib$(ARCH).o -LIBS += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \ - fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \ - fs/ubifs/libubifs.o fs/zfs/libzfs.o +LIBS += fs/cramfs/libcramfs.o \ + fs/ext4/libext4fs.o \ + fs/fat/libfat.o \ + fs/fdos/libfdos.o \ + fs/jffs2/libjffs2.o \ + fs/reiserfs/libreiserfs.o \ + fs/ubifs/libubifs.o \ + fs/yaffs2/libyaffs2.o \ + fs/zfs/libzfs.o LIBS += net/libnet.o LIBS += disk/libdisk.o LIBS += drivers/bios_emulator/libatibiosemu.o diff --git a/common/Makefile b/common/Makefile index 3d62775..4273484 100644 --- a/common/Makefile +++ b/common/Makefile @@ -86,7 +86,13 @@ COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o COBJS-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o +COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o +ifdef CONFIG_CMD_EXT4 +COBJS-y += cmd_ext_common.o +else +COBJS-$(CONFIG_CMD_EXT2) += cmd_ext_common.o +endif COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o diff --git a/common/cmd_ext2.c b/common/cmd_ext2.c index 79b1e2f..c27d9c7 100644 --- a/common/cmd_ext2.c +++ b/common/cmd_ext2.c @@ -1,4 +1,9 @@ /* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar + * Manjunatha C Achar + * (C) Copyright 2004 * esd gmbh * Reinhard Arlt @@ -33,225 +38,35 @@ * Ext2fs support */ #include -#include -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) -#include -#endif - -#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION) -#error DOS or EFI partition support must be selected -#endif - -/* #define EXT2_DEBUG */ - -#ifdef EXT2_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif +#include int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char *filename = "/"; - int dev=0; - int part=1; - char *ep; - block_dev_desc_t *dev_desc=NULL; - int part_length; - - if (argc < 3) - return CMD_RET_USAGE; - - dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - - if (dev_desc == NULL) { - printf ("\n** Block device %s %d not supported\n", argv[1], dev); - return 1; - } - - if (*ep) { - if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } - - if (argc == 4) - filename = argv[3]; - - PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename); - - if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) { - printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part); - ext2fs_close(); - return 1; - } - - if (!ext2fs_mount(part_length)) { - printf ("** Bad ext2 partition or disk - %s %d:%d **\n", argv[1], dev, part); - ext2fs_close(); - return 1; - } - - if (ext2fs_ls (filename)) { - printf ("** Error ext2fs_ls() **\n"); - ext2fs_close(); - return 1; - }; - - ext2fs_close(); + if (do_ext_ls(cmdtp, flag, argc, argv)) + return -1; return 0; } -U_BOOT_CMD( - ext2ls, 4, 1, do_ext2ls, - "list files in a directory (default /)", - " [directory]\n" - " - list files from 'dev' on 'interface' in a 'directory'" -); - /****************************************************************************** * Ext2fs boot command intepreter. Derived from diskboot */ int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char *filename = NULL; - char *ep; - int dev, part = 1; - ulong addr = 0, part_length; - int filelen; - disk_partition_t info; - block_dev_desc_t *dev_desc = NULL; - char buf [12]; - unsigned long count; - char *addr_str; - - switch (argc) { - case 3: - addr_str = getenv("loadaddr"); - if (addr_str != NULL) - addr = simple_strtoul (addr_str, NULL, 16); - else - addr = CONFIG_SYS_LOAD_ADDR; - - filename = getenv ("bootfile"); - count = 0; - break; - case 4: - addr = simple_strtoul (argv[3], NULL, 16); - filename = getenv ("bootfile"); - count = 0; - break; - case 5: - addr = simple_strtoul (argv[3], NULL, 16); - filename = argv[4]; - count = 0; - break; - case 6: - addr = simple_strtoul (argv[3], NULL, 16); - filename = argv[4]; - count = simple_strtoul (argv[5], NULL, 16); - break; - - default: - return CMD_RET_USAGE; - } - - if (!filename) { - puts ("** No boot file defined **\n"); - return 1; - } - - dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - if (dev_desc==NULL) { - printf ("** Block device %s %d not supported\n", argv[1], dev); - return 1; - } - if (*ep) { - if (*ep != ':') { - puts ("** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } - - PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part); - - if (part != 0) { - if (get_partition_info (dev_desc, part, &info)) { - printf ("** Bad partition %d **\n", part); - return 1; - } - - if (strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) { - printf ("** Invalid partition type \"%.32s\"" - " (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - return 1; - } - printf ("Loading file \"%s\" " - "from %s device %d:%d (%.32s)\n", - filename, - argv[1], dev, part, info.name); - } else { - printf ("Loading file \"%s\" from %s device %d\n", - filename, argv[1], dev); - } - - - if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) { - printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part); - ext2fs_close(); - return 1; - } - - if (!ext2fs_mount(part_length)) { - printf ("** Bad ext2 partition or disk - %s %d:%d **\n", - argv[1], dev, part); - ext2fs_close(); - return 1; - } - - filelen = ext2fs_open(filename); - if (filelen < 0) { - printf("** File not found %s\n", filename); - ext2fs_close(); - return 1; - } - if ((count < filelen) && (count != 0)) { - filelen = count; - } - - if (ext2fs_read((char *)addr, filelen) != filelen) { - printf("** Unable to read \"%s\" from %s %d:%d **\n", - filename, argv[1], dev, part); - ext2fs_close(); - return 1; - } - - ext2fs_close(); - - /* Loading ok, update default load address */ - load_addr = addr; - - printf ("%d bytes read\n", filelen); - sprintf(buf, "%X", filelen); - setenv("filesize", buf); + if (do_ext_load(cmdtp, flag, argc, argv)) + return -1; return 0; } U_BOOT_CMD( + ext2ls, 4, 1, do_ext2ls, + "list files in a directory (default /)", + " [directory]\n" + " - list files from 'dev' on 'interface' in a 'directory'" +); + +U_BOOT_CMD( ext2load, 6, 0, do_ext2load, "load binary file from a Ext2 filesystem", " [addr] [filename] [bytes]\n" diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c new file mode 100644 index 0000000..3298fee --- /dev/null +++ b/common/cmd_ext4.c @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar + * Manjunatha C Achar + * + * Ext4fs support + * made from existing cmd_ext2.c file of Uboot + * + * (C) Copyright 2004 + * esd gmbh + * Reinhard Arlt + * + * made from cmd_reiserfs by + * + * (C) Copyright 2003 - 2004 + * Sysgo Real-Time Solutions, AG + * Pavel Bartusek + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* + * Changelog: + * 0.1 - Newly created file for ext4fs support. Taken from cmd_ext2.c + * file in uboot. Added ext4fs ls load and write support. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) +#include +#endif + +#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION) +#error DOS or EFI partition support must be selected +#endif + +uint64_t total_sector; +uint64_t part_offset; + +#define DOS_PART_MAGIC_OFFSET 0x1fe +#define DOS_FS_TYPE_OFFSET 0x36 +#define DOS_FS32_TYPE_OFFSET 0x52 + +int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + if (do_ext_load(cmdtp, flag, argc, argv)) + return -1; + + return 0; +} + +int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + if (do_ext_ls(cmdtp, flag, argc, argv)) + return -1; + + return 0; +} + +U_BOOT_CMD(ext4ls, 4, 1, do_ext4_ls, + "list files in a directory (default /)", + " [directory]\n" + " - list files from 'dev' on 'interface' in a 'directory'"); + +U_BOOT_CMD(ext4load, 6, 0, do_ext4_load, + "load binary file from a Ext4 filesystem", + " [addr] [filename] [bytes]\n" + " - load binary file 'filename' from 'dev' on 'interface'\n" + " to address 'addr' from ext4 filesystem"); diff --git a/common/cmd_ext_common.c b/common/cmd_ext_common.c new file mode 100644 index 0000000..56ee9a5 --- /dev/null +++ b/common/cmd_ext_common.c @@ -0,0 +1,259 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT2/4 filesystem implementation in Uboot by + * Uma Shankar + * Manjunatha C Achar + * + * Ext4fs support + * made from existing cmd_ext2.c file of Uboot + * + * (C) Copyright 2004 + * esd gmbh + * Reinhard Arlt + * + * made from cmd_reiserfs by + * + * (C) Copyright 2003 - 2004 + * Sysgo Real-Time Solutions, AG + * Pavel Bartusek + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* + * Changelog: + * 0.1 - Newly created file for ext4fs support. Taken from cmd_ext2.c + * file in uboot. Added ext4fs ls load and write support. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) +#include +#endif + +#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION) +#error DOS or EFI partition support must be selected +#endif + +#define DOS_PART_MAGIC_OFFSET 0x1fe +#define DOS_FS_TYPE_OFFSET 0x36 +#define DOS_FS32_TYPE_OFFSET 0x52 + +int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + char *filename = NULL; + char *ep; + int dev; + unsigned long part = 1; + ulong addr = 0; + ulong part_length; + int filelen; + disk_partition_t info; + struct ext_filesystem *fs; + char buf[12]; + unsigned long count; + const char *addr_str; + + count = 0; + addr = simple_strtoul(argv[3], NULL, 16); + filename = getenv("bootfile"); + switch (argc) { + case 3: + addr_str = getenv("loadaddr"); + if (addr_str != NULL) + addr = simple_strtoul(addr_str, NULL, 16); + else + addr = CONFIG_SYS_LOAD_ADDR; + + break; + case 4: + break; + case 5: + filename = argv[4]; + break; + case 6: + filename = argv[4]; + count = simple_strtoul(argv[5], NULL, 16); + break; + + default: + return cmd_usage(cmdtp); + } + + if (!filename) { + puts("** No boot file defined **\n"); + return 1; + } + + dev = (int)simple_strtoul(argv[2], &ep, 16); + ext4_dev_desc = get_dev(argv[1], dev); + if (ext4_dev_desc == NULL) { + printf("** Block device %s %d not supported\n", argv[1], dev); + return 1; + } + if (init_fs(ext4_dev_desc)) + return 1; + + fs = get_fs(); + if (*ep) { + if (*ep != ':') { + puts("** Invalid boot device, use `dev[:part]' **\n"); + goto fail; + } + part = simple_strtoul(++ep, NULL, 16); + } + + if (part != 0) { + if (get_partition_info(fs->dev_desc, part, &info)) { + printf("** Bad partition %lu **\n", part); + goto fail; + } + + if (strncmp((char *)info.type, BOOT_PART_TYPE, + strlen(BOOT_PART_TYPE)) != 0) { + printf("** Invalid partition type \"%s\"" + " (expect \"" BOOT_PART_TYPE "\")\n", info.type); + goto fail; + } + printf("Loading file \"%s\" " + "from %s device %d:%lu %s\n", + filename, argv[1], dev, part, info.name); + } else { + printf("Loading file \"%s\" from %s device %d\n", + filename, argv[1], dev); + } + + part_length = ext4fs_set_blk_dev(fs->dev_desc, part); + if (part_length == 0) { + printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part); + ext4fs_close(); + goto fail; + } + + if (!ext4fs_mount(part_length)) { + printf("** Bad ext2 partition or disk - %s %d:%lu **\n", + argv[1], dev, part); + ext4fs_close(); + goto fail; + } + + filelen = ext4fs_open(filename); + if (filelen < 0) { + printf("** File not found %s\n", filename); + ext4fs_close(); + goto fail; + } + if ((count < filelen) && (count != 0)) + filelen = count; + + if (ext4fs_read((char *)addr, filelen) != filelen) { + printf("** Unable to read \"%s\" from %s %d:%lu **\n", + filename, argv[1], dev, part); + ext4fs_close(); + goto fail; + } + + ext4fs_close(); + deinit_fs(fs->dev_desc); + /* Loading ok, update default load address */ + load_addr = addr; + + printf("%d bytes read\n", filelen); + sprintf(buf, "%X", filelen); + setenv("filesize", buf); + + return 0; +fail: + deinit_fs(fs->dev_desc); + return 1; +} + +int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + const char *filename = "/"; + int dev; + unsigned long part = 1; + char *ep; + struct ext_filesystem *fs; + int part_length; + if (argc < 3) + return cmd_usage(cmdtp); + + dev = (int)simple_strtoul(argv[2], &ep, 16); + + ext4_dev_desc = get_dev(argv[1], dev); + + if (ext4_dev_desc == NULL) { + printf("\n** Block device %s %d not supported\n", argv[1], dev); + return 1; + } + + if (init_fs(ext4_dev_desc)) + return 1; + + fs = get_fs(); + if (*ep) { + if (*ep != ':') { + puts("\n** Invalid boot device, use `dev[:part]' **\n"); + goto fail; + } + part = simple_strtoul(++ep, NULL, 16); + } + + if (argc == 4) + filename = argv[3]; + + part_length = ext4fs_set_blk_dev(fs->dev_desc, part); + if (part_length == 0) { + printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part); + ext4fs_close(); + goto fail; + } + + if (!ext4fs_mount(part_length)) { + printf("** Bad ext2 partition or disk - %s %d:%lu **\n", + argv[1], dev, part); + ext4fs_close(); + goto fail; + } + + if (ext4fs_ls(filename)) { + printf("** Error extfs_ls() **\n"); + ext4fs_close(); + goto fail; + }; + + ext4fs_close(); + deinit_fs(fs->dev_desc); + return 0; + +fail: + deinit_fs(fs->dev_desc); + return 1; +} diff --git a/fs/Makefile b/fs/Makefile index 28da76e..901e189 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -23,7 +23,10 @@ # subdirs-$(CONFIG_CMD_CRAMFS) := cramfs -subdirs-$(CONFIG_CMD_EXT2) += ext2 +subdirs-$(CONFIG_CMD_EXT4) += ext4 +ifndef CONFIG_CMD_EXT4 +subdirs-$(CONFIG_CMD_EXT2) += ext4 +endif subdirs-$(CONFIG_CMD_FAT) += fat subdirs-$(CONFIG_CMD_FDOS) += fdos subdirs-$(CONFIG_CMD_JFFS2) += jffs2 diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile deleted file mode 100644 index 3c65d25..0000000 --- a/fs/ext2/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2003 -# Pavel Bartusek, Sysgo Real-Time Solutions AG, pba@sysgo.de -# -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)libext2fs.o - -AOBJS = -COBJS-$(CONFIG_CMD_EXT2) := ext2fs.o dev.o - -SRCS := $(AOBJS:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS-y)) - -#CPPFLAGS += - -all: $(LIB) $(AOBJS) - -$(LIB): $(obj).depend $(OBJS) - $(call cmd_link_o_target, $(OBJS)) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/fs/ext2/dev.c b/fs/ext2/dev.c deleted file mode 100644 index 874e211..0000000 --- a/fs/ext2/dev.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * (C) Copyright 2004 - * esd gmbh - * Reinhard Arlt - * - * based on code of fs/reiserfs/dev.c by - * - * (C) Copyright 2003 - 2004 - * Sysgo AG, , Pavel Bartusek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - - -#include -#include -#include - -static block_dev_desc_t *ext2fs_block_dev_desc; -static disk_partition_t part_info; - -int ext2fs_set_blk_dev(block_dev_desc_t *rbdd, int part) -{ - ext2fs_block_dev_desc = rbdd; - - if (part == 0) { - /* disk doesn't use partition table */ - part_info.start = 0; - part_info.size = rbdd->lba; - part_info.blksz = rbdd->blksz; - } else { - if (get_partition_info - (ext2fs_block_dev_desc, part, &part_info)) { - return 0; - } - } - return part_info.size; -} - - -int ext2fs_devread(int sector, int byte_offset, int byte_len, char *buf) -{ - ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, SECTOR_SIZE); - unsigned sectors; - - /* - * Check partition boundaries - */ - if ((sector < 0) || - ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >= - part_info.size)) { - /* errnum = ERR_OUTSIDE_PART; */ - printf(" ** %s read outside partition sector %d\n", - __func__, - sector); - return 0; - } - - /* - * Get the read to the beginning of a partition. - */ - sector += byte_offset >> SECTOR_BITS; - byte_offset &= SECTOR_SIZE - 1; - - debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len); - - if (ext2fs_block_dev_desc == NULL) { - printf(" ** %s Invalid Block Device Descriptor (NULL)\n", - __func__); - return 0; - } - - if (byte_offset != 0) { - /* read first part which isn't aligned with start of sector */ - if (ext2fs_block_dev_desc-> - block_read(ext2fs_block_dev_desc->dev, - part_info.start + sector, 1, - (unsigned long *) sec_buf) != 1) { - printf(" ** %s read error **\n", __func__); - return 0; - } - memcpy(buf, sec_buf + byte_offset, - min(SECTOR_SIZE - byte_offset, byte_len)); - buf += min(SECTOR_SIZE - byte_offset, byte_len); - byte_len -= min(SECTOR_SIZE - byte_offset, byte_len); - sector++; - } - - /* read sector aligned part */ - sectors = byte_len / SECTOR_SIZE; - - if (sectors > 0) { - if (ext2fs_block_dev_desc->block_read( - ext2fs_block_dev_desc->dev, - part_info.start + sector, - sectors, - (unsigned long *) buf) != sectors) { - printf(" ** %s read error - block\n", __func__); - return 0; - } - - buf += sectors * SECTOR_SIZE; - byte_len -= sectors * SECTOR_SIZE; - sector += sectors; - } - - if (byte_len != 0) { - /* read rest of data which are not in whole sector */ - if (ext2fs_block_dev_desc-> - block_read(ext2fs_block_dev_desc->dev, - part_info.start + sector, 1, - (unsigned long *) sec_buf) != 1) { - printf(" ** %s read error - last part\n", __func__); - return 0; - } - memcpy(buf, sec_buf, byte_len); - } - return 1; -} diff --git a/fs/ext2/ext2fs.c b/fs/ext2/ext2fs.c deleted file mode 100644 index 418404e..0000000 --- a/fs/ext2/ext2fs.c +++ /dev/null @@ -1,919 +0,0 @@ -/* - * (C) Copyright 2004 - * esd gmbh - * Reinhard Arlt - * - * based on code from grub2 fs/ext2.c and fs/fshelp.c by - * - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include - -extern int ext2fs_devread (int sector, int byte_offset, int byte_len, - char *buf); - -/* Magic value used to identify an ext2 filesystem. */ -#define EXT2_MAGIC 0xEF53 -/* Amount of indirect blocks in an inode. */ -#define INDIRECT_BLOCKS 12 -/* Maximum lenght of a pathname. */ -#define EXT2_PATH_MAX 4096 -/* Maximum nesting of symlinks, used to prevent a loop. */ -#define EXT2_MAX_SYMLINKCNT 8 - -/* Filetype used in directory entry. */ -#define FILETYPE_UNKNOWN 0 -#define FILETYPE_REG 1 -#define FILETYPE_DIRECTORY 2 -#define FILETYPE_SYMLINK 7 - -/* Filetype information as used in inodes. */ -#define FILETYPE_INO_MASK 0170000 -#define FILETYPE_INO_REG 0100000 -#define FILETYPE_INO_DIRECTORY 0040000 -#define FILETYPE_INO_SYMLINK 0120000 - -/* Bits used as offset in sector */ -#define DISK_SECTOR_BITS 9 - -/* Log2 size of ext2 block in 512 blocks. */ -#define LOG2_EXT2_BLOCK_SIZE(data) (__le32_to_cpu (data->sblock.log2_block_size) + 1) - -/* Log2 size of ext2 block in bytes. */ -#define LOG2_BLOCK_SIZE(data) (__le32_to_cpu (data->sblock.log2_block_size) + 10) - -/* The size of an ext2 block in bytes. */ -#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data)) - -/* The ext2 superblock. */ -struct ext2_sblock { - uint32_t total_inodes; - uint32_t total_blocks; - uint32_t reserved_blocks; - uint32_t free_blocks; - uint32_t free_inodes; - uint32_t first_data_block; - uint32_t log2_block_size; - uint32_t log2_fragment_size; - uint32_t blocks_per_group; - uint32_t fragments_per_group; - uint32_t inodes_per_group; - uint32_t mtime; - uint32_t utime; - uint16_t mnt_count; - uint16_t max_mnt_count; - uint16_t magic; - uint16_t fs_state; - uint16_t error_handling; - uint16_t minor_revision_level; - uint32_t lastcheck; - uint32_t checkinterval; - uint32_t creator_os; - uint32_t revision_level; - uint16_t uid_reserved; - uint16_t gid_reserved; - uint32_t first_inode; - uint16_t inode_size; - uint16_t block_group_number; - uint32_t feature_compatibility; - uint32_t feature_incompat; - uint32_t feature_ro_compat; - uint32_t unique_id[4]; - char volume_name[16]; - char last_mounted_on[64]; - uint32_t compression_info; -}; - -/* The ext2 blockgroup. */ -struct ext2_block_group { - uint32_t block_id; - uint32_t inode_id; - uint32_t inode_table_id; - uint16_t free_blocks; - uint16_t free_inodes; - uint16_t used_dir_cnt; - uint32_t reserved[3]; -}; - -/* The ext2 inode. */ -struct ext2_inode { - uint16_t mode; - uint16_t uid; - uint32_t size; - uint32_t atime; - uint32_t ctime; - uint32_t mtime; - uint32_t dtime; - uint16_t gid; - uint16_t nlinks; - uint32_t blockcnt; /* Blocks of 512 bytes!! */ - uint32_t flags; - uint32_t osd1; - union { - struct datablocks { - uint32_t dir_blocks[INDIRECT_BLOCKS]; - uint32_t indir_block; - uint32_t double_indir_block; - uint32_t tripple_indir_block; - } blocks; - char symlink[60]; - } b; - uint32_t version; - uint32_t acl; - uint32_t dir_acl; - uint32_t fragment_addr; - uint32_t osd2[3]; -}; - -/* The header of an ext2 directory entry. */ -struct ext2_dirent { - uint32_t inode; - uint16_t direntlen; - uint8_t namelen; - uint8_t filetype; -}; - -struct ext2fs_node { - struct ext2_data *data; - struct ext2_inode inode; - int ino; - int inode_read; -}; - -/* Information about a "mounted" ext2 filesystem. */ -struct ext2_data { - struct ext2_sblock sblock; - struct ext2_inode *inode; - struct ext2fs_node diropen; -}; - - -typedef struct ext2fs_node *ext2fs_node_t; - -struct ext2_data *ext2fs_root = NULL; -ext2fs_node_t ext2fs_file = NULL; -int symlinknest = 0; -uint32_t *indir1_block = NULL; -int indir1_size = 0; -int indir1_blkno = -1; -uint32_t *indir2_block = NULL; -int indir2_size = 0; -int indir2_blkno = -1; -static unsigned int inode_size; - - -static int ext2fs_blockgroup - (struct ext2_data *data, int group, struct ext2_block_group *blkgrp) { - unsigned int blkno; - unsigned int blkoff; - unsigned int desc_per_blk; - - desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group); - - blkno = __le32_to_cpu(data->sblock.first_data_block) + 1 + - group / desc_per_blk; - blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group); -#ifdef DEBUG - printf ("ext2fs read %d group descriptor (blkno %d blkoff %d)\n", - group, blkno, blkoff); -#endif - return (ext2fs_devread (blkno << LOG2_EXT2_BLOCK_SIZE(data), - blkoff, sizeof(struct ext2_block_group), (char *)blkgrp)); - -} - - -static int ext2fs_read_inode - (struct ext2_data *data, int ino, struct ext2_inode *inode) { - struct ext2_block_group blkgrp; - struct ext2_sblock *sblock = &data->sblock; - int inodes_per_block; - int status; - - unsigned int blkno; - unsigned int blkoff; - -#ifdef DEBUG - printf ("ext2fs read inode %d, inode_size %d\n", ino, inode_size); -#endif - /* It is easier to calculate if the first inode is 0. */ - ino--; - status = ext2fs_blockgroup (data, ino / __le32_to_cpu - (sblock->inodes_per_group), &blkgrp); - if (status == 0) { - return (0); - } - - inodes_per_block = EXT2_BLOCK_SIZE(data) / inode_size; - - blkno = __le32_to_cpu (blkgrp.inode_table_id) + - (ino % __le32_to_cpu (sblock->inodes_per_group)) - / inodes_per_block; - blkoff = (ino % inodes_per_block) * inode_size; -#ifdef DEBUG - printf ("ext2fs read inode blkno %d blkoff %d\n", blkno, blkoff); -#endif - /* Read the inode. */ - status = ext2fs_devread (blkno << LOG2_EXT2_BLOCK_SIZE (data), blkoff, - sizeof (struct ext2_inode), (char *) inode); - if (status == 0) { - return (0); - } - - return (1); -} - - -void ext2fs_free_node (ext2fs_node_t node, ext2fs_node_t currroot) { - if ((node != &ext2fs_root->diropen) && (node != currroot)) { - free (node); - } -} - - -static int ext2fs_read_block (ext2fs_node_t node, int fileblock) { - struct ext2_data *data = node->data; - struct ext2_inode *inode = &node->inode; - int blknr; - int blksz = EXT2_BLOCK_SIZE (data); - int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data); - int status; - - /* Direct blocks. */ - if (fileblock < INDIRECT_BLOCKS) { - blknr = __le32_to_cpu (inode->b.blocks.dir_blocks[fileblock]); - } - /* Indirect. */ - else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) { - if (indir1_block == NULL) { - indir1_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - indir1_blkno = -1; - } - if (blksz != indir1_size) { - free (indir1_block); - indir1_block = NULL; - indir1_size = 0; - indir1_blkno = -1; - indir1_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - } - if ((__le32_to_cpu (inode->b.blocks.indir_block) << - log2_blksz) != indir1_blkno) { - status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz, - 0, blksz, - (char *) indir1_block); - if (status == 0) { - printf ("** ext2fs read block (indir 1) failed. **\n"); - return (0); - } - indir1_blkno = - __le32_to_cpu (inode->b.blocks. - indir_block) << log2_blksz; - } - blknr = __le32_to_cpu (indir1_block - [fileblock - INDIRECT_BLOCKS]); - } - /* Double indirect. */ - else if (fileblock < - (INDIRECT_BLOCKS + (blksz / 4 * (blksz / 4 + 1)))) { - unsigned int perblock = blksz / 4; - unsigned int rblock = fileblock - (INDIRECT_BLOCKS - + blksz / 4); - - if (indir1_block == NULL) { - indir1_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 2 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - indir1_blkno = -1; - } - if (blksz != indir1_size) { - free (indir1_block); - indir1_block = NULL; - indir1_size = 0; - indir1_blkno = -1; - indir1_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir1_block == NULL) { - printf ("** ext2fs read block (indir 2 1) malloc failed. **\n"); - return (-1); - } - indir1_size = blksz; - } - if ((__le32_to_cpu (inode->b.blocks.double_indir_block) << - log2_blksz) != indir1_blkno) { - status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz, - 0, blksz, - (char *) indir1_block); - if (status == 0) { - printf ("** ext2fs read block (indir 2 1) failed. **\n"); - return (-1); - } - indir1_blkno = - __le32_to_cpu (inode->b.blocks.double_indir_block) << log2_blksz; - } - - if (indir2_block == NULL) { - indir2_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir2_block == NULL) { - printf ("** ext2fs read block (indir 2 2) malloc failed. **\n"); - return (-1); - } - indir2_size = blksz; - indir2_blkno = -1; - } - if (blksz != indir2_size) { - free (indir2_block); - indir2_block = NULL; - indir2_size = 0; - indir2_blkno = -1; - indir2_block = (uint32_t *) memalign(ARCH_DMA_MINALIGN, - blksz); - if (indir2_block == NULL) { - printf ("** ext2fs read block (indir 2 2) malloc failed. **\n"); - return (-1); - } - indir2_size = blksz; - } - if ((__le32_to_cpu (indir1_block[rblock / perblock]) << - log2_blksz) != indir2_blkno) { - status = ext2fs_devread (__le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz, - 0, blksz, - (char *) indir2_block); - if (status == 0) { - printf ("** ext2fs read block (indir 2 2) failed. **\n"); - return (-1); - } - indir2_blkno = - __le32_to_cpu (indir1_block[rblock / perblock]) << log2_blksz; - } - blknr = __le32_to_cpu (indir2_block[rblock % perblock]); - } - /* Tripple indirect. */ - else { - printf ("** ext2fs doesn't support tripple indirect blocks. **\n"); - return (-1); - } -#ifdef DEBUG - printf ("ext2fs_read_block %08x\n", blknr); -#endif - return (blknr); -} - - -int ext2fs_read_file - (ext2fs_node_t node, int pos, unsigned int len, char *buf) { - int i; - int blockcnt; - int log2blocksize = LOG2_EXT2_BLOCK_SIZE (node->data); - int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS); - unsigned int filesize = __le32_to_cpu(node->inode.size); - - /* Adjust len so it we can't read past the end of the file. */ - if (len > filesize) { - len = filesize; - } - blockcnt = ((len + pos) + blocksize - 1) / blocksize; - - for (i = pos / blocksize; i < blockcnt; i++) { - int blknr; - int blockoff = pos % blocksize; - int blockend = blocksize; - - int skipfirst = 0; - - blknr = ext2fs_read_block (node, i); - if (blknr < 0) { - return (-1); - } - - /* Last block. */ - if (i == blockcnt - 1) { - blockend = (len + pos) % blocksize; - - /* The last portion is exactly blocksize. */ - if (!blockend) { - blockend = blocksize; - } - } - - /* First block. */ - if (i == pos / blocksize) { - skipfirst = blockoff; - blockend -= skipfirst; - } - - /* grab middle blocks in one go */ - if (i != pos / blocksize && i < blockcnt - 1 && blockcnt > 3) { - int oldblk = blknr; - int blocknxt = ext2fs_read_block(node, i + 1); - while (i < blockcnt - 1) { - if (blocknxt == (oldblk + 1)) { - oldblk = blocknxt; - i++; - } else { - blocknxt = ext2fs_read_block(node, i); - break; - } - blocknxt = ext2fs_read_block(node, i); - } - - if (oldblk == blknr) - blockend = blocksize; - else - blockend = (1 + blocknxt - blknr) * blocksize; - } - - blknr = blknr << log2blocksize; - - /* If the block number is 0 this block is not stored on disk but - is zero filled instead. */ - if (blknr) { - int status; - - status = ext2fs_devread (blknr, skipfirst, blockend, buf); - if (status == 0) { - return (-1); - } - } else { - memset (buf, 0, blocksize - skipfirst); - } - buf += blockend - skipfirst; - } - return (len); -} - - -static int ext2fs_iterate_dir (ext2fs_node_t dir, char *name, ext2fs_node_t * fnode, int *ftype) -{ - unsigned int fpos = 0; - int status; - struct ext2fs_node *diro = (struct ext2fs_node *) dir; - -#ifdef DEBUG - if (name != NULL) - printf ("Iterate dir %s\n", name); -#endif /* of DEBUG */ - if (!diro->inode_read) { - status = ext2fs_read_inode (diro->data, diro->ino, - &diro->inode); - if (status == 0) { - return (0); - } - } - /* Search the file. */ - while (fpos < __le32_to_cpu (diro->inode.size)) { - struct ext2_dirent dirent; - - status = ext2fs_read_file (diro, fpos, - sizeof (struct ext2_dirent), - (char *) &dirent); - if (status < 1) { - return (0); - } - if (dirent.namelen != 0) { - char filename[dirent.namelen + 1]; - ext2fs_node_t fdiro; - int type = FILETYPE_UNKNOWN; - - status = ext2fs_read_file (diro, - fpos + sizeof (struct ext2_dirent), - dirent.namelen, filename); - if (status < 1) { - return (0); - } - fdiro = malloc (sizeof (struct ext2fs_node)); - if (!fdiro) { - return (0); - } - - fdiro->data = diro->data; - fdiro->ino = __le32_to_cpu (dirent.inode); - - filename[dirent.namelen] = '\0'; - - if (dirent.filetype != FILETYPE_UNKNOWN) { - fdiro->inode_read = 0; - - if (dirent.filetype == FILETYPE_DIRECTORY) { - type = FILETYPE_DIRECTORY; - } else if (dirent.filetype == - FILETYPE_SYMLINK) { - type = FILETYPE_SYMLINK; - } else if (dirent.filetype == FILETYPE_REG) { - type = FILETYPE_REG; - } - } else { - /* The filetype can not be read from the dirent, get it from inode */ - - status = ext2fs_read_inode (diro->data, - __le32_to_cpu(dirent.inode), - &fdiro->inode); - if (status == 0) { - free (fdiro); - return (0); - } - fdiro->inode_read = 1; - - if ((__le16_to_cpu (fdiro->inode.mode) & - FILETYPE_INO_MASK) == - FILETYPE_INO_DIRECTORY) { - type = FILETYPE_DIRECTORY; - } else if ((__le16_to_cpu (fdiro->inode.mode) - & FILETYPE_INO_MASK) == - FILETYPE_INO_SYMLINK) { - type = FILETYPE_SYMLINK; - } else if ((__le16_to_cpu (fdiro->inode.mode) - & FILETYPE_INO_MASK) == - FILETYPE_INO_REG) { - type = FILETYPE_REG; - } - } -#ifdef DEBUG - printf ("iterate >%s<\n", filename); -#endif /* of DEBUG */ - if ((name != NULL) && (fnode != NULL) - && (ftype != NULL)) { - if (strcmp (filename, name) == 0) { - *ftype = type; - *fnode = fdiro; - return (1); - } - } else { - if (fdiro->inode_read == 0) { - status = ext2fs_read_inode (diro->data, - __le32_to_cpu (dirent.inode), - &fdiro->inode); - if (status == 0) { - free (fdiro); - return (0); - } - fdiro->inode_read = 1; - } - switch (type) { - case FILETYPE_DIRECTORY: - printf (" "); - break; - case FILETYPE_SYMLINK: - printf (" "); - break; - case FILETYPE_REG: - printf (" "); - break; - default: - printf ("< ? > "); - break; - } - printf ("%10d %s\n", - __le32_to_cpu (fdiro->inode.size), - filename); - } - free (fdiro); - } - fpos += __le16_to_cpu (dirent.direntlen); - } - return (0); -} - - -static char *ext2fs_read_symlink (ext2fs_node_t node) { - char *symlink; - struct ext2fs_node *diro = node; - int status; - - if (!diro->inode_read) { - status = ext2fs_read_inode (diro->data, diro->ino, - &diro->inode); - if (status == 0) { - return (0); - } - } - symlink = malloc (__le32_to_cpu (diro->inode.size) + 1); - if (!symlink) { - return (0); - } - /* If the filesize of the symlink is bigger than - 60 the symlink is stored in a separate block, - otherwise it is stored in the inode. */ - if (__le32_to_cpu (diro->inode.size) <= 60) { - strncpy (symlink, diro->inode.b.symlink, - __le32_to_cpu (diro->inode.size)); - } else { - status = ext2fs_read_file (diro, 0, - __le32_to_cpu (diro->inode.size), - symlink); - if (status == 0) { - free (symlink); - return (0); - } - } - symlink[__le32_to_cpu (diro->inode.size)] = '\0'; - return (symlink); -} - - -int ext2fs_find_file1 - (const char *currpath, - ext2fs_node_t currroot, ext2fs_node_t * currfound, int *foundtype) { - char fpath[strlen (currpath) + 1]; - char *name = fpath; - char *next; - int status; - int type = FILETYPE_DIRECTORY; - ext2fs_node_t currnode = currroot; - ext2fs_node_t oldnode = currroot; - - strncpy (fpath, currpath, strlen (currpath) + 1); - - /* Remove all leading slashes. */ - while (*name == '/') { - name++; - } - if (!*name) { - *currfound = currnode; - return (1); - } - - for (;;) { - int found; - - /* Extract the actual part from the pathname. */ - next = strchr (name, '/'); - if (next) { - /* Remove all leading slashes. */ - while (*next == '/') { - *(next++) = '\0'; - } - } - - /* At this point it is expected that the current node is a directory, check if this is true. */ - if (type != FILETYPE_DIRECTORY) { - ext2fs_free_node (currnode, currroot); - return (0); - } - - oldnode = currnode; - - /* Iterate over the directory. */ - found = ext2fs_iterate_dir (currnode, name, &currnode, &type); - if (found == 0) { - return (0); - } - if (found == -1) { - break; - } - - /* Read in the symlink and follow it. */ - if (type == FILETYPE_SYMLINK) { - char *symlink; - - /* Test if the symlink does not loop. */ - if (++symlinknest == 8) { - ext2fs_free_node (currnode, currroot); - ext2fs_free_node (oldnode, currroot); - return (0); - } - - symlink = ext2fs_read_symlink (currnode); - ext2fs_free_node (currnode, currroot); - - if (!symlink) { - ext2fs_free_node (oldnode, currroot); - return (0); - } -#ifdef DEBUG - printf ("Got symlink >%s<\n", symlink); -#endif /* of DEBUG */ - /* The symlink is an absolute path, go back to the root inode. */ - if (symlink[0] == '/') { - ext2fs_free_node (oldnode, currroot); - oldnode = &ext2fs_root->diropen; - } - - /* Lookup the node the symlink points to. */ - status = ext2fs_find_file1 (symlink, oldnode, - &currnode, &type); - - free (symlink); - - if (status == 0) { - ext2fs_free_node (oldnode, currroot); - return (0); - } - } - - ext2fs_free_node (oldnode, currroot); - - /* Found the node! */ - if (!next || *next == '\0') { - *currfound = currnode; - *foundtype = type; - return (1); - } - name = next; - } - return (-1); -} - - -int ext2fs_find_file - (const char *path, - ext2fs_node_t rootnode, ext2fs_node_t * foundnode, int expecttype) { - int status; - int foundtype = FILETYPE_DIRECTORY; - - - symlinknest = 0; - if (!path) { - return (0); - } - - status = ext2fs_find_file1 (path, rootnode, foundnode, &foundtype); - if (status == 0) { - return (0); - } - /* Check if the node that was found was of the expected type. */ - if ((expecttype == FILETYPE_REG) && (foundtype != expecttype)) { - return (0); - } else if ((expecttype == FILETYPE_DIRECTORY) - && (foundtype != expecttype)) { - return (0); - } - return (1); -} - - -int ext2fs_ls (const char *dirname) { - ext2fs_node_t dirnode; - int status; - - if (ext2fs_root == NULL) { - return (0); - } - - status = ext2fs_find_file (dirname, &ext2fs_root->diropen, &dirnode, - FILETYPE_DIRECTORY); - if (status != 1) { - printf ("** Can not find directory. **\n"); - return (1); - } - ext2fs_iterate_dir (dirnode, NULL, NULL, NULL); - ext2fs_free_node (dirnode, &ext2fs_root->diropen); - return (0); -} - - -int ext2fs_open (const char *filename) { - ext2fs_node_t fdiro = NULL; - int status; - int len; - - if (ext2fs_root == NULL) { - return (-1); - } - ext2fs_file = NULL; - status = ext2fs_find_file (filename, &ext2fs_root->diropen, &fdiro, - FILETYPE_REG); - if (status == 0) { - goto fail; - } - if (!fdiro->inode_read) { - status = ext2fs_read_inode (fdiro->data, fdiro->ino, - &fdiro->inode); - if (status == 0) { - goto fail; - } - } - len = __le32_to_cpu (fdiro->inode.size); - ext2fs_file = fdiro; - return (len); - -fail: - ext2fs_free_node (fdiro, &ext2fs_root->diropen); - return (-1); -} - - -int ext2fs_close (void - ) { - if ((ext2fs_file != NULL) && (ext2fs_root != NULL)) { - ext2fs_free_node (ext2fs_file, &ext2fs_root->diropen); - ext2fs_file = NULL; - } - if (ext2fs_root != NULL) { - free (ext2fs_root); - ext2fs_root = NULL; - } - if (indir1_block != NULL) { - free (indir1_block); - indir1_block = NULL; - indir1_size = 0; - indir1_blkno = -1; - } - if (indir2_block != NULL) { - free (indir2_block); - indir2_block = NULL; - indir2_size = 0; - indir2_blkno = -1; - } - return (0); -} - - -int ext2fs_read (char *buf, unsigned len) { - int status; - - if (ext2fs_root == NULL) { - return (0); - } - - if (ext2fs_file == NULL) { - return (0); - } - - status = ext2fs_read_file (ext2fs_file, 0, len, buf); - return (status); -} - - -int ext2fs_mount (unsigned part_length) { - struct ext2_data *data; - int status; - - data = malloc (sizeof (struct ext2_data)); - if (!data) { - return (0); - } - /* Read the superblock. */ - status = ext2fs_devread (1 * 2, 0, sizeof (struct ext2_sblock), - (char *) &data->sblock); - if (status == 0) { - goto fail; - } - /* Make sure this is an ext2 filesystem. */ - if (__le16_to_cpu (data->sblock.magic) != EXT2_MAGIC) { - goto fail; - } - if (__le32_to_cpu(data->sblock.revision_level == 0)) { - inode_size = 128; - } else { - inode_size = __le16_to_cpu(data->sblock.inode_size); - } -#ifdef DEBUG - printf("EXT2 rev %d, inode_size %d\n", - __le32_to_cpu(data->sblock.revision_level), inode_size); -#endif - data->diropen.data = data; - data->diropen.ino = 2; - data->diropen.inode_read = 1; - data->inode = &data->diropen.inode; - - status = ext2fs_read_inode (data, 2, data->inode); - if (status == 0) { - goto fail; - } - - ext2fs_root = data; - - return (1); - -fail: - printf ("Failed to mount ext2 filesystem...\n"); - free (data); - ext2fs_root = NULL; - return (0); -} diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile new file mode 100644 index 0000000..7b7fcbd --- /dev/null +++ b/fs/ext4/Makefile @@ -0,0 +1,54 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2003 +# Pavel Bartusek, Sysgo Real-Time Solutions AG, pba@sysgo.de +# +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)libext4fs.o + +AOBJS = +COBJS-$(CONFIG_CMD_EXT4) := ext4fs.o ext4_common.o dev.o +ifndef CONFIG_CMD_EXT4 +COBJS-$(CONFIG_CMD_EXT2) := ext4fs.o ext4_common.o dev.o +endif + +SRCS := $(AOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS-y)) + + +all: $(LIB) $(AOBJS) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c new file mode 100644 index 0000000..fb62f24 --- /dev/null +++ b/fs/ext4/dev.c @@ -0,0 +1,145 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar + * Manjunatha C Achar + * + * made from existing ext2/dev.c file of Uboot + * (C) Copyright 2004 + * esd gmbh + * Reinhard Arlt + * + * based on code of fs/reiserfs/dev.c by + * + * (C) Copyright 2003 - 2004 + * Sysgo AG, , Pavel Bartusek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * Changelog: + * 0.1 - Newly created file for ext4fs support. Taken from + * fs/ext2/dev.c file in uboot. + */ + +#include +#include +#include + +static block_dev_desc_t *ext4fs_block_dev_desc; +static disk_partition_t part_info; + +int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part) +{ + ext4fs_block_dev_desc = rbdd; + + if (part == 0) { + /* disk doesn't use partition table */ + part_info.start = 0; + part_info.size = rbdd->lba; + part_info.blksz = rbdd->blksz; + } else { + if (get_partition_info(ext4fs_block_dev_desc, + part, &part_info)) + return 0; + } + return part_info.size; +} + +int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf) +{ + char sec_buf[SECTOR_SIZE]; + unsigned block_len; + + /* Check partition boundaries */ + if ((sector < 0) + || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >= + part_info.size)) { + printf("%s read outside partition %d\n", __func__, sector); + return 0; + } + + /* Get the read to the beginning of a partition */ + sector += byte_offset >> SECTOR_BITS; + byte_offset &= SECTOR_SIZE - 1; + + debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len); + + if (ext4fs_block_dev_desc == NULL) { + printf("** Invalid Block Device Descriptor (NULL)\n"); + return 0; + } + + if (byte_offset != 0) { + /* read first part which isn't aligned with start of sector */ + if (ext4fs_block_dev_desc-> + block_read(ext4fs_block_dev_desc->dev, + part_info.start + sector, 1, + (unsigned long *) sec_buf) != 1) { + printf(" ** ext2fs_devread() read error **\n"); + return 0; + } + memcpy(buf, sec_buf + byte_offset, + min(SECTOR_SIZE - byte_offset, byte_len)); + buf += min(SECTOR_SIZE - byte_offset, byte_len); + byte_len -= min(SECTOR_SIZE - byte_offset, byte_len); + sector++; + } + + if (byte_len == 0) + return 1; + + /* read sector aligned part */ + block_len = byte_len & ~(SECTOR_SIZE - 1); + + if (block_len == 0) { + u8 p[SECTOR_SIZE]; + + block_len = SECTOR_SIZE; + ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev, + part_info.start + sector, + 1, (unsigned long *)p); + memcpy(buf, p, byte_len); + return 1; + } + + if (ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev, + part_info.start + sector, + block_len / SECTOR_SIZE, + (unsigned long *) buf) != + block_len / SECTOR_SIZE) { + printf(" ** %s read error - block\n", __func__); + return 0; + } + block_len = byte_len & ~(SECTOR_SIZE - 1); + buf += block_len; + byte_len -= block_len; + sector += block_len / SECTOR_SIZE; + + if (byte_len != 0) { + /* read rest of data which are not in whole sector */ + if (ext4fs_block_dev_desc-> + block_read(ext4fs_block_dev_desc->dev, + part_info.start + sector, 1, + (unsigned long *) sec_buf) != 1) { + printf("* %s read error - last part\n", __func__); + return 0; + } + memcpy(buf, sec_buf, byte_len); + } + return 1; +} diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c new file mode 100644 index 0000000..2ddbb50 --- /dev/null +++ b/fs/ext4/ext4_common.c @@ -0,0 +1,875 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar + * Manjunatha C Achar + * + * ext4ls and ext4load : Based on ext2 ls load support in Uboot. + * + * (C) Copyright 2004 + * esd gmbh + * Reinhard Arlt + * + * based on code from grub2 fs/ext2.c and fs/fshelp.c by + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ext4_common.h" + +struct ext2_data *ext4fs_root; +struct ext2fs_node *ext4fs_file; +uint32_t *ext4fs_indir1_block; +int ext4fs_indir1_size; +int ext4fs_indir1_blkno = -1; +uint32_t *ext4fs_indir2_block; +int ext4fs_indir2_size; +int ext4fs_indir2_blkno = -1; + +uint32_t *ext4fs_indir3_block; +int ext4fs_indir3_size; +int ext4fs_indir3_blkno = -1; +struct ext2_inode *g_parent_inode; +static int symlinknest; + +static struct ext4_extent_header *ext4fs_get_extent_block + (struct ext2_data *data, char *buf, + struct ext4_extent_header *ext_block, + uint32_t fileblock, int log2_blksz) +{ + struct ext4_extent_idx *index; + unsigned long long block; + struct ext_filesystem *fs = get_fs(); + int i; + + while (1) { + index = (struct ext4_extent_idx *)(ext_block + 1); + + if (le32_to_cpu(ext_block->eh_magic) != EXT4_EXT_MAGIC) + return 0; + + if (ext_block->eh_depth == 0) + return ext_block; + i = -1; + do { + i++; + if (i >= le32_to_cpu(ext_block->eh_entries)) + break; + } while (fileblock > le32_to_cpu(index[i].ei_block)); + + if (--i < 0) + return 0; + + block = le32_to_cpu(index[i].ei_leaf_hi); + block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo); + + if (ext4fs_devread(block << log2_blksz, 0, fs->blksz, buf)) + ext_block = (struct ext4_extent_header *)buf; + else + return 0; + } +} + +static int ext4fs_blockgroup + (struct ext2_data *data, int group, struct ext2_block_group *blkgrp) +{ + long int blkno; + unsigned int blkoff, desc_per_blk; + + desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group); + + blkno = __le32_to_cpu(data->sblock.first_data_block) + 1 + + group / desc_per_blk; + blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group); + + debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n", + group, blkno, blkoff); + + return ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data), + blkoff, sizeof(struct ext2_block_group), + (char *)blkgrp); +} + +int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode) +{ + struct ext2_block_group blkgrp; + struct ext2_sblock *sblock = &data->sblock; + struct ext_filesystem *fs = get_fs(); + int inodes_per_block, status; + long int blkno; + unsigned int blkoff; + + /* It is easier to calculate if the first inode is 0. */ + ino--; + status = ext4fs_blockgroup(data, ino / __le32_to_cpu + (sblock->inodes_per_group), &blkgrp); + if (status == 0) + return 0; + + inodes_per_block = EXT2_BLOCK_SIZE(data) / fs->inodesz; + blkno = __le32_to_cpu(blkgrp.inode_table_id) + + (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block; + blkoff = (ino % inodes_per_block) * fs->inodesz; + /* Read the inode. */ + status = ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data), blkoff, + sizeof(struct ext2_inode), (char *)inode); + if (status == 0) + return 0; + + return 1; +} + +long int read_allocated_block(struct ext2_inode *inode, int fileblock) +{ + long int blknr; + int blksz; + int log2_blksz; + int status; + long int rblock; + long int perblock_parent; + long int perblock_child; + unsigned long long start; + /* get the blocksize of the filesystem */ + blksz = EXT2_BLOCK_SIZE(ext4fs_root); + log2_blksz = LOG2_EXT2_BLOCK_SIZE(ext4fs_root); + if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FL) { + char *buf = zalloc(blksz); + if (!buf) + return -ENOMEM; + struct ext4_extent_header *ext_block; + struct ext4_extent *extent; + int i = -1; + ext_block = ext4fs_get_extent_block(ext4fs_root, buf, + (struct ext4_extent_header + *)inode->b. + blocks.dir_blocks, + fileblock, log2_blksz); + if (!ext_block) { + printf("invalid extent block\n"); + free(buf); + return -EINVAL; + } + + extent = (struct ext4_extent *)(ext_block + 1); + + do { + i++; + if (i >= le32_to_cpu(ext_block->eh_entries)) + break; + } while (fileblock >= le32_to_cpu(extent[i].ee_block)); + if (--i >= 0) { + fileblock -= le32_to_cpu(extent[i].ee_block); + if (fileblock >= le32_to_cpu(extent[i].ee_len)) { + free(buf); + return 0; + } + + start = le32_to_cpu(extent[i].ee_start_hi); + start = (start << 32) + + le32_to_cpu(extent[i].ee_start_lo); + free(buf); + return fileblock + start; + } + + printf("Extent Error\n"); + free(buf); + return -1; + } + + /* Direct blocks. */ + if (fileblock < INDIRECT_BLOCKS) + blknr = __le32_to_cpu(inode->b.blocks.dir_blocks[fileblock]); + + /* Indirect. */ + else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) { + if (ext4fs_indir1_block == NULL) { + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** SI ext2fs read block (indir 1)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + ext4fs_indir1_blkno = -1; + } + if (blksz != ext4fs_indir1_size) { + free(ext4fs_indir1_block); + ext4fs_indir1_block = NULL; + ext4fs_indir1_size = 0; + ext4fs_indir1_blkno = -1; + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** SI ext2fs read block (indir 1):" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + } + if ((__le32_to_cpu(inode->b.blocks.indir_block) << + log2_blksz) != ext4fs_indir1_blkno) { + status = + ext4fs_devread(__le32_to_cpu + (inode->b.blocks. + indir_block) << log2_blksz, 0, + blksz, (char *)ext4fs_indir1_block); + if (status == 0) { + printf("** SI ext2fs read block (indir 1)" + "failed. **\n"); + return 0; + } + ext4fs_indir1_blkno = + __le32_to_cpu(inode->b.blocks. + indir_block) << log2_blksz; + } + blknr = __le32_to_cpu(ext4fs_indir1_block + [fileblock - INDIRECT_BLOCKS]); + } + /* Double indirect. */ + else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4 * + (blksz / 4 + 1)))) { + + long int perblock = blksz / 4; + long int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4); + + if (ext4fs_indir1_block == NULL) { + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** DI ext2fs read block (indir 2 1)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + ext4fs_indir1_blkno = -1; + } + if (blksz != ext4fs_indir1_size) { + free(ext4fs_indir1_block); + ext4fs_indir1_block = NULL; + ext4fs_indir1_size = 0; + ext4fs_indir1_blkno = -1; + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** DI ext2fs read block (indir 2 1)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + } + if ((__le32_to_cpu(inode->b.blocks.double_indir_block) << + log2_blksz) != ext4fs_indir1_blkno) { + status = + ext4fs_devread(__le32_to_cpu + (inode->b.blocks. + double_indir_block) << log2_blksz, + 0, blksz, + (char *)ext4fs_indir1_block); + if (status == 0) { + printf("** DI ext2fs read block (indir 2 1)" + "failed. **\n"); + return -1; + } + ext4fs_indir1_blkno = + __le32_to_cpu(inode->b.blocks.double_indir_block) << + log2_blksz; + } + + if (ext4fs_indir2_block == NULL) { + ext4fs_indir2_block = zalloc(blksz); + if (ext4fs_indir2_block == NULL) { + printf("** DI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir2_size = blksz; + ext4fs_indir2_blkno = -1; + } + if (blksz != ext4fs_indir2_size) { + free(ext4fs_indir2_block); + ext4fs_indir2_block = NULL; + ext4fs_indir2_size = 0; + ext4fs_indir2_blkno = -1; + ext4fs_indir2_block = zalloc(blksz); + if (ext4fs_indir2_block == NULL) { + printf("** DI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir2_size = blksz; + } + if ((__le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) << + log2_blksz) != ext4fs_indir2_blkno) { + status = ext4fs_devread(__le32_to_cpu + (ext4fs_indir1_block + [rblock / + perblock]) << log2_blksz, 0, + blksz, + (char *)ext4fs_indir2_block); + if (status == 0) { + printf("** DI ext2fs read block (indir 2 2)" + "failed. **\n"); + return -1; + } + ext4fs_indir2_blkno = + __le32_to_cpu(ext4fs_indir1_block[rblock + / + perblock]) << + log2_blksz; + } + blknr = __le32_to_cpu(ext4fs_indir2_block[rblock % perblock]); + } + /* Tripple indirect. */ + else { + rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4 + + (blksz / 4 * blksz / 4)); + perblock_child = blksz / 4; + perblock_parent = ((blksz / 4) * (blksz / 4)); + + if (ext4fs_indir1_block == NULL) { + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** TI ext2fs read block (indir 2 1)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + ext4fs_indir1_blkno = -1; + } + if (blksz != ext4fs_indir1_size) { + free(ext4fs_indir1_block); + ext4fs_indir1_block = NULL; + ext4fs_indir1_size = 0; + ext4fs_indir1_blkno = -1; + ext4fs_indir1_block = zalloc(blksz); + if (ext4fs_indir1_block == NULL) { + printf("** TI ext2fs read block (indir 2 1)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir1_size = blksz; + } + if ((__le32_to_cpu(inode->b.blocks.triple_indir_block) << + log2_blksz) != ext4fs_indir1_blkno) { + status = ext4fs_devread + (__le32_to_cpu(inode->b.blocks.triple_indir_block) + << log2_blksz, 0, blksz, + (char *)ext4fs_indir1_block); + if (status == 0) { + printf("** TI ext2fs read block (indir 2 1)" + "failed. **\n"); + return -1; + } + ext4fs_indir1_blkno = + __le32_to_cpu(inode->b.blocks.triple_indir_block) << + log2_blksz; + } + + if (ext4fs_indir2_block == NULL) { + ext4fs_indir2_block = zalloc(blksz); + if (ext4fs_indir2_block == NULL) { + printf("** TI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir2_size = blksz; + ext4fs_indir2_blkno = -1; + } + if (blksz != ext4fs_indir2_size) { + free(ext4fs_indir2_block); + ext4fs_indir2_block = NULL; + ext4fs_indir2_size = 0; + ext4fs_indir2_blkno = -1; + ext4fs_indir2_block = zalloc(blksz); + if (ext4fs_indir2_block == NULL) { + printf("** TI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir2_size = blksz; + } + if ((__le32_to_cpu(ext4fs_indir1_block[rblock / + perblock_parent]) << + log2_blksz) + != ext4fs_indir2_blkno) { + status = ext4fs_devread(__le32_to_cpu + (ext4fs_indir1_block + [rblock / + perblock_parent]) << + log2_blksz, 0, blksz, + (char *)ext4fs_indir2_block); + if (status == 0) { + printf("** TI ext2fs read block (indir 2 2)" + "failed. **\n"); + return -1; + } + ext4fs_indir2_blkno = + __le32_to_cpu(ext4fs_indir1_block[rblock / + perblock_parent]) + << log2_blksz; + } + + if (ext4fs_indir3_block == NULL) { + ext4fs_indir3_block = zalloc(blksz); + if (ext4fs_indir3_block == NULL) { + printf("** TI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir3_size = blksz; + ext4fs_indir3_blkno = -1; + } + if (blksz != ext4fs_indir3_size) { + free(ext4fs_indir3_block); + ext4fs_indir3_block = NULL; + ext4fs_indir3_size = 0; + ext4fs_indir3_blkno = -1; + ext4fs_indir3_block = zalloc(blksz); + if (ext4fs_indir3_block == NULL) { + printf("** TI ext2fs read block (indir 2 2)" + "malloc failed. **\n"); + return -1; + } + ext4fs_indir3_size = blksz; + } + if ((__le32_to_cpu(ext4fs_indir2_block[rblock + / + perblock_child]) << + log2_blksz) != ext4fs_indir3_blkno) { + status = + ext4fs_devread(__le32_to_cpu + (ext4fs_indir2_block + [(rblock / perblock_child) + % (blksz / 4)]) << log2_blksz, 0, + blksz, (char *)ext4fs_indir3_block); + if (status == 0) { + printf("** TI ext2fs read block (indir 2 2)" + "failed. **\n"); + return -1; + } + ext4fs_indir3_blkno = + __le32_to_cpu(ext4fs_indir2_block[(rblock / + perblock_child) % + (blksz / + 4)]) << + log2_blksz; + } + + blknr = __le32_to_cpu(ext4fs_indir3_block + [rblock % perblock_child]); + } + debug("ext4fs_read_block %ld\n", blknr); + + return blknr; +} + +void ext4fs_close(void) +{ + if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) { + ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen); + ext4fs_file = NULL; + } + if (ext4fs_root != NULL) { + free(ext4fs_root); + ext4fs_root = NULL; + } + if (ext4fs_indir1_block != NULL) { + free(ext4fs_indir1_block); + ext4fs_indir1_block = NULL; + ext4fs_indir1_size = 0; + ext4fs_indir1_blkno = -1; + } + if (ext4fs_indir2_block != NULL) { + free(ext4fs_indir2_block); + ext4fs_indir2_block = NULL; + ext4fs_indir2_size = 0; + ext4fs_indir2_blkno = -1; + } + if (ext4fs_indir3_block != NULL) { + free(ext4fs_indir3_block); + ext4fs_indir3_block = NULL; + ext4fs_indir3_size = 0; + ext4fs_indir3_blkno = -1; + } +} + +int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, + struct ext2fs_node **fnode, int *ftype) +{ + unsigned int fpos = 0; + int status; + struct ext2fs_node *diro = (struct ext2fs_node *) dir; + +#ifdef DEBUG + if (name != NULL) + printf("Iterate dir %s\n", name); +#endif /* of DEBUG */ + if (!diro->inode_read) { + status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode); + if (status == 0) + return 0; + } + /* Search the file. */ + while (fpos < __le32_to_cpu(diro->inode.size)) { + struct ext2_dirent dirent; + + status = ext4fs_read_file(diro, fpos, + sizeof(struct ext2_dirent), + (char *) &dirent); + if (status < 1) + return 0; + + if (dirent.namelen != 0) { + char filename[dirent.namelen + 1]; + struct ext2fs_node *fdiro; + int type = FILETYPE_UNKNOWN; + + status = ext4fs_read_file(diro, + fpos + + sizeof(struct ext2_dirent), + dirent.namelen, filename); + if (status < 1) + return 0; + + fdiro = zalloc(sizeof(struct ext2fs_node)); + if (!fdiro) + return 0; + + fdiro->data = diro->data; + fdiro->ino = __le32_to_cpu(dirent.inode); + + filename[dirent.namelen] = '\0'; + + if (dirent.filetype != FILETYPE_UNKNOWN) { + fdiro->inode_read = 0; + + if (dirent.filetype == FILETYPE_DIRECTORY) + type = FILETYPE_DIRECTORY; + else if (dirent.filetype == FILETYPE_SYMLINK) + type = FILETYPE_SYMLINK; + else if (dirent.filetype == FILETYPE_REG) + type = FILETYPE_REG; + } else { + status = ext4fs_read_inode(diro->data, + __le32_to_cpu + (dirent.inode), + &fdiro->inode); + if (status == 0) { + free(fdiro); + return 0; + } + fdiro->inode_read = 1; + + if ((__le16_to_cpu(fdiro->inode.mode) & + FILETYPE_INO_MASK) == + FILETYPE_INO_DIRECTORY) { + type = FILETYPE_DIRECTORY; + } else if ((__le16_to_cpu(fdiro->inode.mode) + & FILETYPE_INO_MASK) == + FILETYPE_INO_SYMLINK) { + type = FILETYPE_SYMLINK; + } else if ((__le16_to_cpu(fdiro->inode.mode) + & FILETYPE_INO_MASK) == + FILETYPE_INO_REG) { + type = FILETYPE_REG; + } + } +#ifdef DEBUG + printf("iterate >%s<\n", filename); +#endif /* of DEBUG */ + if ((name != NULL) && (fnode != NULL) + && (ftype != NULL)) { + if (strcmp(filename, name) == 0) { + *ftype = type; + *fnode = fdiro; + return 1; + } + } else { + if (fdiro->inode_read == 0) { + status = ext4fs_read_inode(diro->data, + __le32_to_cpu( + dirent.inode), + &fdiro->inode); + if (status == 0) { + free(fdiro); + return 0; + } + fdiro->inode_read = 1; + } + switch (type) { + case FILETYPE_DIRECTORY: + printf(" "); + break; + case FILETYPE_SYMLINK: + printf(" "); + break; + case FILETYPE_REG: + printf(" "); + break; + default: + printf("< ? > "); + break; + } + printf("%10d %s\n", + __le32_to_cpu(fdiro->inode.size), + filename); + } + free(fdiro); + } + fpos += __le16_to_cpu(dirent.direntlen); + } + return 0; +} + +static char *ext4fs_read_symlink(struct ext2fs_node *node) +{ + char *symlink; + struct ext2fs_node *diro = node; + int status; + + if (!diro->inode_read) { + status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode); + if (status == 0) + return 0; + } + symlink = zalloc(__le32_to_cpu(diro->inode.size) + 1); + if (!symlink) + return 0; + + if (__le32_to_cpu(diro->inode.size) <= 60) { + strncpy(symlink, diro->inode.b.symlink, + __le32_to_cpu(diro->inode.size)); + } else { + status = ext4fs_read_file(diro, 0, + __le32_to_cpu(diro->inode.size), + symlink); + if (status == 0) { + free(symlink); + return 0; + } + } + symlink[__le32_to_cpu(diro->inode.size)] = '\0'; + return symlink; +} + +static int ext4fs_find_file1(const char *currpath, + struct ext2fs_node *currroot, + struct ext2fs_node **currfound, int *foundtype) +{ + char fpath[strlen(currpath) + 1]; + char *name = fpath; + char *next; + int status; + int type = FILETYPE_DIRECTORY; + struct ext2fs_node *currnode = currroot; + struct ext2fs_node *oldnode = currroot; + + strncpy(fpath, currpath, strlen(currpath) + 1); + + /* Remove all leading slashes. */ + while (*name == '/') + name++; + + if (!*name) { + *currfound = currnode; + return 1; + } + + for (;;) { + int found; + + /* Extract the actual part from the pathname. */ + next = strchr(name, '/'); + if (next) { + /* Remove all leading slashes. */ + while (*next == '/') + *(next++) = '\0'; + } + + if (type != FILETYPE_DIRECTORY) { + ext4fs_free_node(currnode, currroot); + return 0; + } + + oldnode = currnode; + + /* Iterate over the directory. */ + found = ext4fs_iterate_dir(currnode, name, &currnode, &type); + if (found == 0) + return 0; + + if (found == -1) + break; + + /* Read in the symlink and follow it. */ + if (type == FILETYPE_SYMLINK) { + char *symlink; + + /* Test if the symlink does not loop. */ + if (++symlinknest == 8) { + ext4fs_free_node(currnode, currroot); + ext4fs_free_node(oldnode, currroot); + return 0; + } + + symlink = ext4fs_read_symlink(currnode); + ext4fs_free_node(currnode, currroot); + + if (!symlink) { + ext4fs_free_node(oldnode, currroot); + return 0; + } + + debug("Got symlink >%s<\n", symlink); + + if (symlink[0] == '/') { + ext4fs_free_node(oldnode, currroot); + oldnode = &ext4fs_root->diropen; + } + + /* Lookup the node the symlink points to. */ + status = ext4fs_find_file1(symlink, oldnode, + &currnode, &type); + + free(symlink); + + if (status == 0) { + ext4fs_free_node(oldnode, currroot); + return 0; + } + } + + ext4fs_free_node(oldnode, currroot); + + /* Found the node! */ + if (!next || *next == '\0') { + *currfound = currnode; + *foundtype = type; + return 1; + } + name = next; + } + return -1; +} + +int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode, + struct ext2fs_node **foundnode, int expecttype) +{ + int status; + int foundtype = FILETYPE_DIRECTORY; + + symlinknest = 0; + if (!path) + return 0; + + status = ext4fs_find_file1(path, rootnode, foundnode, &foundtype); + if (status == 0) + return 0; + + /* Check if the node that was found was of the expected type. */ + if ((expecttype == FILETYPE_REG) && (foundtype != expecttype)) + return 0; + else if ((expecttype == FILETYPE_DIRECTORY) + && (foundtype != expecttype)) + return 0; + + return 1; +} + +int ext4fs_open(const char *filename) +{ + struct ext2fs_node *fdiro = NULL; + int status; + int len; + + if (ext4fs_root == NULL) + return -1; + + ext4fs_file = NULL; + status = ext4fs_find_file(filename, &ext4fs_root->diropen, &fdiro, + FILETYPE_REG); + if (status == 0) + goto fail; + + if (!fdiro->inode_read) { + status = ext4fs_read_inode(fdiro->data, fdiro->ino, + &fdiro->inode); + if (status == 0) + goto fail; + } + len = __le32_to_cpu(fdiro->inode.size); + ext4fs_file = fdiro; + + return len; +fail: + ext4fs_free_node(fdiro, &ext4fs_root->diropen); + + return -1; +} + +int ext4fs_mount(unsigned part_length) +{ + struct ext2_data *data; + int status; + struct ext_filesystem *fs = get_fs(); + data = zalloc(sizeof(struct ext2_data)); + if (!data) + return 0; + + /* Read the superblock. */ + status = ext4fs_devread(1 * 2, 0, sizeof(struct ext2_sblock), + (char *)&data->sblock); + + if (status == 0) + goto fail; + + /* Make sure this is an ext2 filesystem. */ + if (__le16_to_cpu(data->sblock.magic) != EXT2_MAGIC) + goto fail; + + if (__le32_to_cpu(data->sblock.revision_level == 0)) + fs->inodesz = 128; + else + fs->inodesz = __le16_to_cpu(data->sblock.inode_size); + + debug("EXT2 rev %d, inode_size %d\n", + __le32_to_cpu(data->sblock.revision_level), fs->inodesz); + + data->diropen.data = data; + data->diropen.ino = 2; + data->diropen.inode_read = 1; + data->inode = &data->diropen.inode; + + status = ext4fs_read_inode(data, 2, data->inode); + if (status == 0) + goto fail; + + ext4fs_root = data; + + return 1; +fail: + printf("Failed to mount ext2 filesystem...\n"); + free(data); + ext4fs_root = NULL; + + return 0; +} diff --git a/fs/ext4/ext4_common.h b/fs/ext4/ext4_common.h new file mode 100644 index 0000000..8e8bcbc --- /dev/null +++ b/fs/ext4/ext4_common.h @@ -0,0 +1,63 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar + * Manjunatha C Achar + * + * ext4ls and ext4load : based on ext2 ls load support in Uboot. + * + * (C) Copyright 2004 + * esd gmbh + * Reinhard Arlt + * + * based on code from grub2 fs/ext2.c and fs/fshelp.c by + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __EXT4_COMMON__ +#define __EXT4_COMMON__ +#include +#include +#include +#include + +#define YES 1 +#define NO 0 +#define TRUE 1 +#define FALSE 0 +#define RECOVER 1 +#define SCAN 0 + +#define S_IFLNK 0120000 /* symbolic link */ +#define BLOCK_NO_ONE 1 +#define SUPERBLOCK_SECTOR 2 +#define SUPERBLOCK_SIZE 1024 +#define F_FILE 1 + +#define zalloc(size) calloc(1, size) + +extern unsigned long part_offset; +int ext4fs_read_inode(struct ext2_data *data, int ino, + struct ext2_inode *inode); +int ext4fs_read_file(struct ext2fs_node *node, int pos, + unsigned int len, char *buf); +int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode, + struct ext2fs_node **foundnode, int expecttype); +int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, + struct ext2fs_node **fnode, int *ftype); +#endif diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c new file mode 100644 index 0000000..1287bf0 --- /dev/null +++ b/fs/ext4/ext4fs.c @@ -0,0 +1,228 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar + * Manjunatha C Achar + * + * ext4ls and ext4load : Based on ext2 ls and load support in Uboot. + * Ext4 read optimization taken from Open-Moko + * Qi bootloader + * + * (C) Copyright 2004 + * esd gmbh + * Reinhard Arlt + * + * based on code from grub2 fs/ext2.c and fs/fshelp.c by + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "ext4_common.h" + +int ext4fs_symlinknest; +block_dev_desc_t *ext4_dev_desc; + +struct ext_filesystem *get_fs(void) +{ + if (ext4_dev_desc == NULL || ext4_dev_desc->priv == NULL) + printf("Invalid Input Arguments %s\n", __func__); + + return ext4_dev_desc->priv; +} + +int init_fs(block_dev_desc_t *dev_desc) +{ + struct ext_filesystem *fs; + if (dev_desc == NULL) { + printf("Invalid Input Arguments %s\n", __func__); + return -EINVAL; + } + + fs = zalloc(sizeof(struct ext_filesystem)); + if (fs == NULL) { + printf("malloc failed: %s\n", __func__); + return -ENOMEM; + } + + fs->dev_desc = dev_desc; + dev_desc->priv = fs; + + return 0; +} + +void deinit_fs(block_dev_desc_t *dev_desc) +{ + if (dev_desc == NULL) { + printf("Invalid Input Arguments %s\n", __func__); + return; + } + free(dev_desc->priv); + dev_desc->priv = NULL; +} + +void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot) +{ + if ((node != &ext4fs_root->diropen) && (node != currroot)) + free(node); +} + +/* + * Taken from openmoko-kernel mailing list: By Andy green + * Optimized read file API : collects and defers contiguous sector + * reads into one potentially more efficient larger sequential read action + */ +int ext4fs_read_file(struct ext2fs_node *node, int pos, + unsigned int len, char *buf) +{ + int i; + int blockcnt; + int log2blocksize = LOG2_EXT2_BLOCK_SIZE(node->data); + int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS); + unsigned int filesize = __le32_to_cpu(node->inode.size); + int previous_block_number = -1; + int delayed_start = 0; + int delayed_extent = 0; + int delayed_skipfirst = 0; + int delayed_next = 0; + char *delayed_buf = NULL; + short status; + + /* Adjust len so it we can't read past the end of the file. */ + if (len > filesize) + len = filesize; + + blockcnt = ((len + pos) + blocksize - 1) / blocksize; + + for (i = pos / blocksize; i < blockcnt; i++) { + int blknr; + int blockoff = pos % blocksize; + int blockend = blocksize; + int skipfirst = 0; + blknr = read_allocated_block(&(node->inode), i); + if (blknr < 0) + return -1; + + blknr = blknr << log2blocksize; + + /* Last block. */ + if (i == blockcnt - 1) { + blockend = (len + pos) % blocksize; + + /* The last portion is exactly blocksize. */ + if (!blockend) + blockend = blocksize; + } + + /* First block. */ + if (i == pos / blocksize) { + skipfirst = blockoff; + blockend -= skipfirst; + } + if (blknr) { + int status; + + if (previous_block_number != -1) { + if (delayed_next == blknr) { + delayed_extent += blockend; + delayed_next += blockend >> SECTOR_BITS; + } else { /* spill */ + status = ext4fs_devread(delayed_start, + delayed_skipfirst, + delayed_extent, + delayed_buf); + if (status == 0) + return -1; + previous_block_number = blknr; + delayed_start = blknr; + delayed_extent = blockend; + delayed_skipfirst = skipfirst; + delayed_buf = buf; + delayed_next = blknr + + (blockend >> SECTOR_BITS); + } + } else { + previous_block_number = blknr; + delayed_start = blknr; + delayed_extent = blockend; + delayed_skipfirst = skipfirst; + delayed_buf = buf; + delayed_next = blknr + + (blockend >> SECTOR_BITS); + } + } else { + if (previous_block_number != -1) { + /* spill */ + status = ext4fs_devread(delayed_start, + delayed_skipfirst, + delayed_extent, + delayed_buf); + if (status == 0) + return -1; + previous_block_number = -1; + } + memset(buf, 0, blocksize - skipfirst); + } + buf += blocksize - skipfirst; + } + if (previous_block_number != -1) { + /* spill */ + status = ext4fs_devread(delayed_start, + delayed_skipfirst, delayed_extent, + delayed_buf); + if (status == 0) + return -1; + previous_block_number = -1; + } + + return len; +} + +int ext4fs_ls(const char *dirname) +{ + struct ext2fs_node *dirnode; + int status; + + if (dirname == NULL) + return 0; + + status = ext4fs_find_file(dirname, &ext4fs_root->diropen, &dirnode, + FILETYPE_DIRECTORY); + if (status != 1) { + printf("** Can not find directory. **\n"); + return 1; + } + + ext4fs_iterate_dir(dirnode, NULL, NULL, NULL); + ext4fs_free_node(dirnode, &ext4fs_root->diropen); + + return 0; +} + +int ext4fs_read(char *buf, unsigned len) +{ + if (ext4fs_root == NULL || ext4fs_file == NULL) + return 0; + + return ext4fs_read_file(ext4fs_file, 0, len, buf); +} diff --git a/include/ext2fs.h b/include/ext2fs.h deleted file mode 100644 index 163a9bb..0000000 --- a/include/ext2fs.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. - * - * (C) Copyright 2003 Sysgo Real-Time Solutions, AG - * Pavel Bartusek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* An implementation for the Ext2FS filesystem ported from GRUB. - * Some parts of this code (mainly the structures and defines) are - * from the original ext2 fs code, as found in the linux kernel. - */ - - -#define SECTOR_SIZE 0x200 -#define SECTOR_BITS 9 - -/* Error codes */ -typedef enum -{ - ERR_NONE = 0, - ERR_BAD_FILENAME, - ERR_BAD_FILETYPE, - ERR_BAD_GZIP_DATA, - ERR_BAD_GZIP_HEADER, - ERR_BAD_PART_TABLE, - ERR_BAD_VERSION, - ERR_BELOW_1MB, - ERR_BOOT_COMMAND, - ERR_BOOT_FAILURE, - ERR_BOOT_FEATURES, - ERR_DEV_FORMAT, - ERR_DEV_VALUES, - ERR_EXEC_FORMAT, - ERR_FILELENGTH, - ERR_FILE_NOT_FOUND, - ERR_FSYS_CORRUPT, - ERR_FSYS_MOUNT, - ERR_GEOM, - ERR_NEED_LX_KERNEL, - ERR_NEED_MB_KERNEL, - ERR_NO_DISK, - ERR_NO_PART, - ERR_NUMBER_PARSING, - ERR_OUTSIDE_PART, - ERR_READ, - ERR_SYMLINK_LOOP, - ERR_UNRECOGNIZED, - ERR_WONT_FIT, - ERR_WRITE, - ERR_BAD_ARGUMENT, - ERR_UNALIGNED, - ERR_PRIVILEGED, - ERR_DEV_NEED_INIT, - ERR_NO_DISK_SPACE, - ERR_NUMBER_OVERFLOW, - - MAX_ERR_NUM -} ext2fs_error_t; - - -extern int ext2fs_set_blk_dev(block_dev_desc_t *rbdd, int part); -extern int ext2fs_ls (const char *dirname); -extern int ext2fs_open (const char *filename); -extern int ext2fs_read (char *buf, unsigned len); -extern int ext2fs_mount (unsigned part_length); -extern int ext2fs_close(void); diff --git a/include/ext4fs.h b/include/ext4fs.h new file mode 100644 index 0000000..58a6a1d --- /dev/null +++ b/include/ext4fs.h @@ -0,0 +1,132 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar + * Manjunatha C Achar + * + * Ext4 Extent data structures are taken from original ext4 fs code + * as found in the linux kernel. + * + * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __EXT4__ +#define __EXT4__ +#include + +#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ +#define EXT4_EXT_MAGIC 0xf30a +#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 +#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 +#define EXT4_INDIRECT_BLOCKS 12 + +#define EXT4_BG_INODE_UNINIT 0x0001 +#define EXT4_BG_BLOCK_UNINIT 0x0002 +#define EXT4_BG_INODE_ZEROED 0x0004 + +/* + * ext4_inode has i_block array (60 bytes total). + * The first 12 bytes store ext4_extent_header; + * the remainder stores an array of ext4_extent. + */ + +/* + * This is the extent on-disk structure. + * It's used at the bottom of the tree. + */ +struct ext4_extent { + __le32 ee_block; /* first logical block extent covers */ + __le16 ee_len; /* number of blocks covered by extent */ + __le16 ee_start_hi; /* high 16 bits of physical block */ + __le32 ee_start_lo; /* low 32 bits of physical block */ +}; + +/* + * This is index on-disk structure. + * It's used at all the levels except the bottom. + */ +struct ext4_extent_idx { + __le32 ei_block; /* index covers logical blocks from 'block' */ + __le32 ei_leaf_lo; /* pointer to the physical block of the next * + * level. leaf or next index could be there */ + __le16 ei_leaf_hi; /* high 16 bits of physical block */ + __u16 ei_unused; +}; + +/* Each block (leaves and indexes), even inode-stored has header. */ +struct ext4_extent_header { + __le16 eh_magic; /* probably will support different formats */ + __le16 eh_entries; /* number of valid entries */ + __le16 eh_max; /* capacity of store in entries */ + __le16 eh_depth; /* has tree real underlying blocks? */ + __le32 eh_generation; /* generation of the tree */ +}; + +struct ext_filesystem { + /* Total Sector of partition */ + uint64_t total_sect; + /* Block size of partition */ + uint32_t blksz; + /* Inode size of partition */ + uint32_t inodesz; + /* Sectors per Block */ + uint32_t sect_perblk; + /* Group Descriptor Block Number */ + uint32_t gdtable_blkno; + /* Total block groups of partition */ + uint32_t no_blkgrp; + /* No of blocks required for bgdtable */ + uint32_t no_blk_pergdt; + /* Superblock */ + struct ext2_sblock *sb; + /* Block group descritpor table */ + struct ext2_block_group *gd; + char *gdtable; + + /* Block Bitmap Related */ + unsigned char **blk_bmaps; + long int curr_blkno; + uint16_t first_pass_bbmap; + + /* Inode Bitmap Related */ + unsigned char **inode_bmaps; + int curr_inode_no; + uint16_t first_pass_ibmap; + + /* Journal Related */ + + /* Block Device Descriptor */ + block_dev_desc_t *dev_desc; +}; + +extern block_dev_desc_t *ext4_dev_desc; +extern struct ext2_data *ext4fs_root; +extern struct ext2fs_node *ext4fs_file; + +struct ext_filesystem *get_fs(void); +int init_fs(block_dev_desc_t *dev_desc); +void deinit_fs(block_dev_desc_t *dev_desc); +int ext4fs_open(const char *filename); +int ext4fs_read(char *buf, unsigned len); +int ext4fs_mount(unsigned part_length); +void ext4fs_close(void); +int ext4fs_ls(const char *dirname); +void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot); +int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf); +int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part); +long int read_allocated_block(struct ext2_inode *inode, int fileblock); +#endif diff --git a/include/ext_common.h b/include/ext_common.h new file mode 100644 index 0000000..c90d95b --- /dev/null +++ b/include/ext_common.h @@ -0,0 +1,197 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar + * Manjunatha C Achar + * + * Data structures and headers for ext4 support have been taken from + * ext2 ls load support in Uboot + * + * (C) Copyright 2004 + * esd gmbh + * Reinhard Arlt + * + * based on code from grub2 fs/ext2.c and fs/fshelp.c by + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __EXT_COMMON__ +#define __EXT_COMMON__ +#include +#define SECTOR_SIZE 0x200 +#define SECTOR_BITS 9 + +/* Magic value used to identify an ext2 filesystem. */ +#define EXT2_MAGIC 0xEF53 +/* Amount of indirect blocks in an inode. */ +#define INDIRECT_BLOCKS 12 +/* Maximum lenght of a pathname. */ +#define EXT2_PATH_MAX 4096 +/* Maximum nesting of symlinks, used to prevent a loop. */ +#define EXT2_MAX_SYMLINKCNT 8 + +/* Filetype used in directory entry. */ +#define FILETYPE_UNKNOWN 0 +#define FILETYPE_REG 1 +#define FILETYPE_DIRECTORY 2 +#define FILETYPE_SYMLINK 7 + +/* Filetype information as used in inodes. */ +#define FILETYPE_INO_MASK 0170000 +#define FILETYPE_INO_REG 0100000 +#define FILETYPE_INO_DIRECTORY 0040000 +#define FILETYPE_INO_SYMLINK 0120000 +#define EXT2_ROOT_INO 2 /* Root inode */ + +/* Bits used as offset in sector */ +#define DISK_SECTOR_BITS 9 +/* The size of an ext2 block in bytes. */ +#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data)) + +/* Log2 size of ext2 block in 512 blocks. */ +#define LOG2_EXT2_BLOCK_SIZE(data) (__le32_to_cpu \ + (data->sblock.log2_block_size) + 1) + +/* Log2 size of ext2 block in bytes. */ +#define LOG2_BLOCK_SIZE(data) (__le32_to_cpu \ + (data->sblock.log2_block_size) + 10) +#define INODE_SIZE_FILESYSTEM(data) (__le32_to_cpu \ + (data->sblock.inode_size)) + +#define EXT2_FT_DIR 2 +#define SUCCESS 1 + +/* Macro-instructions used to manage several block sizes */ +#define EXT2_MIN_BLOCK_LOG_SIZE 10 /* 1024 */ +#define EXT2_MAX_BLOCK_LOG_SIZE 16 /* 65536 */ +#define EXT2_MIN_BLOCK_SIZE (1 << EXT2_MIN_BLOCK_LOG_SIZE) +#define EXT2_MAX_BLOCK_SIZE (1 << EXT2_MAX_BLOCK_LOG_SIZE) + +/* The ext2 superblock. */ +struct ext2_sblock { + uint32_t total_inodes; + uint32_t total_blocks; + uint32_t reserved_blocks; + uint32_t free_blocks; + uint32_t free_inodes; + uint32_t first_data_block; + uint32_t log2_block_size; + uint32_t log2_fragment_size; + uint32_t blocks_per_group; + uint32_t fragments_per_group; + uint32_t inodes_per_group; + uint32_t mtime; + uint32_t utime; + uint16_t mnt_count; + uint16_t max_mnt_count; + uint16_t magic; + uint16_t fs_state; + uint16_t error_handling; + uint16_t minor_revision_level; + uint32_t lastcheck; + uint32_t checkinterval; + uint32_t creator_os; + uint32_t revision_level; + uint16_t uid_reserved; + uint16_t gid_reserved; + uint32_t first_inode; + uint16_t inode_size; + uint16_t block_group_number; + uint32_t feature_compatibility; + uint32_t feature_incompat; + uint32_t feature_ro_compat; + uint32_t unique_id[4]; + char volume_name[16]; + char last_mounted_on[64]; + uint32_t compression_info; +}; + +struct ext2_block_group { + __u32 block_id; /* Blocks bitmap block */ + __u32 inode_id; /* Inodes bitmap block */ + __u32 inode_table_id; /* Inodes table block */ + __u16 free_blocks; /* Free blocks count */ + __u16 free_inodes; /* Free inodes count */ + __u16 used_dir_cnt; /* Directories count */ + __u16 bg_flags; + __u32 bg_reserved[2]; + __u16 bg_itable_unused; /* Unused inodes count */ + __u16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/ +}; + +/* The ext2 inode. */ +struct ext2_inode { + uint16_t mode; + uint16_t uid; + uint32_t size; + uint32_t atime; + uint32_t ctime; + uint32_t mtime; + uint32_t dtime; + uint16_t gid; + uint16_t nlinks; + uint32_t blockcnt; /* Blocks of 512 bytes!! */ + uint32_t flags; + uint32_t osd1; + union { + struct datablocks { + uint32_t dir_blocks[INDIRECT_BLOCKS]; + uint32_t indir_block; + uint32_t double_indir_block; + uint32_t triple_indir_block; + } blocks; + char symlink[60]; + } b; + uint32_t version; + uint32_t acl; + uint32_t dir_acl; + uint32_t fragment_addr; + uint32_t osd2[3]; +}; + +/* The header of an ext2 directory entry. */ +struct ext2_dirent { + uint32_t inode; + uint16_t direntlen; + uint8_t namelen; + uint8_t filetype; +}; + +struct ext2fs_node { + struct ext2_data *data; + struct ext2_inode inode; + int ino; + int inode_read; +}; + +/* Information about a "mounted" ext2 filesystem. */ +struct ext2_data { + struct ext2_sblock sblock; + struct ext2_inode *inode; + struct ext2fs_node diropen; +}; + +int do_ext2ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +int do_ext2load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]); +int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); +int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]); +int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); +#endif -- cgit v1.1 From ed34f34dbaf206dfe223f4bc2147d600fe1b0f58 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Fri, 25 May 2012 21:22:49 +0530 Subject: ext4fs write support Signed-off-by: Uma Shankar Signed-off-by: Manjunatha C Achar Signed-off-by: Iqbal Shareef Signed-off-by: Hakgoo Lee --- common/cmd_ext4.c | 141 +++++ doc/README.ext4 | 46 ++ fs/ext4/Makefile | 1 + fs/ext4/crc16.c | 62 +++ fs/ext4/crc16.h | 16 + fs/ext4/ext4_common.c | 1353 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/ext4_common.h | 25 + fs/ext4/ext4_journal.c | 667 ++++++++++++++++++++++++ fs/ext4/ext4_journal.h | 141 +++++ fs/ext4/ext4fs.c | 961 ++++++++++++++++++++++++++++++++++ include/ext4fs.h | 12 + include/ext_common.h | 2 + 12 files changed, 3427 insertions(+) create mode 100644 doc/README.ext4 create mode 100644 fs/ext4/crc16.c create mode 100644 fs/ext4/crc16.h create mode 100644 fs/ext4/ext4_journal.c create mode 100644 fs/ext4/ext4_journal.h diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c index 3298fee..77094c4 100644 --- a/common/cmd_ext4.c +++ b/common/cmd_ext4.c @@ -62,6 +62,10 @@ uint64_t total_sector; uint64_t part_offset; +#if defined(CONFIG_CMD_EXT4_WRITE) +static uint64_t part_size; +static uint16_t cur_part = 1; +#endif #define DOS_PART_MAGIC_OFFSET 0x1fe #define DOS_FS_TYPE_OFFSET 0x36 @@ -84,6 +88,143 @@ int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) return 0; } +#if defined(CONFIG_CMD_EXT4_WRITE) +static int ext4_register_device(block_dev_desc_t *dev_desc, int part_no) +{ + unsigned char buffer[SECTOR_SIZE]; + disk_partition_t info; + + if (!dev_desc->block_read) + return -1; + + /* check if we have a MBR (on floppies we have only a PBR) */ + if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) { + printf("** Can't read from device %d **\n", dev_desc->dev); + return -1; + } + if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || + buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { + /* no signature found */ + return -1; + } + + /* First we assume there is a MBR */ + if (!get_partition_info(dev_desc, part_no, &info)) { + part_offset = info.start; + cur_part = part_no; + part_size = info.size; + } else if ((strncmp((char *)&buffer[DOS_FS_TYPE_OFFSET], + "FAT", 3) == 0) || (strncmp((char *)&buffer + [DOS_FS32_TYPE_OFFSET], + "FAT32", 5) == 0)) { + /* ok, we assume we are on a PBR only */ + cur_part = 1; + part_offset = 0; + } else { + printf("** Partition %d not valid on device %d **\n", + part_no, dev_desc->dev); + return -1; + } + + return 0; +} + +int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + const char *filename = "/"; + int part_length; + unsigned long part = 1; + int dev; + char *ep; + unsigned long ram_address; + unsigned long file_size; + disk_partition_t info; + struct ext_filesystem *fs; + + if (argc < 6) + return cmd_usage(cmdtp); + + dev = (int)simple_strtoul(argv[2], &ep, 16); + ext4_dev_desc = get_dev(argv[1], dev); + if (ext4_dev_desc == NULL) { + printf("Block device %s %d not supported\n", argv[1], dev); + return 1; + } + if (init_fs(ext4_dev_desc)) + return 1; + + fs = get_fs(); + if (*ep) { + if (*ep != ':') { + puts("Invalid boot device, use `dev[:part]'\n"); + goto fail; + } + part = simple_strtoul(++ep, NULL, 16); + } + + /* get the filename */ + filename = argv[3]; + + /* get the address in hexadecimal format (string to int) */ + ram_address = simple_strtoul(argv[4], NULL, 16); + + /* get the filesize in base 10 format */ + file_size = simple_strtoul(argv[5], NULL, 10); + + /* set the device as block device */ + part_length = ext4fs_set_blk_dev(fs->dev_desc, part); + if (part_length == 0) { + printf("Bad partition - %s %d:%lu\n", argv[1], dev, part); + goto fail; + } + + /* register the device and partition */ + if (ext4_register_device(fs->dev_desc, part) != 0) { + printf("Unable to use %s %d:%lu for fattable\n", + argv[1], dev, part); + goto fail; + } + + /* get the partition information */ + if (!get_partition_info(fs->dev_desc, part, &info)) { + total_sector = (info.size * info.blksz) / SECTOR_SIZE; + fs->total_sect = total_sector; + } else { + printf("error : get partition info\n"); + goto fail; + } + + /* mount the filesystem */ + if (!ext4fs_mount(part_length)) { + printf("Bad ext4 partition %s %d:%lu\n", argv[1], dev, part); + goto fail; + } + + /* start write */ + if (ext4fs_write(filename, (unsigned char *)ram_address, file_size)) { + printf("** Error ext4fs_write() **\n"); + goto fail; + } + ext4fs_close(); + deinit_fs(fs->dev_desc); + + return 0; + +fail: + ext4fs_close(); + deinit_fs(fs->dev_desc); + + return 1; +} + +U_BOOT_CMD(ext4write, 6, 1, do_ext4_write, + "create a file in the root directory", + " [Absolute filename path] [Address] [sizebytes]\n" + " - create a file in / directory"); + +#endif + U_BOOT_CMD(ext4ls, 4, 1, do_ext4_ls, "list files in a directory (default /)", " [directory]\n" diff --git a/doc/README.ext4 b/doc/README.ext4 new file mode 100644 index 0000000..b3ea8b7 --- /dev/null +++ b/doc/README.ext4 @@ -0,0 +1,46 @@ +This patch series adds support for ext4 ls,load and write features in uboot +Journaling is supported for write feature. + +To Enable ext2 ls and load commands, modify the board specific config file with +#define CONFIG_CMD_EXT2 + +To Enable ext4 ls and load commands, modify the board specific config file with +#define CONFIG_CMD_EXT4 + +To enable ext4 write command, modify the board specific config file with +#define CONFIG_CMD_EXT4 +#define CONFIG_CMD_EXT4_WRITE + +Steps to test: + +1. After applying the patch, ext4 specific commands can be seen + in the boot loader prompt using + UBOOT #help + + ext4load- load binary file from a Ext4 file system + ext4ls - list files in a directory (default /) + ext4write- create a file in ext4 formatted partition + +2. To list the files in ext4 formatted partition, execute + ext4ls [directory] + For example: + UBOOT #ext4ls mmc 0:5 /usr/lib + +3. To read and load a file from an ext4 formatted partition to RAM, execute + ext4load [addr] [filename] [bytes] + For example: + UBOOT #ext4load mmc 2:2 0x30007fc0 uImage + +4. To write a file to a ext4 formatted partition. + a) First load a file to RAM at a particular address for example 0x30007fc0. + Now execute ext4write command + ext4write [filename] [Address] [sizebytes] + For example: + UBOOT #ext4write mmc 2:2 /boot/uImage 0x30007fc0 6183120 + (here 6183120 is the size of the file to be written) + Note: Absolute path is required for the file to be written + +References : + -- ext4 implementation in Linux Kernel + -- Uboot existing ext2 load and ls implementation + -- Journaling block device JBD2 implementation in linux Kernel diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index 7b7fcbd..82cd9ae 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_CMD_EXT4) := ext4fs.o ext4_common.o dev.o ifndef CONFIG_CMD_EXT4 COBJS-$(CONFIG_CMD_EXT2) := ext4fs.o ext4_common.o dev.o endif +COBJS-$(CONFIG_CMD_EXT4_WRITE) += ext4_journal.o crc16.o SRCS := $(AOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS-y)) diff --git a/fs/ext4/crc16.c b/fs/ext4/crc16.c new file mode 100644 index 0000000..3afb34d --- /dev/null +++ b/fs/ext4/crc16.c @@ -0,0 +1,62 @@ +/* + * crc16.c + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include +#include "crc16.h" + +/** CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1) */ +static __u16 const crc16_table[256] = { + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 +}; + +/** + * Compute the CRC-16 for the data buffer +*/ + +unsigned int ext2fs_crc16(unsigned int crc, + const void *buffer, unsigned int len) +{ + const unsigned char *cp = buffer; + + while (len--) + crc = (((crc >> 8) & 0xffU) ^ + crc16_table[(crc ^ *cp++) & 0xffU]) & 0x0000ffffU; + return crc; +} diff --git a/fs/ext4/crc16.h b/fs/ext4/crc16.h new file mode 100644 index 0000000..5fd113a --- /dev/null +++ b/fs/ext4/crc16.h @@ -0,0 +1,16 @@ +/* + * crc16.h - CRC-16 routine + * Implements the standard CRC-16: + * Width 16 + * Poly 0x8005 (x16 + x15 + x2 + 1) + * Init 0 + * + * Copyright (c) 2005 Ben Gardner + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ +#ifndef __CRC16_H +#define __CRC16_H +extern unsigned int ext2fs_crc16(unsigned int crc, + const void *buffer, unsigned int len); +#endif diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c index 2ddbb50..083e45e 100644 --- a/fs/ext4/ext4_common.c +++ b/fs/ext4/ext4_common.c @@ -14,6 +14,8 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 2003, 2004 Free Software Foundation, Inc. * + * ext4write : Based on generic ext4 protocol. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -54,6 +56,1357 @@ int ext4fs_indir3_blkno = -1; struct ext2_inode *g_parent_inode; static int symlinknest; +#if defined(CONFIG_CMD_EXT4_WRITE) +uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n) +{ + uint32_t res = size / n; + if (res * n != size) + res++; + + return res; +} + +void put_ext4(uint64_t off, void *buf, uint32_t size) +{ + uint64_t startblock; + uint64_t remainder; + unsigned char *temp_ptr = NULL; + unsigned char sec_buf[SECTOR_SIZE]; + struct ext_filesystem *fs = get_fs(); + + startblock = off / (uint64_t)SECTOR_SIZE; + startblock += part_offset; + remainder = off % (uint64_t)SECTOR_SIZE; + remainder &= SECTOR_SIZE - 1; + + if (fs->dev_desc == NULL) + return; + + if ((startblock + (size / SECTOR_SIZE)) > + (part_offset + fs->total_sect)) { + printf("part_offset is %lu\n", part_offset); + printf("total_sector is %llu\n", fs->total_sect); + printf("error: overflow occurs\n"); + return; + } + + if (remainder) { + if (fs->dev_desc->block_read) { + fs->dev_desc->block_read(fs->dev_desc->dev, + startblock, 1, sec_buf); + temp_ptr = sec_buf; + memcpy((temp_ptr + remainder), + (unsigned char *)buf, size); + fs->dev_desc->block_write(fs->dev_desc->dev, + startblock, 1, sec_buf); + } + } else { + if (size / SECTOR_SIZE != 0) { + fs->dev_desc->block_write(fs->dev_desc->dev, + startblock, + size / SECTOR_SIZE, + (unsigned long *)buf); + } else { + fs->dev_desc->block_read(fs->dev_desc->dev, + startblock, 1, sec_buf); + temp_ptr = sec_buf; + memcpy(temp_ptr, buf, size); + fs->dev_desc->block_write(fs->dev_desc->dev, + startblock, 1, + (unsigned long *)sec_buf); + } + } +} + +static int _get_new_inode_no(unsigned char *buffer) +{ + struct ext_filesystem *fs = get_fs(); + unsigned char input; + int operand, status; + int count = 1; + int j = 0; + + /* get the blocksize of the filesystem */ + unsigned char *ptr = buffer; + while (*ptr == 255) { + ptr++; + count += 8; + if (count > ext4fs_root->sblock.inodes_per_group) + return -1; + } + + for (j = 0; j < fs->blksz; j++) { + input = *ptr; + int i = 0; + while (i <= 7) { + operand = 1 << i; + status = input & operand; + if (status) { + i++; + count++; + } else { + *ptr |= operand; + return count; + } + } + ptr = ptr + 1; + } + + return -1; +} + +static int _get_new_blk_no(unsigned char *buffer) +{ + unsigned char input; + int operand, status; + int count = 0; + int j = 0; + unsigned char *ptr = buffer; + struct ext_filesystem *fs = get_fs(); + + if (fs->blksz != 1024) + count = 0; + else + count = 1; + + while (*ptr == 255) { + ptr++; + count += 8; + if (count == (fs->blksz * 8)) + return -1; + } + + for (j = 0; j < fs->blksz; j++) { + input = *ptr; + int i = 0; + while (i <= 7) { + operand = 1 << i; + status = input & operand; + if (status) { + i++; + count++; + } else { + *ptr |= operand; + return count; + } + } + ptr = ptr + 1; + } + + return -1; +} + +int ext4fs_set_block_bmap(long int blockno, unsigned char *buffer, int index) +{ + int i, remainder, status; + unsigned char *ptr = buffer; + unsigned char operand; + i = blockno / 8; + remainder = blockno % 8; + int blocksize = EXT2_BLOCK_SIZE(ext4fs_root); + + i = i - (index * blocksize); + if (blocksize != 1024) { + ptr = ptr + i; + operand = 1 << remainder; + status = *ptr & operand; + if (status) + return -1; + + *ptr = *ptr | operand; + return 0; + } else { + if (remainder == 0) { + ptr = ptr + i - 1; + operand = (1 << 7); + } else { + ptr = ptr + i; + operand = (1 << (remainder - 1)); + } + status = *ptr & operand; + if (status) + return -1; + + *ptr = *ptr | operand; + return 0; + } +} + +void ext4fs_reset_block_bmap(long int blockno, unsigned char *buffer, int index) +{ + int i, remainder, status; + unsigned char *ptr = buffer; + unsigned char operand; + i = blockno / 8; + remainder = blockno % 8; + int blocksize = EXT2_BLOCK_SIZE(ext4fs_root); + + i = i - (index * blocksize); + if (blocksize != 1024) { + ptr = ptr + i; + operand = (1 << remainder); + status = *ptr & operand; + if (status) + *ptr = *ptr & ~(operand); + } else { + if (remainder == 0) { + ptr = ptr + i - 1; + operand = (1 << 7); + } else { + ptr = ptr + i; + operand = (1 << (remainder - 1)); + } + status = *ptr & operand; + if (status) + *ptr = *ptr & ~(operand); + } +} + +int ext4fs_set_inode_bmap(int inode_no, unsigned char *buffer, int index) +{ + int i, remainder, status; + unsigned char *ptr = buffer; + unsigned char operand; + + inode_no -= (index * ext4fs_root->sblock.inodes_per_group); + i = inode_no / 8; + remainder = inode_no % 8; + if (remainder == 0) { + ptr = ptr + i - 1; + operand = (1 << 7); + } else { + ptr = ptr + i; + operand = (1 << (remainder - 1)); + } + status = *ptr & operand; + if (status) + return -1; + + *ptr = *ptr | operand; + + return 0; +} + +void ext4fs_reset_inode_bmap(int inode_no, unsigned char *buffer, int index) +{ + int i, remainder, status; + unsigned char *ptr = buffer; + unsigned char operand; + + inode_no -= (index * ext4fs_root->sblock.inodes_per_group); + i = inode_no / 8; + remainder = inode_no % 8; + if (remainder == 0) { + ptr = ptr + i - 1; + operand = (1 << 7); + } else { + ptr = ptr + i; + operand = (1 << (remainder - 1)); + } + status = *ptr & operand; + if (status) + *ptr = *ptr & ~(operand); +} + +int ext4fs_checksum_update(unsigned int i) +{ + struct ext2_block_group *desc; + struct ext_filesystem *fs = get_fs(); + __u16 crc = 0; + + desc = (struct ext2_block_group *)&fs->gd[i]; + if (fs->sb->feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { + int offset = offsetof(struct ext2_block_group, bg_checksum); + + crc = ext2fs_crc16(~0, fs->sb->unique_id, + sizeof(fs->sb->unique_id)); + crc = ext2fs_crc16(crc, &i, sizeof(i)); + crc = ext2fs_crc16(crc, desc, offset); + offset += sizeof(desc->bg_checksum); /* skip checksum */ + assert(offset == sizeof(*desc)); + } + + return crc; +} + +static int check_void_in_dentry(struct ext2_dirent *dir, char *filename) +{ + int dentry_length; + int sizeof_void_space; + int new_entry_byte_reqd; + short padding_factor = 0; + + if (dir->namelen % 4 != 0) + padding_factor = 4 - (dir->namelen % 4); + + dentry_length = sizeof(struct ext2_dirent) + + dir->namelen + padding_factor; + sizeof_void_space = dir->direntlen - dentry_length; + if (sizeof_void_space == 0) + return 0; + + padding_factor = 0; + if (strlen(filename) % 4 != 0) + padding_factor = 4 - (strlen(filename) % 4); + + new_entry_byte_reqd = strlen(filename) + + sizeof(struct ext2_dirent) + padding_factor; + if (sizeof_void_space >= new_entry_byte_reqd) { + dir->direntlen = dentry_length; + return sizeof_void_space; + } + + return 0; +} + +void ext4fs_update_parent_dentry(char *filename, int *p_ino, int file_type) +{ + unsigned int *zero_buffer = NULL; + char *root_first_block_buffer = NULL; + int direct_blk_idx; + long int root_blknr; + long int first_block_no_of_root = 0; + long int previous_blknr = -1; + int totalbytes = 0; + short int padding_factor = 0; + unsigned int new_entry_byte_reqd; + unsigned int last_entry_dirlen; + int sizeof_void_space = 0; + int templength = 0; + int inodeno; + int status; + struct ext_filesystem *fs = get_fs(); + /* directory entry */ + struct ext2_dirent *dir; + char *ptr = NULL; + char *temp_dir = NULL; + + zero_buffer = zalloc(fs->blksz); + if (!zero_buffer) { + printf("No Memory\n"); + return; + } + root_first_block_buffer = zalloc(fs->blksz); + if (!root_first_block_buffer) { + free(zero_buffer); + printf("No Memory\n"); + return; + } +restart: + + /* read the block no allocated to a file */ + for (direct_blk_idx = 0; direct_blk_idx < INDIRECT_BLOCKS; + direct_blk_idx++) { + root_blknr = read_allocated_block(g_parent_inode, + direct_blk_idx); + if (root_blknr == 0) { + first_block_no_of_root = previous_blknr; + break; + } + previous_blknr = root_blknr; + } + + status = ext4fs_devread(first_block_no_of_root + * fs->sect_perblk, + 0, fs->blksz, root_first_block_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(root_first_block_buffer, first_block_no_of_root)) + goto fail; + dir = (struct ext2_dirent *)root_first_block_buffer; + ptr = (char *)dir; + totalbytes = 0; + while (dir->direntlen > 0) { + /* + * blocksize-totalbytes because last directory length + * i.e. dir->direntlen is free availble space in the + * block that means it is a last entry of directory + * entry + */ + + /* traversing the each directory entry */ + if (fs->blksz - totalbytes == dir->direntlen) { + if (strlen(filename) % 4 != 0) + padding_factor = 4 - (strlen(filename) % 4); + + new_entry_byte_reqd = strlen(filename) + + sizeof(struct ext2_dirent) + padding_factor; + padding_factor = 0; + /* + * update last directory entry length to its + * length because we are creating new directory + * entry + */ + if (dir->namelen % 4 != 0) + padding_factor = 4 - (dir->namelen % 4); + + last_entry_dirlen = dir->namelen + + sizeof(struct ext2_dirent) + padding_factor; + if ((fs->blksz - totalbytes - last_entry_dirlen) < + new_entry_byte_reqd) { + printf("1st Block Full:Allocate new block\n"); + + if (direct_blk_idx == INDIRECT_BLOCKS - 1) { + printf("Directory exceeds limit\n"); + goto fail; + } + g_parent_inode->b.blocks.dir_blocks + [direct_blk_idx] = ext4fs_get_new_blk_no(); + if (g_parent_inode->b.blocks.dir_blocks + [direct_blk_idx] == -1) { + printf("no block left to assign\n"); + goto fail; + } + put_ext4(((uint64_t) + (g_parent_inode->b. + blocks.dir_blocks[direct_blk_idx] * + fs->blksz)), zero_buffer, fs->blksz); + g_parent_inode->size = + g_parent_inode->size + fs->blksz; + g_parent_inode->blockcnt = + g_parent_inode->blockcnt + fs->sect_perblk; + if (ext4fs_put_metadata + (root_first_block_buffer, + first_block_no_of_root)) + goto fail; + goto restart; + } + dir->direntlen = last_entry_dirlen; + break; + } + + templength = dir->direntlen; + totalbytes = totalbytes + templength; + sizeof_void_space = check_void_in_dentry(dir, filename); + if (sizeof_void_space) + break; + + dir = (struct ext2_dirent *)((char *)dir + templength); + ptr = (char *)dir; + } + + /* make a pointer ready for creating next directory entry */ + templength = dir->direntlen; + totalbytes = totalbytes + templength; + dir = (struct ext2_dirent *)((char *)dir + templength); + ptr = (char *)dir; + + /* get the next available inode number */ + inodeno = ext4fs_get_new_inode_no(); + if (inodeno == -1) { + printf("no inode left to assign\n"); + goto fail; + } + dir->inode = inodeno; + if (sizeof_void_space) + dir->direntlen = sizeof_void_space; + else + dir->direntlen = fs->blksz - totalbytes; + + dir->namelen = strlen(filename); + dir->filetype = FILETYPE_REG; /* regular file */ + temp_dir = (char *)dir; + temp_dir = temp_dir + sizeof(struct ext2_dirent); + memcpy(temp_dir, filename, strlen(filename)); + + *p_ino = inodeno; + + /* update or write the 1st block of root inode */ + if (ext4fs_put_metadata(root_first_block_buffer, + first_block_no_of_root)) + goto fail; + +fail: + free(zero_buffer); + free(root_first_block_buffer); +} + +static int search_dir(struct ext2_inode *parent_inode, char *dirname) +{ + int status; + int inodeno; + int totalbytes; + int templength; + int direct_blk_idx; + long int blknr; + int found = 0; + char *ptr = NULL; + unsigned char *block_buffer = NULL; + struct ext2_dirent *dir = NULL; + struct ext2_dirent *previous_dir = NULL; + struct ext_filesystem *fs = get_fs(); + + /* read the block no allocated to a file */ + for (direct_blk_idx = 0; direct_blk_idx < INDIRECT_BLOCKS; + direct_blk_idx++) { + blknr = read_allocated_block(parent_inode, direct_blk_idx); + if (blknr == 0) + goto fail; + + /* read the blocks of parenet inode */ + block_buffer = zalloc(fs->blksz); + if (!block_buffer) + goto fail; + + status = ext4fs_devread(blknr * fs->sect_perblk, + 0, fs->blksz, (char *)block_buffer); + if (status == 0) + goto fail; + + dir = (struct ext2_dirent *)block_buffer; + ptr = (char *)dir; + totalbytes = 0; + while (dir->direntlen >= 0) { + /* + * blocksize-totalbytes because last directory + * length i.e.,*dir->direntlen is free availble + * space in the block that means + * it is a last entry of directory entry + */ + if (strlen(dirname) == dir->namelen) { + if (strncmp(dirname, ptr + + sizeof(struct ext2_dirent), + dir->namelen) == 0) { + previous_dir->direntlen += + dir->direntlen; + inodeno = dir->inode; + dir->inode = 0; + found = 1; + break; + } + } + + if (fs->blksz - totalbytes == dir->direntlen) + break; + + /* traversing the each directory entry */ + templength = dir->direntlen; + totalbytes = totalbytes + templength; + previous_dir = dir; + dir = (struct ext2_dirent *)((char *)dir + templength); + ptr = (char *)dir; + } + + if (found == 1) { + free(block_buffer); + block_buffer = NULL; + return inodeno; + } + + free(block_buffer); + block_buffer = NULL; + } + +fail: + free(block_buffer); + + return -1; +} + +static int find_dir_depth(char *dirname) +{ + char *token = strtok(dirname, "/"); + int count = 0; + while (token != NULL) { + token = strtok(NULL, "/"); + count++; + } + return count + 1 + 1; + /* + * for example for string /home/temp + * depth=home(1)+temp(1)+1 extra for NULL; + * so count is 4; + */ +} + +static int parse_path(char **arr, char *dirname) +{ + char *token = strtok(dirname, "/"); + int i = 0; + + /* add root */ + arr[i] = zalloc(strlen("/") + 1); + if (!arr[i]) + return -ENOMEM; + + arr[i++] = "/"; + + /* add each path entry after root */ + while (token != NULL) { + arr[i] = zalloc(strlen(token) + 1); + if (!arr[i]) + return -ENOMEM; + memcpy(arr[i++], token, strlen(token)); + token = strtok(NULL, "/"); + } + arr[i] = NULL; + + return 0; +} + +int ext4fs_iget(int inode_no, struct ext2_inode *inode) +{ + if (ext4fs_read_inode(ext4fs_root, inode_no, inode) == 0) + return -1; + + return 0; +} + +/* + * Function: ext4fs_get_parent_inode_num + * Return Value: inode Number of the parent directory of file/Directory to be + * created + * dirname : Input parmater, input path name of the file/directory to be created + * dname : Output parameter, to be filled with the name of the directory + * extracted from dirname + */ +int ext4fs_get_parent_inode_num(const char *dirname, char *dname, int flags) +{ + int i; + int depth = 0; + int matched_inode_no; + int result_inode_no = -1; + char **ptr = NULL; + char *depth_dirname = NULL; + char *parse_dirname = NULL; + struct ext2_inode *parent_inode = NULL; + struct ext2_inode *first_inode = NULL; + struct ext2_inode temp_inode; + + if (*dirname != '/') { + printf("Please supply Absolute path\n"); + return -1; + } + + /* TODO: input validation make equivalent to linux */ + depth_dirname = zalloc(strlen(dirname) + 1); + if (!depth_dirname) + return -ENOMEM; + + memcpy(depth_dirname, dirname, strlen(dirname)); + depth = find_dir_depth(depth_dirname); + parse_dirname = zalloc(strlen(dirname) + 1); + if (!parse_dirname) + goto fail; + memcpy(parse_dirname, dirname, strlen(dirname)); + + /* allocate memory for each directory level */ + ptr = zalloc((depth) * sizeof(char *)); + if (!ptr) + goto fail; + if (parse_path(ptr, parse_dirname)) + goto fail; + parent_inode = zalloc(sizeof(struct ext2_inode)); + if (!parent_inode) + goto fail; + first_inode = zalloc(sizeof(struct ext2_inode)); + if (!first_inode) + goto fail; + memcpy(parent_inode, ext4fs_root->inode, sizeof(struct ext2_inode)); + memcpy(first_inode, parent_inode, sizeof(struct ext2_inode)); + if (flags & F_FILE) + result_inode_no = EXT2_ROOT_INO; + for (i = 1; i < depth; i++) { + matched_inode_no = search_dir(parent_inode, ptr[i]); + if (matched_inode_no == -1) { + if (ptr[i + 1] == NULL && i == 1) { + result_inode_no = EXT2_ROOT_INO; + goto end; + } else { + if (ptr[i + 1] == NULL) + break; + printf("Invalid path\n"); + result_inode_no = -1; + goto fail; + } + } else { + if (ptr[i + 1] != NULL) { + memset(parent_inode, '\0', + sizeof(struct ext2_inode)); + if (ext4fs_iget(matched_inode_no, + parent_inode)) { + result_inode_no = -1; + goto fail; + } + result_inode_no = matched_inode_no; + } else { + break; + } + } + } + +end: + if (i == 1) + matched_inode_no = search_dir(first_inode, ptr[i]); + else + matched_inode_no = search_dir(parent_inode, ptr[i]); + + if (matched_inode_no != -1) { + ext4fs_iget(matched_inode_no, &temp_inode); + if (temp_inode.mode & S_IFDIR) { + printf("It is a Directory\n"); + result_inode_no = -1; + goto fail; + } + } + + if (strlen(ptr[i]) > 256) { + result_inode_no = -1; + goto fail; + } + memcpy(dname, ptr[i], strlen(ptr[i])); + +fail: + free(depth_dirname); + free(parse_dirname); + free(ptr); + free(parent_inode); + free(first_inode); + + return result_inode_no; +} + +static int check_filename(char *filename, unsigned int blknr) +{ + unsigned int first_block_no_of_root; + int totalbytes = 0; + int templength = 0; + int status, inodeno; + int found = 0; + char *root_first_block_buffer = NULL; + char *root_first_block_addr = NULL; + struct ext2_dirent *dir = NULL; + struct ext2_dirent *previous_dir = NULL; + char *ptr = NULL; + struct ext_filesystem *fs = get_fs(); + + /* get the first block of root */ + first_block_no_of_root = blknr; + root_first_block_buffer = zalloc(fs->blksz); + if (!root_first_block_buffer) + return -ENOMEM; + root_first_block_addr = root_first_block_buffer; + status = ext4fs_devread(first_block_no_of_root * + fs->sect_perblk, 0, + fs->blksz, root_first_block_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(root_first_block_buffer, first_block_no_of_root)) + goto fail; + dir = (struct ext2_dirent *)root_first_block_buffer; + ptr = (char *)dir; + totalbytes = 0; + while (dir->direntlen >= 0) { + /* + * blocksize-totalbytes because last + * directory length i.e., *dir->direntlen + * is free availble space in the block that + * means it is a last entry of directory entry + */ + if (strlen(filename) == dir->namelen) { + if (strncmp(filename, ptr + sizeof(struct ext2_dirent), + dir->namelen) == 0) { + printf("file found deleting\n"); + previous_dir->direntlen += dir->direntlen; + inodeno = dir->inode; + dir->inode = 0; + found = 1; + break; + } + } + + if (fs->blksz - totalbytes == dir->direntlen) + break; + + /* traversing the each directory entry */ + templength = dir->direntlen; + totalbytes = totalbytes + templength; + previous_dir = dir; + dir = (struct ext2_dirent *)((char *)dir + templength); + ptr = (char *)dir; + } + + + if (found == 1) { + if (ext4fs_put_metadata(root_first_block_addr, + first_block_no_of_root)) + goto fail; + return inodeno; + } +fail: + free(root_first_block_buffer); + + return -1; +} + +int ext4fs_filename_check(char *filename) +{ + short direct_blk_idx = 0; + long int blknr = -1; + int inodeno = -1; + + /* read the block no allocated to a file */ + for (direct_blk_idx = 0; direct_blk_idx < INDIRECT_BLOCKS; + direct_blk_idx++) { + blknr = read_allocated_block(g_parent_inode, direct_blk_idx); + if (blknr == 0) + break; + inodeno = check_filename(filename, blknr); + if (inodeno != -1) + return inodeno; + } + + return -1; +} + +long int ext4fs_get_new_blk_no(void) +{ + short i; + short status; + int remainder; + unsigned int bg_idx; + static int prev_bg_bitmap_index = -1; + unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + char *zero_buffer = zalloc(fs->blksz); + if (!journal_buffer || !zero_buffer) + goto fail; + struct ext2_block_group *gd = (struct ext2_block_group *)fs->gdtable; + + if (fs->first_pass_bbmap == 0) { + for (i = 0; i < fs->no_blkgrp; i++) { + if (gd[i].free_blocks) { + if (gd[i].bg_flags & EXT4_BG_BLOCK_UNINIT) { + put_ext4(((uint64_t) (gd[i].block_id * + fs->blksz)), + zero_buffer, fs->blksz); + gd[i].bg_flags = + gd[i]. + bg_flags & ~EXT4_BG_BLOCK_UNINIT; + memcpy(fs->blk_bmaps[i], zero_buffer, + fs->blksz); + } + fs->curr_blkno = + _get_new_blk_no(fs->blk_bmaps[i]); + if (fs->curr_blkno == -1) + /* if block bitmap is completely fill */ + continue; + fs->curr_blkno = fs->curr_blkno + + (i * fs->blksz * 8); + fs->first_pass_bbmap++; + gd[i].free_blocks--; + fs->sb->free_blocks--; + status = ext4fs_devread(gd[i].block_id * + fs->sect_perblk, 0, + fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[i].block_id)) + goto fail; + goto success; + } else { + debug("no space left on block group %d\n", i); + } + } + + goto fail; + } else { +restart: + fs->curr_blkno++; + /* get the blockbitmap index respective to blockno */ + if (fs->blksz != 1024) { + bg_idx = fs->curr_blkno / blk_per_grp; + } else { + bg_idx = fs->curr_blkno / blk_per_grp; + remainder = fs->curr_blkno % blk_per_grp; + if (!remainder) + bg_idx--; + } + + /* + * To skip completely filled block group bitmaps + * Optimize the block allocation + */ + if (bg_idx >= fs->no_blkgrp) + goto fail; + + if (gd[bg_idx].free_blocks == 0) { + debug("block group %u is full. Skipping\n", bg_idx); + fs->curr_blkno = fs->curr_blkno + blk_per_grp; + fs->curr_blkno--; + goto restart; + } + + if (gd[bg_idx].bg_flags & EXT4_BG_BLOCK_UNINIT) { + memset(zero_buffer, '\0', fs->blksz); + put_ext4(((uint64_t) (gd[bg_idx].block_id * fs->blksz)), + zero_buffer, fs->blksz); + memcpy(fs->blk_bmaps[bg_idx], zero_buffer, fs->blksz); + gd[bg_idx].bg_flags = gd[bg_idx].bg_flags & + ~EXT4_BG_BLOCK_UNINIT; + } + + if (ext4fs_set_block_bmap(fs->curr_blkno, fs->blk_bmaps[bg_idx], + bg_idx) != 0) { + debug("going for restart for the block no %ld %u\n", + fs->curr_blkno, bg_idx); + goto restart; + } + + /* journal backup */ + if (prev_bg_bitmap_index != bg_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[bg_idx].block_id + * fs->sect_perblk, + 0, fs->blksz, journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + + prev_bg_bitmap_index = bg_idx; + } + gd[bg_idx].free_blocks--; + fs->sb->free_blocks--; + goto success; + } +success: + free(journal_buffer); + free(zero_buffer); + + return fs->curr_blkno; +fail: + free(journal_buffer); + free(zero_buffer); + + return -1; +} + +int ext4fs_get_new_inode_no(void) +{ + short i; + short status; + unsigned int ibmap_idx; + static int prev_inode_bitmap_index = -1; + unsigned int inodes_per_grp = ext4fs_root->sblock.inodes_per_group; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + char *zero_buffer = zalloc(fs->blksz); + if (!journal_buffer || !zero_buffer) + goto fail; + struct ext2_block_group *gd = (struct ext2_block_group *)fs->gdtable; + + if (fs->first_pass_ibmap == 0) { + for (i = 0; i < fs->no_blkgrp; i++) { + if (gd[i].free_inodes) { + if (gd[i].bg_itable_unused != gd[i].free_inodes) + gd[i].bg_itable_unused = + gd[i].free_inodes; + if (gd[i].bg_flags & EXT4_BG_INODE_UNINIT) { + put_ext4(((uint64_t) + (gd[i].inode_id * fs->blksz)), + zero_buffer, fs->blksz); + gd[i].bg_flags = gd[i].bg_flags & + ~EXT4_BG_INODE_UNINIT; + memcpy(fs->inode_bmaps[i], + zero_buffer, fs->blksz); + } + fs->curr_inode_no = + _get_new_inode_no(fs->inode_bmaps[i]); + if (fs->curr_inode_no == -1) + /* if block bitmap is completely fill */ + continue; + fs->curr_inode_no = fs->curr_inode_no + + (i * inodes_per_grp); + fs->first_pass_ibmap++; + gd[i].free_inodes--; + gd[i].bg_itable_unused--; + fs->sb->free_inodes--; + status = ext4fs_devread(gd[i].inode_id * + fs->sect_perblk, 0, + fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[i].inode_id)) + goto fail; + goto success; + } else + debug("no inode left on block group %d\n", i); + } + goto fail; + } else { +restart: + fs->curr_inode_no++; + /* get the blockbitmap index respective to blockno */ + ibmap_idx = fs->curr_inode_no / inodes_per_grp; + if (gd[ibmap_idx].bg_flags & EXT4_BG_INODE_UNINIT) { + memset(zero_buffer, '\0', fs->blksz); + put_ext4(((uint64_t) (gd[ibmap_idx].inode_id * + fs->blksz)), zero_buffer, + fs->blksz); + gd[ibmap_idx].bg_flags = + gd[ibmap_idx].bg_flags & ~EXT4_BG_INODE_UNINIT; + memcpy(fs->inode_bmaps[ibmap_idx], zero_buffer, + fs->blksz); + } + + if (ext4fs_set_inode_bmap(fs->curr_inode_no, + fs->inode_bmaps[ibmap_idx], + ibmap_idx) != 0) { + debug("going for restart for the block no %d %u\n", + fs->curr_inode_no, ibmap_idx); + goto restart; + } + + /* journal backup */ + if (prev_inode_bitmap_index != ibmap_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[ibmap_idx].inode_id + * fs->sect_perblk, + 0, fs->blksz, journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[ibmap_idx].inode_id)) + goto fail; + prev_inode_bitmap_index = ibmap_idx; + } + if (gd[ibmap_idx].bg_itable_unused != gd[ibmap_idx].free_inodes) + gd[ibmap_idx].bg_itable_unused = + gd[ibmap_idx].free_inodes; + gd[ibmap_idx].free_inodes--; + gd[ibmap_idx].bg_itable_unused--; + fs->sb->free_inodes--; + goto success; + } + +success: + free(journal_buffer); + free(zero_buffer); + + return fs->curr_inode_no; +fail: + free(journal_buffer); + free(zero_buffer); + + return -1; + +} + + +static void alloc_single_indirect_block(struct ext2_inode *file_inode, + unsigned int *total_remaining_blocks, + unsigned int *no_blks_reqd) +{ + short i; + short status; + long int actual_block_no; + long int si_blockno; + /* si :single indirect */ + unsigned int *si_buffer = NULL; + unsigned int *si_start_addr = NULL; + struct ext_filesystem *fs = get_fs(); + + if (*total_remaining_blocks != 0) { + si_buffer = zalloc(fs->blksz); + if (!si_buffer) { + printf("No Memory\n"); + return; + } + si_start_addr = si_buffer; + si_blockno = ext4fs_get_new_blk_no(); + if (si_blockno == -1) { + printf("no block left to assign\n"); + goto fail; + } + (*no_blks_reqd)++; + debug("SIPB %ld: %u\n", si_blockno, *total_remaining_blocks); + + status = ext4fs_devread(si_blockno * fs->sect_perblk, + 0, fs->blksz, (char *)si_buffer); + memset(si_buffer, '\0', fs->blksz); + if (status == 0) + goto fail; + + for (i = 0; i < (fs->blksz / sizeof(int)); i++) { + actual_block_no = ext4fs_get_new_blk_no(); + if (actual_block_no == -1) { + printf("no block left to assign\n"); + goto fail; + } + *si_buffer = actual_block_no; + debug("SIAB %u: %u\n", *si_buffer, + *total_remaining_blocks); + + si_buffer++; + (*total_remaining_blocks)--; + if (*total_remaining_blocks == 0) + break; + } + + /* write the block to disk */ + put_ext4(((uint64_t) (si_blockno * fs->blksz)), + si_start_addr, fs->blksz); + file_inode->b.blocks.indir_block = si_blockno; + } +fail: + free(si_start_addr); +} + +static void alloc_double_indirect_block(struct ext2_inode *file_inode, + unsigned int *total_remaining_blocks, + unsigned int *no_blks_reqd) +{ + short i; + short j; + short status; + long int actual_block_no; + /* di:double indirect */ + long int di_blockno_parent; + long int di_blockno_child; + unsigned int *di_parent_buffer = NULL; + unsigned int *di_child_buff = NULL; + unsigned int *di_block_start_addr = NULL; + unsigned int *di_child_buff_start = NULL; + struct ext_filesystem *fs = get_fs(); + + if (*total_remaining_blocks != 0) { + /* double indirect parent block connecting to inode */ + di_blockno_parent = ext4fs_get_new_blk_no(); + if (di_blockno_parent == -1) { + printf("no block left to assign\n"); + goto fail; + } + di_parent_buffer = zalloc(fs->blksz); + if (!di_parent_buffer) + goto fail; + + di_block_start_addr = di_parent_buffer; + (*no_blks_reqd)++; + debug("DIPB %ld: %u\n", di_blockno_parent, + *total_remaining_blocks); + + status = ext4fs_devread(di_blockno_parent * + fs->sect_perblk, 0, + fs->blksz, (char *)di_parent_buffer); + memset(di_parent_buffer, '\0', fs->blksz); + + /* + * start:for each double indirect parent + * block create one more block + */ + for (i = 0; i < (fs->blksz / sizeof(int)); i++) { + di_blockno_child = ext4fs_get_new_blk_no(); + if (di_blockno_child == -1) { + printf("no block left to assign\n"); + goto fail; + } + di_child_buff = zalloc(fs->blksz); + if (!di_child_buff) + goto fail; + + di_child_buff_start = di_child_buff; + *di_parent_buffer = di_blockno_child; + di_parent_buffer++; + (*no_blks_reqd)++; + debug("DICB %ld: %u\n", di_blockno_child, + *total_remaining_blocks); + + status = ext4fs_devread(di_blockno_child * + fs->sect_perblk, 0, + fs->blksz, + (char *)di_child_buff); + memset(di_child_buff, '\0', fs->blksz); + /* filling of actual datablocks for each child */ + for (j = 0; j < (fs->blksz / sizeof(int)); j++) { + actual_block_no = ext4fs_get_new_blk_no(); + if (actual_block_no == -1) { + printf("no block left to assign\n"); + goto fail; + } + *di_child_buff = actual_block_no; + debug("DIAB %ld: %u\n", actual_block_no, + *total_remaining_blocks); + + di_child_buff++; + (*total_remaining_blocks)--; + if (*total_remaining_blocks == 0) + break; + } + /* write the block table */ + put_ext4(((uint64_t) (di_blockno_child * fs->blksz)), + di_child_buff_start, fs->blksz); + free(di_child_buff_start); + di_child_buff_start = NULL; + + if (*total_remaining_blocks == 0) + break; + } + put_ext4(((uint64_t) (di_blockno_parent * fs->blksz)), + di_block_start_addr, fs->blksz); + file_inode->b.blocks.double_indir_block = di_blockno_parent; + } +fail: + free(di_block_start_addr); +} + +static void alloc_triple_indirect_block(struct ext2_inode *file_inode, + unsigned int *total_remaining_blocks, + unsigned int *no_blks_reqd) +{ + short i; + short j; + short k; + long int actual_block_no; + /* ti: Triple Indirect */ + long int ti_gp_blockno; + long int ti_parent_blockno; + long int ti_child_blockno; + unsigned int *ti_gp_buff = NULL; + unsigned int *ti_parent_buff = NULL; + unsigned int *ti_child_buff = NULL; + unsigned int *ti_gp_buff_start_addr = NULL; + unsigned int *ti_pbuff_start_addr = NULL; + unsigned int *ti_cbuff_start_addr = NULL; + struct ext_filesystem *fs = get_fs(); + if (*total_remaining_blocks != 0) { + /* triple indirect grand parent block connecting to inode */ + ti_gp_blockno = ext4fs_get_new_blk_no(); + if (ti_gp_blockno == -1) { + printf("no block left to assign\n"); + goto fail; + } + ti_gp_buff = zalloc(fs->blksz); + if (!ti_gp_buff) + goto fail; + + ti_gp_buff_start_addr = ti_gp_buff; + (*no_blks_reqd)++; + debug("TIGPB %ld: %u\n", ti_gp_blockno, + *total_remaining_blocks); + + /* for each 4 byte grand parent entry create one more block */ + for (i = 0; i < (fs->blksz / sizeof(int)); i++) { + ti_parent_blockno = ext4fs_get_new_blk_no(); + if (ti_parent_blockno == -1) { + printf("no block left to assign\n"); + goto fail; + } + ti_parent_buff = zalloc(fs->blksz); + if (!ti_parent_buff) + goto fail; + + ti_pbuff_start_addr = ti_parent_buff; + *ti_gp_buff = ti_parent_blockno; + ti_gp_buff++; + (*no_blks_reqd)++; + debug("TIPB %ld: %u\n", ti_parent_blockno, + *total_remaining_blocks); + + /* for each 4 byte entry parent create one more block */ + for (j = 0; j < (fs->blksz / sizeof(int)); j++) { + ti_child_blockno = ext4fs_get_new_blk_no(); + if (ti_child_blockno == -1) { + printf("no block left assign\n"); + goto fail; + } + ti_child_buff = zalloc(fs->blksz); + if (!ti_child_buff) + goto fail; + + ti_cbuff_start_addr = ti_child_buff; + *ti_parent_buff = ti_child_blockno; + ti_parent_buff++; + (*no_blks_reqd)++; + debug("TICB %ld: %u\n", ti_parent_blockno, + *total_remaining_blocks); + + /* fill actual datablocks for each child */ + for (k = 0; k < (fs->blksz / sizeof(int)); + k++) { + actual_block_no = + ext4fs_get_new_blk_no(); + if (actual_block_no == -1) { + printf("no block left\n"); + goto fail; + } + *ti_child_buff = actual_block_no; + debug("TIAB %ld: %u\n", actual_block_no, + *total_remaining_blocks); + + ti_child_buff++; + (*total_remaining_blocks)--; + if (*total_remaining_blocks == 0) + break; + } + /* write the child block */ + put_ext4(((uint64_t) (ti_child_blockno * + fs->blksz)), + ti_cbuff_start_addr, fs->blksz); + free(ti_cbuff_start_addr); + + if (*total_remaining_blocks == 0) + break; + } + /* write the parent block */ + put_ext4(((uint64_t) (ti_parent_blockno * fs->blksz)), + ti_pbuff_start_addr, fs->blksz); + free(ti_pbuff_start_addr); + + if (*total_remaining_blocks == 0) + break; + } + /* write the grand parent block */ + put_ext4(((uint64_t) (ti_gp_blockno * fs->blksz)), + ti_gp_buff_start_addr, fs->blksz); + file_inode->b.blocks.triple_indir_block = ti_gp_blockno; + } +fail: + free(ti_gp_buff_start_addr); +} + +void ext4fs_allocate_blocks(struct ext2_inode *file_inode, + unsigned int total_remaining_blocks, + unsigned int *total_no_of_block) +{ + short i; + long int direct_blockno; + unsigned int no_blks_reqd = 0; + + /* allocation of direct blocks */ + for (i = 0; i < INDIRECT_BLOCKS; i++) { + direct_blockno = ext4fs_get_new_blk_no(); + if (direct_blockno == -1) { + printf("no block left to assign\n"); + return; + } + file_inode->b.blocks.dir_blocks[i] = direct_blockno; + debug("DB %ld: %u\n", direct_blockno, total_remaining_blocks); + + total_remaining_blocks--; + if (total_remaining_blocks == 0) + break; + } + + alloc_single_indirect_block(file_inode, &total_remaining_blocks, + &no_blks_reqd); + alloc_double_indirect_block(file_inode, &total_remaining_blocks, + &no_blks_reqd); + alloc_triple_indirect_block(file_inode, &total_remaining_blocks, + &no_blks_reqd); + *total_no_of_block += no_blks_reqd; +} + +#endif + static struct ext4_extent_header *ext4fs_get_extent_block (struct ext2_data *data, char *buf, struct ext4_extent_header *ext_block, diff --git a/fs/ext4/ext4_common.h b/fs/ext4/ext4_common.h index 8e8bcbc..801b8b8 100644 --- a/fs/ext4/ext4_common.h +++ b/fs/ext4/ext4_common.h @@ -14,6 +14,8 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 2003, 2004 Free Software Foundation, Inc. * + * ext4write : Based on generic ext4 protocol. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -35,6 +37,10 @@ #include #include #include +#if defined(CONFIG_CMD_EXT4_WRITE) +#include "ext4_journal.h" +#include "crc16.h" +#endif #define YES 1 #define NO 0 @@ -60,4 +66,23 @@ int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode, struct ext2fs_node **foundnode, int expecttype); int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, struct ext2fs_node **fnode, int *ftype); + +#if defined(CONFIG_CMD_EXT4_WRITE) +uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n); +int ext4fs_checksum_update(unsigned int i); +int ext4fs_get_parent_inode_num(const char *dirname, char *dname, int flags); +void ext4fs_update_parent_dentry(char *filename, int *p_ino, int file_type); +long int ext4fs_get_new_blk_no(void); +int ext4fs_get_new_inode_no(void); +void ext4fs_reset_block_bmap(long int blockno, unsigned char *buffer, + int index); +int ext4fs_set_block_bmap(long int blockno, unsigned char *buffer, int index); +int ext4fs_set_inode_bmap(int inode_no, unsigned char *buffer, int index); +void ext4fs_reset_inode_bmap(int inode_no, unsigned char *buffer, int index); +int ext4fs_iget(int inode_no, struct ext2_inode *inode); +void ext4fs_allocate_blocks(struct ext2_inode *file_inode, + unsigned int total_remaining_blocks, + unsigned int *total_no_of_block); +void put_ext4(uint64_t off, void *buf, uint32_t size); +#endif #endif diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c new file mode 100644 index 0000000..8a252d6 --- /dev/null +++ b/fs/ext4/ext4_journal.c @@ -0,0 +1,667 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar + * Manjunatha C Achar + * + * Journal data structures and headers for Journaling feature of ext4 + * have been referred from JBD2 (Journaling Block device 2) + * implementation in Linux Kernel. + * Written by Stephen C. Tweedie + * + * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include "ext4_common.h" + +static struct revoke_blk_list *revk_blk_list; +static struct revoke_blk_list *prev_node; +static int first_node = TRUE; + +int gindex; +int gd_index; +int jrnl_blk_idx; +struct journal_log *journal_ptr[MAX_JOURNAL_ENTRIES]; +struct dirty_blocks *dirty_block_ptr[MAX_JOURNAL_ENTRIES]; + +int ext4fs_init_journal(void) +{ + int i; + char *temp = NULL; + struct ext_filesystem *fs = get_fs(); + + /* init globals */ + revk_blk_list = NULL; + prev_node = NULL; + gindex = 0; + gd_index = 0; + jrnl_blk_idx = 1; + + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + journal_ptr[i] = zalloc(sizeof(struct journal_log)); + if (!journal_ptr[i]) + goto fail; + dirty_block_ptr[i] = zalloc(sizeof(struct dirty_blocks)); + if (!dirty_block_ptr[i]) + goto fail; + journal_ptr[i]->buf = NULL; + journal_ptr[i]->blknr = -1; + + dirty_block_ptr[i]->buf = NULL; + dirty_block_ptr[i]->blknr = -1; + } + + if (fs->blksz == 4096) { + temp = zalloc(fs->blksz); + if (!temp) + goto fail; + journal_ptr[gindex]->buf = zalloc(fs->blksz); + if (!journal_ptr[gindex]->buf) + goto fail; + ext4fs_devread(0, 0, fs->blksz, temp); + memcpy(temp + SUPERBLOCK_SIZE, fs->sb, SUPERBLOCK_SIZE); + memcpy(journal_ptr[gindex]->buf, temp, fs->blksz); + journal_ptr[gindex++]->blknr = 0; + free(temp); + } else { + journal_ptr[gindex]->buf = zalloc(fs->blksz); + if (!journal_ptr[gindex]->buf) + goto fail; + memcpy(journal_ptr[gindex]->buf, fs->sb, SUPERBLOCK_SIZE); + journal_ptr[gindex++]->blknr = 1; + } + + /* Check the file system state using journal super block */ + if (ext4fs_check_journal_state(SCAN)) + goto fail; + /* Check the file system state using journal super block */ + if (ext4fs_check_journal_state(RECOVER)) + goto fail; + + return 0; +fail: + return -1; +} + +void ext4fs_dump_metadata(void) +{ + struct ext_filesystem *fs = get_fs(); + int i; + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (dirty_block_ptr[i]->blknr == -1) + break; + put_ext4((uint64_t) ((uint64_t)dirty_block_ptr[i]->blknr * + (uint64_t)fs->blksz), dirty_block_ptr[i]->buf, + fs->blksz); + } +} + +void ext4fs_free_journal(void) +{ + int i; + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (dirty_block_ptr[i]->blknr == -1) + break; + if (dirty_block_ptr[i]->buf) + free(dirty_block_ptr[i]->buf); + } + + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (journal_ptr[i]->blknr == -1) + break; + if (journal_ptr[i]->buf) + free(journal_ptr[i]->buf); + } + + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (journal_ptr[i]) + free(journal_ptr[i]); + if (dirty_block_ptr[i]) + free(dirty_block_ptr[i]); + } + gindex = 0; + gd_index = 0; + jrnl_blk_idx = 1; +} + +int ext4fs_log_gdt(char *gd_table) +{ + struct ext_filesystem *fs = get_fs(); + short i; + long int var = fs->gdtable_blkno; + for (i = 0; i < fs->no_blk_pergdt; i++) { + journal_ptr[gindex]->buf = zalloc(fs->blksz); + if (!journal_ptr[gindex]->buf) + return -ENOMEM; + memcpy(journal_ptr[gindex]->buf, gd_table, fs->blksz); + gd_table += fs->blksz; + journal_ptr[gindex++]->blknr = var++; + } + + return 0; +} + +/* + * This function stores the backup copy of meta data in RAM + * journal_buffer -- Buffer containing meta data + * blknr -- Block number on disk of the meta data buffer + */ +int ext4fs_log_journal(char *journal_buffer, long int blknr) +{ + struct ext_filesystem *fs = get_fs(); + short i; + + if (!journal_buffer) { + printf("Invalid input arguments %s\n", __func__); + return -EINVAL; + } + + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (journal_ptr[i]->blknr == -1) + break; + if (journal_ptr[i]->blknr == blknr) + return 0; + } + + journal_ptr[gindex]->buf = zalloc(fs->blksz); + if (!journal_ptr[gindex]->buf) + return -ENOMEM; + + memcpy(journal_ptr[gindex]->buf, journal_buffer, fs->blksz); + journal_ptr[gindex++]->blknr = blknr; + + return 0; +} + +/* + * This function stores the modified meta data in RAM + * metadata_buffer -- Buffer containing meta data + * blknr -- Block number on disk of the meta data buffer + */ +int ext4fs_put_metadata(char *metadata_buffer, long int blknr) +{ + struct ext_filesystem *fs = get_fs(); + if (!metadata_buffer) { + printf("Invalid input arguments %s\n", __func__); + return -EINVAL; + } + dirty_block_ptr[gd_index]->buf = zalloc(fs->blksz); + if (!dirty_block_ptr[gd_index]->buf) + return -ENOMEM; + memcpy(dirty_block_ptr[gd_index]->buf, metadata_buffer, fs->blksz); + dirty_block_ptr[gd_index++]->blknr = blknr; + + return 0; +} + +void print_revoke_blks(char *revk_blk) +{ + int offset; + int max; + long int blocknr; + struct journal_revoke_header_t *header; + + if (revk_blk == NULL) + return; + + header = (struct journal_revoke_header_t *) revk_blk; + offset = sizeof(struct journal_revoke_header_t); + max = be32_to_cpu(header->r_count); + printf("total bytes %d\n", max); + + while (offset < max) { + blocknr = be32_to_cpu(*((long int *)(revk_blk + offset))); + printf("revoke blknr is %ld\n", blocknr); + offset += 4; + } +} + +static struct revoke_blk_list *_get_node(void) +{ + struct revoke_blk_list *tmp_node; + tmp_node = zalloc(sizeof(struct revoke_blk_list)); + if (tmp_node == NULL) + return NULL; + tmp_node->content = NULL; + tmp_node->next = NULL; + + return tmp_node; +} + +void ext4fs_push_revoke_blk(char *buffer) +{ + struct revoke_blk_list *node = NULL; + struct ext_filesystem *fs = get_fs(); + if (buffer == NULL) { + printf("buffer ptr is NULL\n"); + return; + } + node = _get_node(); + if (!node) { + printf("_get_node: malloc failed\n"); + return; + } + + node->content = zalloc(fs->blksz); + if (node->content == NULL) + return; + memcpy(node->content, buffer, fs->blksz); + + if (first_node == TRUE) { + revk_blk_list = node; + prev_node = node; + first_node = FALSE; + } else { + prev_node->next = node; + prev_node = node; + } +} + +void ext4fs_free_revoke_blks(void) +{ + struct revoke_blk_list *tmp_node = revk_blk_list; + struct revoke_blk_list *next_node = NULL; + + while (tmp_node != NULL) { + if (tmp_node->content) + free(tmp_node->content); + tmp_node = tmp_node->next; + } + + tmp_node = revk_blk_list; + while (tmp_node != NULL) { + next_node = tmp_node->next; + free(tmp_node); + tmp_node = next_node; + } + + revk_blk_list = NULL; + prev_node = NULL; + first_node = TRUE; +} + +int check_blknr_for_revoke(long int blknr, int sequence_no) +{ + struct journal_revoke_header_t *header; + int offset; + int max; + long int blocknr; + char *revk_blk; + struct revoke_blk_list *tmp_revk_node = revk_blk_list; + while (tmp_revk_node != NULL) { + revk_blk = tmp_revk_node->content; + + header = (struct journal_revoke_header_t *) revk_blk; + if (sequence_no < be32_to_cpu(header->r_header.h_sequence)) { + offset = sizeof(struct journal_revoke_header_t); + max = be32_to_cpu(header->r_count); + + while (offset < max) { + blocknr = be32_to_cpu(*((long int *) + (revk_blk + offset))); + if (blocknr == blknr) + goto found; + offset += 4; + } + } + tmp_revk_node = tmp_revk_node->next; + } + + return -1; + +found: + return 0; +} + +/* + * This function parses the journal blocks and replays the + * suceessful transactions. A transaction is successfull + * if commit block is found for a descriptor block + * The tags in descriptor block contain the disk block + * numbers of the metadata to be replayed + */ +void recover_transaction(int prev_desc_logical_no) +{ + struct ext2_inode inode_journal; + struct ext_filesystem *fs = get_fs(); + struct journal_header_t *jdb; + long int blknr; + char *p_jdb; + int ofs, flags; + int i; + struct ext3_journal_block_tag *tag; + char *temp_buff = zalloc(fs->blksz); + char *metadata_buff = zalloc(fs->blksz); + if (!temp_buff || !metadata_buff) + goto fail; + i = prev_desc_logical_no; + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, + (struct ext2_inode *)&inode_journal); + blknr = read_allocated_block((struct ext2_inode *) + &inode_journal, i); + ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff); + p_jdb = (char *)temp_buff; + jdb = (struct journal_header_t *) temp_buff; + ofs = sizeof(struct journal_header_t); + + do { + tag = (struct ext3_journal_block_tag *)&p_jdb[ofs]; + ofs += sizeof(struct ext3_journal_block_tag); + + if (ofs > fs->blksz) + break; + + flags = be32_to_cpu(tag->flags); + if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID)) + ofs += 16; + + i++; + debug("\t\ttag %u\n", be32_to_cpu(tag->block)); + if (revk_blk_list != NULL) { + if (check_blknr_for_revoke(be32_to_cpu(tag->block), + be32_to_cpu(jdb->h_sequence)) == 0) + continue; + } + blknr = read_allocated_block(&inode_journal, i); + ext4fs_devread(blknr * fs->sect_perblk, 0, + fs->blksz, metadata_buff); + put_ext4((uint64_t)(be32_to_cpu(tag->block) * fs->blksz), + metadata_buff, (uint32_t) fs->blksz); + } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG)); +fail: + free(temp_buff); + free(metadata_buff); +} + +void print_jrnl_status(int recovery_flag) +{ + if (recovery_flag == RECOVER) + printf("Journal Recovery Completed\n"); + else + printf("Journal Scan Completed\n"); +} + +int ext4fs_check_journal_state(int recovery_flag) +{ + int i; + int DB_FOUND = NO; + long int blknr; + int transaction_state = TRANSACTION_COMPLETE; + int prev_desc_logical_no = 0; + int curr_desc_logical_no = 0; + int ofs, flags, block; + struct ext2_inode inode_journal; + struct journal_superblock_t *jsb = NULL; + struct journal_header_t *jdb = NULL; + char *p_jdb = NULL; + struct ext3_journal_block_tag *tag = NULL; + char *temp_buff = NULL; + char *temp_buff1 = NULL; + struct ext_filesystem *fs = get_fs(); + + temp_buff = zalloc(fs->blksz); + if (!temp_buff) + return -ENOMEM; + temp_buff1 = zalloc(fs->blksz); + if (!temp_buff1) { + free(temp_buff); + return -ENOMEM; + } + + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal); + blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK); + ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, temp_buff); + jsb = (struct journal_superblock_t *) temp_buff; + + if (fs->sb->feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) { + if (recovery_flag == RECOVER) + printf("Recovery required\n"); + } else { + if (recovery_flag == RECOVER) + printf("File System is consistent\n"); + goto end; + } + + if (be32_to_cpu(jsb->s_start) == 0) + goto end; + + if (!(jsb->s_feature_compat & + cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM))) + jsb->s_feature_compat |= + cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM); + + i = be32_to_cpu(jsb->s_first); + while (1) { + block = be32_to_cpu(jsb->s_first); + blknr = read_allocated_block(&inode_journal, i); + memset(temp_buff1, '\0', fs->blksz); + ext4fs_devread(blknr * fs->sect_perblk, + 0, fs->blksz, temp_buff1); + jdb = (struct journal_header_t *) temp_buff1; + + if (be32_to_cpu(jdb->h_blocktype) == + EXT3_JOURNAL_DESCRIPTOR_BLOCK) { + if (be32_to_cpu(jdb->h_sequence) != + be32_to_cpu(jsb->s_sequence)) { + print_jrnl_status(recovery_flag); + break; + } + + curr_desc_logical_no = i; + if (transaction_state == TRANSACTION_COMPLETE) + transaction_state = TRANSACTION_RUNNING; + else + return -1; + p_jdb = (char *)temp_buff1; + ofs = sizeof(struct journal_header_t); + do { + tag = (struct ext3_journal_block_tag *) + &p_jdb[ofs]; + ofs += sizeof(struct ext3_journal_block_tag); + if (ofs > fs->blksz) + break; + flags = be32_to_cpu(tag->flags); + if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID)) + ofs += 16; + i++; + debug("\t\ttag %u\n", be32_to_cpu(tag->block)); + } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG)); + i++; + DB_FOUND = YES; + } else if (be32_to_cpu(jdb->h_blocktype) == + EXT3_JOURNAL_COMMIT_BLOCK) { + if (be32_to_cpu(jdb->h_sequence) != + be32_to_cpu(jsb->s_sequence)) { + print_jrnl_status(recovery_flag); + break; + } + + if (transaction_state == TRANSACTION_RUNNING || + (DB_FOUND == NO)) { + transaction_state = TRANSACTION_COMPLETE; + i++; + jsb->s_sequence = + cpu_to_be32(be32_to_cpu( + jsb->s_sequence) + 1); + } + prev_desc_logical_no = curr_desc_logical_no; + if ((recovery_flag == RECOVER) && (DB_FOUND == YES)) + recover_transaction(prev_desc_logical_no); + + DB_FOUND = NO; + } else if (be32_to_cpu(jdb->h_blocktype) == + EXT3_JOURNAL_REVOKE_BLOCK) { + if (be32_to_cpu(jdb->h_sequence) != + be32_to_cpu(jsb->s_sequence)) { + print_jrnl_status(recovery_flag); + break; + } + if (recovery_flag == SCAN) + ext4fs_push_revoke_blk((char *)jdb); + i++; + } else { + debug("Else Case\n"); + if (be32_to_cpu(jdb->h_sequence) != + be32_to_cpu(jsb->s_sequence)) { + print_jrnl_status(recovery_flag); + break; + } + } + } + +end: + if (recovery_flag == RECOVER) { + jsb->s_start = cpu_to_be32(1); + jsb->s_sequence = cpu_to_be32(be32_to_cpu(jsb->s_sequence) + 1); + /* get the superblock */ + ext4fs_devread(SUPERBLOCK_SECTOR, 0, SUPERBLOCK_SIZE, + (char *)fs->sb); + fs->sb->feature_incompat |= EXT3_FEATURE_INCOMPAT_RECOVER; + + /* Update the super block */ + put_ext4((uint64_t) (SUPERBLOCK_SIZE), + (struct ext2_sblock *)fs->sb, + (uint32_t) SUPERBLOCK_SIZE); + ext4fs_devread(SUPERBLOCK_SECTOR, 0, SUPERBLOCK_SIZE, + (char *)fs->sb); + + blknr = read_allocated_block(&inode_journal, + EXT2_JOURNAL_SUPERBLOCK); + put_ext4((uint64_t) (blknr * fs->blksz), + (struct journal_superblock_t *)temp_buff, + (uint32_t) fs->blksz); + ext4fs_free_revoke_blks(); + } + free(temp_buff); + free(temp_buff1); + + return 0; +} + +static void update_descriptor_block(long int blknr) +{ + int i; + long int jsb_blknr; + struct journal_header_t jdb; + struct ext3_journal_block_tag tag; + struct ext2_inode inode_journal; + struct journal_superblock_t *jsb = NULL; + char *buf = NULL; + char *temp = NULL; + struct ext_filesystem *fs = get_fs(); + char *temp_buff = zalloc(fs->blksz); + if (!temp_buff) + return; + + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal); + jsb_blknr = read_allocated_block(&inode_journal, + EXT2_JOURNAL_SUPERBLOCK); + ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff); + jsb = (struct journal_superblock_t *) temp_buff; + + jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK); + jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER); + jdb.h_sequence = jsb->s_sequence; + buf = zalloc(fs->blksz); + if (!buf) { + free(temp_buff); + return; + } + temp = buf; + memcpy(buf, &jdb, sizeof(struct journal_header_t)); + temp += sizeof(struct journal_header_t); + + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (journal_ptr[i]->blknr == -1) + break; + + tag.block = cpu_to_be32(journal_ptr[i]->blknr); + tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_SAME_UUID); + memcpy(temp, &tag, sizeof(struct ext3_journal_block_tag)); + temp = temp + sizeof(struct ext3_journal_block_tag); + } + + tag.block = cpu_to_be32(journal_ptr[--i]->blknr); + tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG); + memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag, + sizeof(struct ext3_journal_block_tag)); + put_ext4((uint64_t) (blknr * fs->blksz), buf, (uint32_t) fs->blksz); + + free(temp_buff); + free(buf); +} + +static void update_commit_block(long int blknr) +{ + struct journal_header_t jdb; + struct ext_filesystem *fs = get_fs(); + char *buf = NULL; + struct ext2_inode inode_journal; + struct journal_superblock_t *jsb; + long int jsb_blknr; + char *temp_buff = zalloc(fs->blksz); + if (!temp_buff) + return; + + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal); + jsb_blknr = read_allocated_block(&inode_journal, + EXT2_JOURNAL_SUPERBLOCK); + ext4fs_devread(jsb_blknr * fs->sect_perblk, 0, fs->blksz, temp_buff); + jsb = (struct journal_superblock_t *) temp_buff; + + jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK); + jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER); + jdb.h_sequence = jsb->s_sequence; + buf = zalloc(fs->blksz); + if (!buf) { + free(temp_buff); + return; + } + memcpy(buf, &jdb, sizeof(struct journal_header_t)); + put_ext4((uint64_t) (blknr * fs->blksz), buf, (uint32_t) fs->blksz); + + free(temp_buff); + free(buf); +} + +void ext4fs_update_journal(void) +{ + struct ext2_inode inode_journal; + struct ext_filesystem *fs = get_fs(); + long int blknr; + int i; + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal); + blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++); + update_descriptor_block(blknr); + for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { + if (journal_ptr[i]->blknr == -1) + break; + blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++); + put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), + journal_ptr[i]->buf, fs->blksz); + } + blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++); + update_commit_block(blknr); + printf("update journal finished\n"); +} diff --git a/fs/ext4/ext4_journal.h b/fs/ext4/ext4_journal.h new file mode 100644 index 0000000..acc1c516 --- /dev/null +++ b/fs/ext4/ext4_journal.h @@ -0,0 +1,141 @@ +/* + * (C) Copyright 2011 - 2012 Samsung Electronics + * EXT4 filesystem implementation in Uboot by + * Uma Shankar + * Manjunatha C Achar + * + * Journal data structures and headers for Journaling feature of ext4 + * have been referred from JBD2 (Journaling Block device 2) + * implementation in Linux Kernel. + * + * Written by Stephen C. Tweedie + * + * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __EXT4_JRNL__ +#define __EXT4_JRNL__ + +#define EXT2_JOURNAL_INO 8 /* Journal inode */ +#define EXT2_JOURNAL_SUPERBLOCK 0 /* Journal Superblock number */ + +#define JBD2_FEATURE_COMPAT_CHECKSUM 0x00000001 +#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U +#define TRANSACTION_RUNNING 1 +#define TRANSACTION_COMPLETE 0 +#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ +#define EXT3_JOURNAL_DESCRIPTOR_BLOCK 1 +#define EXT3_JOURNAL_COMMIT_BLOCK 2 +#define EXT3_JOURNAL_SUPERBLOCK_V1 3 +#define EXT3_JOURNAL_SUPERBLOCK_V2 4 +#define EXT3_JOURNAL_REVOKE_BLOCK 5 +#define EXT3_JOURNAL_FLAG_ESCAPE 1 +#define EXT3_JOURNAL_FLAG_SAME_UUID 2 +#define EXT3_JOURNAL_FLAG_DELETED 4 +#define EXT3_JOURNAL_FLAG_LAST_TAG 8 + +/* Maximum entries in 1 journal transaction */ +#define MAX_JOURNAL_ENTRIES 100 +struct journal_log { + char *buf; + int blknr; +}; + +struct dirty_blocks { + char *buf; + int blknr; +}; + +/* Standard header for all descriptor blocks: */ +struct journal_header_t { + __u32 h_magic; + __u32 h_blocktype; + __u32 h_sequence; +}; + +/* The journal superblock. All fields are in big-endian byte order. */ +struct journal_superblock_t { + /* 0x0000 */ + struct journal_header_t s_header; + + /* Static information describing the journal */ + __u32 s_blocksize; /* journal device blocksize */ + __u32 s_maxlen; /* total blocks in journal file */ + __u32 s_first; /* first block of log information */ + + /* Dynamic information describing the current state of the log */ + __u32 s_sequence; /* first commit ID expected in log */ + __u32 s_start; /* blocknr of start of log */ + + /* Error value, as set by journal_abort(). */ + __s32 s_errno; + + /* Remaining fields are only valid in a version-2 superblock */ + __u32 s_feature_compat; /* compatible feature set */ + __u32 s_feature_incompat; /* incompatible feature set */ + __u32 s_feature_ro_compat; /* readonly-compatible feature set */ + /* 0x0030 */ + __u8 s_uuid[16]; /* 128-bit uuid for journal */ + + /* 0x0040 */ + __u32 s_nr_users; /* Nr of filesystems sharing log */ + + __u32 s_dynsuper; /* Blocknr of dynamic superblock copy */ + + /* 0x0048 */ + __u32 s_max_transaction; /* Limit of journal blocks per trans. */ + __u32 s_max_trans_data; /* Limit of data blocks per trans. */ + + /* 0x0050 */ + __u32 s_padding[44]; + + /* 0x0100 */ + __u8 s_users[16 * 48]; /* ids of all fs'es sharing the log */ + /* 0x0400 */ +} ; + +struct ext3_journal_block_tag { + uint32_t block; + uint32_t flags; +}; + +struct journal_revoke_header_t { + struct journal_header_t r_header; + int r_count; /* Count of bytes used in the block */ +}; + +struct revoke_blk_list { + char *content; /* revoke block itself */ + struct revoke_blk_list *next; +}; + +extern struct ext2_data *ext4fs_root; + +int ext4fs_init_journal(void); +int ext4fs_log_gdt(char *gd_table); +int ext4fs_check_journal_state(int recovery_flag); +int ext4fs_log_journal(char *journal_buffer, long int blknr); +int ext4fs_put_metadata(char *metadata_buffer, long int blknr); +void ext4fs_update_journal(void); +void ext4fs_dump_metadata(void); +void ext4fs_push_revoke_blk(char *buffer); +void ext4fs_free_journal(void); +void ext4fs_free_revoke_blks(void); +#endif diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c index 1287bf0..114c2a2 100644 --- a/fs/ext4/ext4fs.c +++ b/fs/ext4/ext4fs.c @@ -16,6 +16,8 @@ * GRUB -- GRand Unified Bootloader * Copyright (C) 2003, 2004 Free Software Foundation, Inc. * + * ext4write : Based on generic ext4 protocol. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -226,3 +228,962 @@ int ext4fs_read(char *buf, unsigned len) return ext4fs_read_file(ext4fs_file, 0, len, buf); } + +#if defined(CONFIG_CMD_EXT4_WRITE) +static void ext4fs_update(void) +{ + short i; + ext4fs_update_journal(); + struct ext_filesystem *fs = get_fs(); + + /* update super block */ + put_ext4((uint64_t)(SUPERBLOCK_SIZE), + (struct ext2_sblock *)fs->sb, (uint32_t)SUPERBLOCK_SIZE); + + /* update block groups */ + for (i = 0; i < fs->no_blkgrp; i++) { + fs->gd[i].bg_checksum = ext4fs_checksum_update(i); + put_ext4((uint64_t)(fs->gd[i].block_id * fs->blksz), + fs->blk_bmaps[i], fs->blksz); + } + + /* update inode table groups */ + for (i = 0; i < fs->no_blkgrp; i++) { + put_ext4((uint64_t) (fs->gd[i].inode_id * fs->blksz), + fs->inode_bmaps[i], fs->blksz); + } + + /* update the block group descriptor table */ + put_ext4((uint64_t)(fs->gdtable_blkno * fs->blksz), + (struct ext2_block_group *)fs->gdtable, + (fs->blksz * fs->no_blk_pergdt)); + + ext4fs_dump_metadata(); + + gindex = 0; + gd_index = 0; +} + +int ext4fs_get_bgdtable(void) +{ + int status; + int grp_desc_size; + struct ext_filesystem *fs = get_fs(); + grp_desc_size = sizeof(struct ext2_block_group); + fs->no_blk_pergdt = (fs->no_blkgrp * grp_desc_size) / fs->blksz; + if ((fs->no_blkgrp * grp_desc_size) % fs->blksz) + fs->no_blk_pergdt++; + + /* allocate memory for gdtable */ + fs->gdtable = zalloc(fs->blksz * fs->no_blk_pergdt); + if (!fs->gdtable) + return -ENOMEM; + /* read the group descriptor table */ + status = ext4fs_devread(fs->gdtable_blkno * fs->sect_perblk, 0, + fs->blksz * fs->no_blk_pergdt, fs->gdtable); + if (status == 0) + goto fail; + + if (ext4fs_log_gdt(fs->gdtable)) { + printf("Error in ext4fs_log_gdt\n"); + return -1; + } + + return 0; +fail: + free(fs->gdtable); + fs->gdtable = NULL; + + return -1; +} + +static void delete_single_indirect_block(struct ext2_inode *inode) +{ + struct ext2_block_group *gd = NULL; + static int prev_bg_bmap_idx = -1; + long int blknr; + int remainder; + int bg_idx; + int status; + unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + if (!journal_buffer) { + printf("No memory\n"); + return; + } + /* get block group descriptor table */ + gd = (struct ext2_block_group *)fs->gdtable; + + /* deleting the single indirect block associated with inode */ + if (inode->b.blocks.indir_block != 0) { + debug("SIPB releasing %u\n", inode->b.blocks.indir_block); + blknr = inode->b.blocks.indir_block; + if (fs->blksz != 1024) { + bg_idx = blknr / blk_per_grp; + } else { + bg_idx = blknr / blk_per_grp; + remainder = blknr % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx); + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + status = + ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal + (journal_buffer, gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } +fail: + free(journal_buffer); +} + +static void delete_double_indirect_block(struct ext2_inode *inode) +{ + int i; + short status; + static int prev_bg_bmap_idx = -1; + long int blknr; + int remainder; + int bg_idx; + unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; + unsigned int *di_buffer = NULL; + unsigned int *DIB_start_addr = NULL; + struct ext2_block_group *gd = NULL; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + if (!journal_buffer) { + printf("No memory\n"); + return; + } + /* get the block group descriptor table */ + gd = (struct ext2_block_group *)fs->gdtable; + + if (inode->b.blocks.double_indir_block != 0) { + di_buffer = zalloc(fs->blksz); + if (!di_buffer) { + printf("No memory\n"); + return; + } + DIB_start_addr = (unsigned int *)di_buffer; + blknr = inode->b.blocks.double_indir_block; + status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, + (char *)di_buffer); + for (i = 0; i < fs->blksz / sizeof(int); i++) { + if (*di_buffer == 0) + break; + + debug("DICB releasing %u\n", *di_buffer); + if (fs->blksz != 1024) { + bg_idx = (*di_buffer) / blk_per_grp; + } else { + bg_idx = (*di_buffer) / blk_per_grp; + remainder = (*di_buffer) % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(*di_buffer, + fs->blk_bmaps[bg_idx], bg_idx); + di_buffer++; + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + status = ext4fs_devread(gd[bg_idx].block_id + * fs->sect_perblk, 0, + fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } + + /* removing the parent double indirect block */ + blknr = inode->b.blocks.double_indir_block; + if (fs->blksz != 1024) { + bg_idx = blknr / blk_per_grp; + } else { + bg_idx = blknr / blk_per_grp; + remainder = blknr % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx); + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + debug("DIPB releasing %ld\n", blknr); + } +fail: + free(DIB_start_addr); + free(journal_buffer); +} + +static void delete_triple_indirect_block(struct ext2_inode *inode) +{ + int i, j; + short status; + static int prev_bg_bmap_idx = -1; + long int blknr; + int remainder; + int bg_idx; + unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; + unsigned int *tigp_buffer = NULL; + unsigned int *tib_start_addr = NULL; + unsigned int *tip_buffer = NULL; + unsigned int *tipb_start_addr = NULL; + struct ext2_block_group *gd = NULL; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + if (!journal_buffer) { + printf("No memory\n"); + return; + } + /* get block group descriptor table */ + gd = (struct ext2_block_group *)fs->gdtable; + + if (inode->b.blocks.triple_indir_block != 0) { + tigp_buffer = zalloc(fs->blksz); + if (!tigp_buffer) { + printf("No memory\n"); + return; + } + tib_start_addr = (unsigned int *)tigp_buffer; + blknr = inode->b.blocks.triple_indir_block; + status = ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, + (char *)tigp_buffer); + for (i = 0; i < fs->blksz / sizeof(int); i++) { + if (*tigp_buffer == 0) + break; + debug("tigp buffer releasing %u\n", *tigp_buffer); + + tip_buffer = zalloc(fs->blksz); + if (!tip_buffer) + goto fail; + tipb_start_addr = (unsigned int *)tip_buffer; + status = ext4fs_devread((*tigp_buffer) * + fs->sect_perblk, 0, fs->blksz, + (char *)tip_buffer); + for (j = 0; j < fs->blksz / sizeof(int); j++) { + if (*tip_buffer == 0) + break; + if (fs->blksz != 1024) { + bg_idx = (*tip_buffer) / blk_per_grp; + } else { + bg_idx = (*tip_buffer) / blk_per_grp; + + remainder = (*tip_buffer) % blk_per_grp; + if (!remainder) + bg_idx--; + } + + ext4fs_reset_block_bmap(*tip_buffer, + fs->blk_bmaps[bg_idx], + bg_idx); + + tip_buffer++; + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + status = + ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, + fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx]. + block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } + free(tipb_start_addr); + tipb_start_addr = NULL; + + /* + * removing the grand parent blocks + * which is connected to inode + */ + if (fs->blksz != 1024) { + bg_idx = (*tigp_buffer) / blk_per_grp; + } else { + bg_idx = (*tigp_buffer) / blk_per_grp; + + remainder = (*tigp_buffer) % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(*tigp_buffer, + fs->blk_bmaps[bg_idx], bg_idx); + + tigp_buffer++; + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = + ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, + fs->blksz, journal_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } + + /* removing the grand parent triple indirect block */ + blknr = inode->b.blocks.triple_indir_block; + if (fs->blksz != 1024) { + bg_idx = blknr / blk_per_grp; + } else { + bg_idx = blknr / blk_per_grp; + remainder = blknr % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx); + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + debug("tigp buffer itself releasing %ld\n", blknr); + } +fail: + free(tib_start_addr); + free(tipb_start_addr); + free(journal_buffer); +} + +static int ext4fs_delete_file(int inodeno) +{ + struct ext2_inode inode; + short status; + int i; + int remainder; + long int blknr; + int bg_idx; + int ibmap_idx; + char *read_buffer = NULL; + char *start_block_address = NULL; + unsigned int no_blocks; + + static int prev_bg_bmap_idx = -1; + unsigned int inodes_per_block; + long int blkno; + unsigned int blkoff; + unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; + unsigned int inode_per_grp = ext4fs_root->sblock.inodes_per_group; + struct ext2_inode *inode_buffer = NULL; + struct ext2_block_group *gd = NULL; + struct ext_filesystem *fs = get_fs(); + char *journal_buffer = zalloc(fs->blksz); + if (!journal_buffer) + return -ENOMEM; + /* get the block group descriptor table */ + gd = (struct ext2_block_group *)fs->gdtable; + status = ext4fs_read_inode(ext4fs_root, inodeno, &inode); + if (status == 0) + goto fail; + + /* read the block no allocated to a file */ + no_blocks = inode.size / fs->blksz; + if (inode.size % fs->blksz) + no_blocks++; + + if (le32_to_cpu(inode.flags) & EXT4_EXTENTS_FL) { + struct ext2fs_node *node_inode = + zalloc(sizeof(struct ext2fs_node)); + if (!node_inode) + goto fail; + node_inode->data = ext4fs_root; + node_inode->ino = inodeno; + node_inode->inode_read = 0; + memcpy(&(node_inode->inode), &inode, sizeof(struct ext2_inode)); + + for (i = 0; i < no_blocks; i++) { + blknr = read_allocated_block(&(node_inode->inode), i); + if (fs->blksz != 1024) { + bg_idx = blknr / blk_per_grp; + } else { + bg_idx = blknr / blk_per_grp; + remainder = blknr % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], + bg_idx); + debug("EXT4_EXTENTS Block releasing %ld: %d\n", + blknr, bg_idx); + + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + status = + ext4fs_devread(gd[bg_idx].block_id * + fs->sect_perblk, 0, + fs->blksz, journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } + if (node_inode) { + free(node_inode); + node_inode = NULL; + } + } else { + + delete_single_indirect_block(&inode); + delete_double_indirect_block(&inode); + delete_triple_indirect_block(&inode); + + /* read the block no allocated to a file */ + no_blocks = inode.size / fs->blksz; + if (inode.size % fs->blksz) + no_blocks++; + for (i = 0; i < no_blocks; i++) { + blknr = read_allocated_block(&inode, i); + if (fs->blksz != 1024) { + bg_idx = blknr / blk_per_grp; + } else { + bg_idx = blknr / blk_per_grp; + remainder = blknr % blk_per_grp; + if (!remainder) + bg_idx--; + } + ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], + bg_idx); + debug("ActualB releasing %ld: %d\n", blknr, bg_idx); + + gd[bg_idx].free_blocks++; + fs->sb->free_blocks++; + /* journal backup */ + if (prev_bg_bmap_idx != bg_idx) { + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[bg_idx].block_id + * fs->sect_perblk, + 0, fs->blksz, + journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, + gd[bg_idx].block_id)) + goto fail; + prev_bg_bmap_idx = bg_idx; + } + } + } + + /* from the inode no to blockno */ + inodes_per_block = fs->blksz / fs->inodesz; + ibmap_idx = inodeno / inode_per_grp; + + /* get the block no */ + inodeno--; + blkno = __le32_to_cpu(gd[ibmap_idx].inode_table_id) + + (inodeno % __le32_to_cpu(inode_per_grp)) / inodes_per_block; + + /* get the offset of the inode */ + blkoff = ((inodeno) % inodes_per_block) * fs->inodesz; + + /* read the block no containing the inode */ + read_buffer = zalloc(fs->blksz); + if (!read_buffer) + goto fail; + start_block_address = read_buffer; + status = ext4fs_devread(blkno * fs->sect_perblk, + 0, fs->blksz, read_buffer); + if (status == 0) + goto fail; + + if (ext4fs_log_journal(read_buffer, blkno)) + goto fail; + + read_buffer = read_buffer + blkoff; + inode_buffer = (struct ext2_inode *)read_buffer; + memset(inode_buffer, '\0', sizeof(struct ext2_inode)); + + /* write the inode to original position in inode table */ + if (ext4fs_put_metadata(start_block_address, blkno)) + goto fail; + + /* update the respective inode bitmaps */ + inodeno++; + ext4fs_reset_inode_bmap(inodeno, fs->inode_bmaps[ibmap_idx], ibmap_idx); + gd[ibmap_idx].free_inodes++; + fs->sb->free_inodes++; + /* journal backup */ + memset(journal_buffer, '\0', fs->blksz); + status = ext4fs_devread(gd[ibmap_idx].inode_id * + fs->sect_perblk, 0, fs->blksz, journal_buffer); + if (status == 0) + goto fail; + if (ext4fs_log_journal(journal_buffer, gd[ibmap_idx].inode_id)) + goto fail; + + ext4fs_update(); + ext4fs_deinit(); + + if (ext4fs_init() != 0) { + printf("error in File System init\n"); + goto fail; + } + + free(start_block_address); + free(journal_buffer); + + return 0; +fail: + free(start_block_address); + free(journal_buffer); + + return -1; +} + +int ext4fs_init(void) +{ + short status; + int i; + unsigned int real_free_blocks = 0; + struct ext_filesystem *fs = get_fs(); + + /* populate fs */ + fs->blksz = EXT2_BLOCK_SIZE(ext4fs_root); + fs->inodesz = INODE_SIZE_FILESYSTEM(ext4fs_root); + fs->sect_perblk = fs->blksz / SECTOR_SIZE; + + /* get the superblock */ + fs->sb = zalloc(SUPERBLOCK_SIZE); + if (!fs->sb) + return -ENOMEM; + if (!ext4fs_devread(SUPERBLOCK_SECTOR, 0, SUPERBLOCK_SIZE, + (char *)fs->sb)) + goto fail; + + /* init journal */ + if (ext4fs_init_journal()) + goto fail; + + /* get total no of blockgroups */ + fs->no_blkgrp = (uint32_t)ext4fs_div_roundup( + (ext4fs_root->sblock.total_blocks - + ext4fs_root->sblock.first_data_block), + ext4fs_root->sblock.blocks_per_group); + + /* get the block group descriptor table */ + fs->gdtable_blkno = ((EXT2_MIN_BLOCK_SIZE == fs->blksz) + 1); + if (ext4fs_get_bgdtable() == -1) { + printf("Error in getting the block group descriptor table\n"); + goto fail; + } + fs->gd = (struct ext2_block_group *)fs->gdtable; + + /* load all the available bitmap block of the partition */ + fs->blk_bmaps = zalloc(fs->no_blkgrp * sizeof(char *)); + if (!fs->blk_bmaps) + goto fail; + for (i = 0; i < fs->no_blkgrp; i++) { + fs->blk_bmaps[i] = zalloc(fs->blksz); + if (!fs->blk_bmaps[i]) + goto fail; + } + + for (i = 0; i < fs->no_blkgrp; i++) { + status = + ext4fs_devread(fs->gd[i].block_id * fs->sect_perblk, 0, + fs->blksz, (char *)fs->blk_bmaps[i]); + if (status == 0) + goto fail; + } + + /* load all the available inode bitmap of the partition */ + fs->inode_bmaps = zalloc(fs->no_blkgrp * sizeof(unsigned char *)); + if (!fs->inode_bmaps) + goto fail; + for (i = 0; i < fs->no_blkgrp; i++) { + fs->inode_bmaps[i] = zalloc(fs->blksz); + if (!fs->inode_bmaps[i]) + goto fail; + } + + for (i = 0; i < fs->no_blkgrp; i++) { + status = ext4fs_devread(fs->gd[i].inode_id * fs->sect_perblk, + 0, fs->blksz, + (char *)fs->inode_bmaps[i]); + if (status == 0) + goto fail; + } + + /* + * check filesystem consistency with free blocks of file system + * some time we observed that superblock freeblocks does not match + * with the blockgroups freeblocks when improper + * reboot of a linux kernel + */ + for (i = 0; i < fs->no_blkgrp; i++) + real_free_blocks = real_free_blocks + fs->gd[i].free_blocks; + if (real_free_blocks != fs->sb->free_blocks) + fs->sb->free_blocks = real_free_blocks; + + return 0; +fail: + ext4fs_deinit(); + + return -1; +} + +void ext4fs_deinit(void) +{ + int i; + struct ext2_inode inode_journal; + struct journal_superblock_t *jsb; + long int blknr; + struct ext_filesystem *fs = get_fs(); + + /* free journal */ + char *temp_buff = zalloc(fs->blksz); + if (temp_buff) { + ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, + &inode_journal); + blknr = read_allocated_block(&inode_journal, + EXT2_JOURNAL_SUPERBLOCK); + ext4fs_devread(blknr * fs->sect_perblk, 0, fs->blksz, + temp_buff); + jsb = (struct journal_superblock_t *)temp_buff; + jsb->s_start = cpu_to_be32(0); + put_ext4((uint64_t) (blknr * fs->blksz), + (struct journal_superblock_t *)temp_buff, fs->blksz); + free(temp_buff); + } + ext4fs_free_journal(); + + /* get the superblock */ + ext4fs_devread(SUPERBLOCK_SECTOR, 0, SUPERBLOCK_SIZE, (char *)fs->sb); + fs->sb->feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER; + put_ext4((uint64_t)(SUPERBLOCK_SIZE), + (struct ext2_sblock *)fs->sb, (uint32_t)SUPERBLOCK_SIZE); + free(fs->sb); + fs->sb = NULL; + + if (fs->blk_bmaps) { + for (i = 0; i < fs->no_blkgrp; i++) { + free(fs->blk_bmaps[i]); + fs->blk_bmaps[i] = NULL; + } + free(fs->blk_bmaps); + fs->blk_bmaps = NULL; + } + + if (fs->inode_bmaps) { + for (i = 0; i < fs->no_blkgrp; i++) { + free(fs->inode_bmaps[i]); + fs->inode_bmaps[i] = NULL; + } + free(fs->inode_bmaps); + fs->inode_bmaps = NULL; + } + + + free(fs->gdtable); + fs->gdtable = NULL; + fs->gd = NULL; + /* + * reinitiliazed the global inode and + * block bitmap first execution check variables + */ + fs->first_pass_ibmap = 0; + fs->first_pass_bbmap = 0; + fs->curr_inode_no = 0; + fs->curr_blkno = 0; +} + +static int ext4fs_write_file(struct ext2_inode *file_inode, + int pos, unsigned int len, char *buf) +{ + int i; + int blockcnt; + int log2blocksize = LOG2_EXT2_BLOCK_SIZE(ext4fs_root); + unsigned int filesize = __le32_to_cpu(file_inode->size); + struct ext_filesystem *fs = get_fs(); + int previous_block_number = -1; + int delayed_start = 0; + int delayed_extent = 0; + int delayed_skipfirst = 0; + int delayed_next = 0; + char *delayed_buf = NULL; + + /* Adjust len so it we can't read past the end of the file. */ + if (len > filesize) + len = filesize; + + blockcnt = ((len + pos) + fs->blksz - 1) / fs->blksz; + + for (i = pos / fs->blksz; i < blockcnt; i++) { + long int blknr; + int blockend = fs->blksz; + int skipfirst = 0; + blknr = read_allocated_block(file_inode, i); + if (blknr < 0) + return -1; + + blknr = blknr << log2blocksize; + + if (blknr) { + if (previous_block_number != -1) { + if (delayed_next == blknr) { + delayed_extent += blockend; + delayed_next += blockend >> SECTOR_BITS; + } else { /* spill */ + put_ext4((uint64_t) (delayed_start * + SECTOR_SIZE), + delayed_buf, + (uint32_t) delayed_extent); + previous_block_number = blknr; + delayed_start = blknr; + delayed_extent = blockend; + delayed_skipfirst = skipfirst; + delayed_buf = buf; + delayed_next = blknr + + (blockend >> SECTOR_BITS); + } + } else { + previous_block_number = blknr; + delayed_start = blknr; + delayed_extent = blockend; + delayed_skipfirst = skipfirst; + delayed_buf = buf; + delayed_next = blknr + + (blockend >> SECTOR_BITS); + } + } else { + if (previous_block_number != -1) { + /* spill */ + put_ext4((uint64_t) (delayed_start * + SECTOR_SIZE), delayed_buf, + (uint32_t) delayed_extent); + previous_block_number = -1; + } + memset(buf, 0, fs->blksz - skipfirst); + } + buf += fs->blksz - skipfirst; + } + if (previous_block_number != -1) { + /* spill */ + put_ext4((uint64_t) (delayed_start * SECTOR_SIZE), + delayed_buf, (uint32_t) delayed_extent); + previous_block_number = -1; + } + + return len; +} + +int ext4fs_write(const char *fname, unsigned char *buffer, + unsigned long sizebytes) +{ + int ret = 0; + struct ext2_inode *file_inode = NULL; + unsigned char *inode_buffer = NULL; + int parent_inodeno; + int inodeno; + time_t timestamp = 0; + + uint64_t bytes_reqd_for_file; + unsigned int blks_reqd_for_file; + unsigned int blocks_remaining; + int existing_file_inodeno; + char filename[256]; + + char *temp_ptr = NULL; + long int itable_blkno; + long int parent_itable_blkno; + long int blkoff; + struct ext2_sblock *sblock = &(ext4fs_root->sblock); + unsigned int inodes_per_block; + unsigned int ibmap_idx; + struct ext_filesystem *fs = get_fs(); + g_parent_inode = zalloc(sizeof(struct ext2_inode)); + if (!g_parent_inode) + goto fail; + + if (ext4fs_init() != 0) { + printf("error in File System init\n"); + return -1; + } + inodes_per_block = fs->blksz / fs->inodesz; + parent_inodeno = ext4fs_get_parent_inode_num(fname, filename, F_FILE); + if (parent_inodeno == -1) + goto fail; + if (ext4fs_iget(parent_inodeno, g_parent_inode)) + goto fail; + /* check if the filename is already present in root */ + existing_file_inodeno = ext4fs_filename_check(filename); + if (existing_file_inodeno != -1) { + ret = ext4fs_delete_file(existing_file_inodeno); + fs->first_pass_bbmap = 0; + fs->curr_blkno = 0; + + fs->first_pass_ibmap = 0; + fs->curr_inode_no = 0; + if (ret) + goto fail; + } + /* calucalate how many blocks required */ + bytes_reqd_for_file = sizebytes; + blks_reqd_for_file = bytes_reqd_for_file / fs->blksz; + if (bytes_reqd_for_file % fs->blksz != 0) { + blks_reqd_for_file++; + debug("total bytes for a file %u\n", blks_reqd_for_file); + } + blocks_remaining = blks_reqd_for_file; + /* test for available space in partition */ + if (fs->sb->free_blocks < blks_reqd_for_file) { + printf("Not enough space on partition !!!\n"); + goto fail; + } + + ext4fs_update_parent_dentry(filename, &inodeno, FILETYPE_REG); + /* prepare file inode */ + inode_buffer = zalloc(fs->inodesz); + if (!inode_buffer) + goto fail; + file_inode = (struct ext2_inode *)inode_buffer; + file_inode->mode = S_IFREG | S_IRWXU | + S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH; + /* ToDo: Update correct time */ + file_inode->mtime = timestamp; + file_inode->atime = timestamp; + file_inode->ctime = timestamp; + file_inode->nlinks = 1; + file_inode->size = sizebytes; + + /* Allocate data blocks */ + ext4fs_allocate_blocks(file_inode, blocks_remaining, + &blks_reqd_for_file); + file_inode->blockcnt = (blks_reqd_for_file * fs->blksz) / SECTOR_SIZE; + + temp_ptr = zalloc(fs->blksz); + if (!temp_ptr) + goto fail; + ibmap_idx = inodeno / ext4fs_root->sblock.inodes_per_group; + inodeno--; + itable_blkno = __le32_to_cpu(fs->gd[ibmap_idx].inode_table_id) + + (inodeno % __le32_to_cpu(sblock->inodes_per_group)) / + inodes_per_block; + blkoff = (inodeno % inodes_per_block) * fs->inodesz; + ext4fs_devread(itable_blkno * fs->sect_perblk, 0, fs->blksz, temp_ptr); + if (ext4fs_log_journal(temp_ptr, itable_blkno)) + goto fail; + + memcpy(temp_ptr + blkoff, inode_buffer, fs->inodesz); + if (ext4fs_put_metadata(temp_ptr, itable_blkno)) + goto fail; + /* copy the file content into data blocks */ + if (ext4fs_write_file(file_inode, 0, sizebytes, (char *)buffer) == -1) { + printf("Error in copying content\n"); + goto fail; + } + ibmap_idx = parent_inodeno / ext4fs_root->sblock.inodes_per_group; + parent_inodeno--; + parent_itable_blkno = __le32_to_cpu(fs->gd[ibmap_idx].inode_table_id) + + (parent_inodeno % + __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block; + blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz; + if (parent_itable_blkno != itable_blkno) { + memset(temp_ptr, '\0', fs->blksz); + ext4fs_devread(parent_itable_blkno * fs->sect_perblk, + 0, fs->blksz, temp_ptr); + if (ext4fs_log_journal(temp_ptr, parent_itable_blkno)) + goto fail; + + memcpy(temp_ptr + blkoff, g_parent_inode, + sizeof(struct ext2_inode)); + if (ext4fs_put_metadata(temp_ptr, parent_itable_blkno)) + goto fail; + free(temp_ptr); + } else { + /* + * If parent and child fall in same inode table block + * both should be kept in 1 buffer + */ + memcpy(temp_ptr + blkoff, g_parent_inode, + sizeof(struct ext2_inode)); + gd_index--; + if (ext4fs_put_metadata(temp_ptr, itable_blkno)) + goto fail; + free(temp_ptr); + } + ext4fs_update(); + ext4fs_deinit(); + + fs->first_pass_bbmap = 0; + fs->curr_blkno = 0; + fs->first_pass_ibmap = 0; + fs->curr_inode_no = 0; + free(inode_buffer); + free(g_parent_inode); + g_parent_inode = NULL; + + return 0; +fail: + ext4fs_deinit(); + free(inode_buffer); + free(g_parent_inode); + g_parent_inode = NULL; + + return -1; +} +#endif diff --git a/include/ext4fs.h b/include/ext4fs.h index 58a6a1d..ab2983c 100644 --- a/include/ext4fs.h +++ b/include/ext4fs.h @@ -117,6 +117,18 @@ extern block_dev_desc_t *ext4_dev_desc; extern struct ext2_data *ext4fs_root; extern struct ext2fs_node *ext4fs_file; +#if defined(CONFIG_CMD_EXT4_WRITE) +extern struct ext2_inode *g_parent_inode; +extern int gd_index; +extern int gindex; + +int ext4fs_init(void); +void ext4fs_deinit(void); +int ext4fs_filename_check(char *filename); +int ext4fs_write(const char *fname, unsigned char *buffer, + unsigned long sizebytes); +#endif + struct ext_filesystem *get_fs(void); int init_fs(block_dev_desc_t *dev_desc); void deinit_fs(block_dev_desc_t *dev_desc); diff --git a/include/ext_common.h b/include/ext_common.h index c90d95b..9b97522 100644 --- a/include/ext_common.h +++ b/include/ext_common.h @@ -191,6 +191,8 @@ int do_ext2load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); +int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]); int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); -- cgit v1.1 From 36d0a42b682e4d8493e8c080425bc9fb6f188cd2 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Aug 2012 16:53:35 +0200 Subject: dm: mips: Fix lb60 WDT control Write the TSCR register via 32bit write instead of 16bit one. The register is 32bit wide and bit 16 is being set, triggering gcc overflow error and making the code broken. Signed-off-by: Marek Vasut Cc: Daniel Cc: Shinya Kuribayashi Cc: Xiangfu Liu --- arch/mips/cpu/xburst/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/cpu/xburst/cpu.c b/arch/mips/cpu/xburst/cpu.c index e976341..ddcbfaa 100644 --- a/arch/mips/cpu/xburst/cpu.c +++ b/arch/mips/cpu/xburst/cpu.c @@ -62,7 +62,7 @@ void __attribute__((weak)) _machine_restart(void) writew(100, &wdt->tdr); /* wdt_set_data(100) */ writew(0, &wdt->tcnt); /* wdt_set_count(0); */ - writew(TCU_TSSR_WDTSC, &tcu->tscr); /* tcu_start_wdt_clock */ + writel(TCU_TSSR_WDTSC, &tcu->tscr); /* tcu_start_wdt_clock */ writeb(readb(&wdt->tcer) | WDT_TCER_TCEN, &wdt->tcer); /* wdt start */ while (1) -- cgit v1.1 From 8b82cefbfc88d12cdffa0970f03047b74d08487e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Aug 2012 16:53:35 +0200 Subject: dm: mips: Fix lb60 timer code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The timer code contains more halfword writes which trigger gcc errors. The registers are again 32bit, yet written by 16bit writes, fix this: timer.c: In function ‘reset_timer_masked’: timer.c:37:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] timer.c: In function ‘get_timer_masked’: timer.c:43:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] timer.c: In function ‘timer_init’: timer.c:86:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] timer.c:88:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] timer.c:89:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] timer.c:90:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] Signed-off-by: Marek Vasut Cc: Daniel Cc: Shinya Kuribayashi Cc: Xiangfu Liu --- arch/mips/cpu/xburst/timer.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/mips/cpu/xburst/timer.c b/arch/mips/cpu/xburst/timer.c index de6f5da..b6b3855 100644 --- a/arch/mips/cpu/xburst/timer.c +++ b/arch/mips/cpu/xburst/timer.c @@ -34,13 +34,13 @@ static struct jz4740_tcu *tcu = (struct jz4740_tcu *)JZ4740_TCU_BASE; void reset_timer_masked(void) { /* reset time */ - gd->lastinc = readw(&tcu->tcnt0); + gd->lastinc = readl(&tcu->tcnt0); gd->tbl = 0; } ulong get_timer_masked(void) { - ulong now = readw(&tcu->tcnt0); + ulong now = readl(&tcu->tcnt0); if (gd->lastinc <= now) gd->tbl += now - gd->lastinc; /* normal mode */ @@ -83,11 +83,11 @@ void udelay_masked(unsigned long usec) int timer_init(void) { - writew(TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN, &tcu->tcsr0); + writel(TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN, &tcu->tcsr0); - writew(0, &tcu->tcnt0); - writew(0, &tcu->tdhr0); - writew(TIMER_FDATA, &tcu->tdfr0); + writel(0, &tcu->tcnt0); + writel(0, &tcu->tdhr0); + writel(TIMER_FDATA, &tcu->tdfr0); /* mask irqs */ writel((1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)), &tcu->tmsr); -- cgit v1.1 From 9a16f310c0182e0744341b85c43ec8c4f50ae4dc Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Aug 2012 16:53:35 +0200 Subject: dm: mips: Fix warnings in lb60 board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lb60 board accesses the clkgr register, which is 32bit via 16bit IO ops. This causes malfunction. Fix this. qi_lb60.c: In function ‘cpm_init’: qi_lb60.c:72:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] qi_lb60.c:84:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] Signed-off-by: Marek Vasut Cc: Daniel Cc: Shinya Kuribayashi Cc: Xiangfu Liu --- board/qi/qi_lb60/qi_lb60.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/qi/qi_lb60/qi_lb60.c b/board/qi/qi_lb60/qi_lb60.c index 3583d01..d975209 100644 --- a/board/qi/qi_lb60/qi_lb60.c +++ b/board/qi/qi_lb60/qi_lb60.c @@ -69,7 +69,7 @@ static void gpio_init(void) static void cpm_init(void) { struct jz4740_cpm *cpm = (struct jz4740_cpm *)JZ4740_CPM_BASE; - uint32_t reg = readw(&cpm->clkgr); + uint32_t reg = readl(&cpm->clkgr); reg |= CPM_CLKGR_IPU | CPM_CLKGR_CIM | @@ -81,7 +81,7 @@ static void cpm_init(void) CPM_CLKGR_UDC | CPM_CLKGR_AIC1; - writew(reg, &cpm->clkgr); + writel(reg, &cpm->clkgr); } int board_early_init_f(void) -- cgit v1.1 From d2aa5dca74fcf8cbe7fa1f27606a5663bb52d3e6 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 12 Aug 2012 16:53:35 +0200 Subject: dm: mips: Import libgcc components from Linux Import ashldr3, ashrdi3 and lshrdi3 to squash possible libgcc fp mismatch, resulting in the following warning: mips-linux-gnu-ld: Warning: /usr/lib/gcc/mips-linux-gnu/4.7/libgcc.a(_lshrdi3.o) uses hard float, u-boot uses soft float mips-linux-gnu-ld: Warning: /usr/lib/gcc/mips-linux-gnu/4.7/libgcc.a(_ashldi3.o) uses hard float, u-boot uses soft float Imported from Linux (linux-next 20120723) as of commit: commit 72fbfb260197a52c2bc2583f3e8f15d261d0f924 Author: Ralf Baechle Date: Wed Jun 7 13:25:37 2006 +0100 [MIPS] Fix optimization for size build. It took a while longer than on other architectures but gcc has finally started to strike us as well ... This also fixes the damage by 6edfba1b33c701108717f4e036320fc39abe1912. Signed-off-by: Ralf Baechle Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck [: removed USE_PRIVATE_LIBGCC = yes] Signed-off-by: Daniel Schwierzeck --- arch/mips/lib/Makefile | 20 ++++++++++++++++++++ arch/mips/lib/ashldi3.c | 25 +++++++++++++++++++++++++ arch/mips/lib/ashrdi3.c | 27 +++++++++++++++++++++++++++ arch/mips/lib/libgcc.h | 25 +++++++++++++++++++++++++ arch/mips/lib/lshrdi3.c | 25 +++++++++++++++++++++++++ 5 files changed, 122 insertions(+) create mode 100644 arch/mips/lib/ashldi3.c create mode 100644 arch/mips/lib/ashrdi3.c create mode 100644 arch/mips/lib/libgcc.h create mode 100644 arch/mips/lib/lshrdi3.c diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 9244f31..967e98a 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -25,6 +25,13 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(ARCH).o +## Build a couple of necessary functions into a private libgcc +LIBGCC = $(obj)libgcc.o +GLSOBJS += ashldi3.o +GLSOBJS += ashrdi3.o +GLSOBJS += lshrdi3.o +LGOBJS := $(addprefix $(obj),$(GLSOBJS)) + SOBJS-y += COBJS-y += board.o @@ -37,9 +44,22 @@ endif SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) +# Always build libmips.o +TARGETS := $(LIB) + +# Build private libgcc only when asked for +ifdef USE_PRIVATE_LIBGCC +TARGETS += $(LIBGCC) +endif + +all: $(TARGETS) + $(LIB): $(obj).depend $(OBJS) $(call cmd_link_o_target, $(OBJS)) +$(LIBGCC): $(obj).depend $(LGOBJS) + $(call cmd_link_o_target, $(LGOBJS)) + ######################################################################### # defines $(obj).depend target diff --git a/arch/mips/lib/ashldi3.c b/arch/mips/lib/ashldi3.c new file mode 100644 index 0000000..9b50d86 --- /dev/null +++ b/arch/mips/lib/ashldi3.c @@ -0,0 +1,25 @@ +#include "libgcc.h" + +long long __ashldi3(long long u, word_type b) +{ + DWunion uu, w; + word_type bm; + + if (b == 0) + return u; + + uu.ll = u; + bm = 32 - b; + + if (bm <= 0) { + w.s.low = 0; + w.s.high = (unsigned int) uu.s.low << -bm; + } else { + const unsigned int carries = (unsigned int) uu.s.low >> bm; + + w.s.low = (unsigned int) uu.s.low << b; + w.s.high = ((unsigned int) uu.s.high << b) | carries; + } + + return w.ll; +} diff --git a/arch/mips/lib/ashrdi3.c b/arch/mips/lib/ashrdi3.c new file mode 100644 index 0000000..f30359b --- /dev/null +++ b/arch/mips/lib/ashrdi3.c @@ -0,0 +1,27 @@ +#include "libgcc.h" + +long long __ashrdi3(long long u, word_type b) +{ + DWunion uu, w; + word_type bm; + + if (b == 0) + return u; + + uu.ll = u; + bm = 32 - b; + + if (bm <= 0) { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = + uu.s.high >> 31; + w.s.low = uu.s.high >> -bm; + } else { + const unsigned int carries = (unsigned int) uu.s.high << bm; + + w.s.high = uu.s.high >> b; + w.s.low = ((unsigned int) uu.s.low >> b) | carries; + } + + return w.ll; +} diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h new file mode 100644 index 0000000..05909d5 --- /dev/null +++ b/arch/mips/lib/libgcc.h @@ -0,0 +1,25 @@ +#ifndef __ASM_LIBGCC_H +#define __ASM_LIBGCC_H + +#include + +typedef int word_type __attribute__ ((mode (__word__))); + +#ifdef __BIG_ENDIAN +struct DWstruct { + int high, low; +}; +#elif defined(__LITTLE_ENDIAN) +struct DWstruct { + int low, high; +}; +#else +#error I feel sick. +#endif + +typedef union { + struct DWstruct s; + long long ll; +} DWunion; + +#endif /* __ASM_LIBGCC_H */ diff --git a/arch/mips/lib/lshrdi3.c b/arch/mips/lib/lshrdi3.c new file mode 100644 index 0000000..bb340ac --- /dev/null +++ b/arch/mips/lib/lshrdi3.c @@ -0,0 +1,25 @@ +#include "libgcc.h" + +long long __lshrdi3(long long u, word_type b) +{ + DWunion uu, w; + word_type bm; + + if (b == 0) + return u; + + uu.ll = u; + bm = 32 - b; + + if (bm <= 0) { + w.s.high = 0; + w.s.low = (unsigned int) uu.s.high >> -bm; + } else { + const unsigned int carries = (unsigned int) uu.s.high << bm; + + w.s.high = (unsigned int) uu.s.high >> b; + w.s.low = ((unsigned int) uu.s.low >> b) | carries; + } + + return w.ll; +} -- cgit v1.1 From 89f4289958c12e6b64a6073f820255c1f719c5cc Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Mon, 23 Jul 2012 10:58:02 +0000 Subject: mpc85xx: Initial SP alignment is wrong. PowerPC mandates SP to be 16 bytes aligned. Furthermore, a stack frame is added, pointing to the reset vector which may in the way when gdb is walking the stack because the reset vector may not accessible depending on emulator settings. Also use a temp register so gdb doesn't pick up intermediate values. Signed-off-by: Joakim Tjernlund Acked-by: Kumar Gala Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/start.S | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index 6aabc30..b1998b2 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -855,18 +855,12 @@ version_string: .globl _start_cont _start_cont: /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/ - lis r1,CONFIG_SYS_INIT_RAM_ADDR@h - ori r1,r1,CONFIG_SYS_INIT_SP_OFFSET@l - + lis r3,(CONFIG_SYS_INIT_RAM_ADDR)@h + ori r3,r3,((CONFIG_SYS_INIT_SP_OFFSET-16)&~0xf)@l /* Align to 16 */ li r0,0 - stwu r0,-4(r1) - stwu r0,-4(r1) /* Terminate call chain */ - - stwu r1,-8(r1) /* Save back chain and move SP */ - lis r0,RESET_VECTOR@h /* Address of reset vector */ - ori r0,r0,RESET_VECTOR@l - stwu r1,-8(r1) /* Save back chain and move SP */ - stw r0,+12(r1) /* Save return addr (underflow vect) */ + stw r0,0(r3) /* Terminate Back Chain */ + stw r0,+4(r3) /* NULL return address. */ + mr r1,r3 /* Transfer to SP(r1) */ GET_GOT bl cpu_init_early_f -- cgit v1.1 From 7de8a7169e0e87c960d06c60570bc062416e681f Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Mon, 23 Jul 2012 10:58:03 +0000 Subject: powerpc: Stack Pointer not properly aligned The code first aligns the SP to 16 then subtract 8, making it 8 bytes aligned. Furthermore the initial stack frame not quite correct either. Signed-off-by: Joakim Tjernlund Signed-off-by: Andy Fleming --- arch/powerpc/lib/board.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index fea310e..435ef10 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -521,9 +521,8 @@ void board_init_f(ulong bootflag) addr_sp -= 16; addr_sp &= ~0xF; s = (ulong *) addr_sp; - *s-- = 0; - *s-- = 0; - addr_sp = (ulong) s; + *s = 0; /* Terminate back chain */ + *++s = 0; /* NULL return address */ debug("Stack Pointer at: %08lx\n", addr_sp); /* -- cgit v1.1 From 7b8f6685fb840fbaff0baf7d2297b4a2c7ddbf65 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Wed, 8 Aug 2012 15:03:33 +0000 Subject: nand/fsl_elbc: shrink SPL a bit by converting out_be32() to __raw_writel() This is needed to make room for a bugfix on p1_p2_rdb_pc. A sync is used before the final write to LSOR that initiates the transaction, to ensure all the other set up has been completed. Signed-off-by: Scott Wood Signed-off-by: Andy Fleming --- nand_spl/nand_boot_fsl_elbc.c | 47 +++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/nand_spl/nand_boot_fsl_elbc.c b/nand_spl/nand_boot_fsl_elbc.c index 502605b..e9d6497 100644 --- a/nand_spl/nand_boot_fsl_elbc.c +++ b/nand_spl/nand_boot_fsl_elbc.c @@ -66,39 +66,42 @@ static void nand_load(unsigned int offs, int uboot_size, uchar *dst) if (large) { fmr |= FMR_ECCM; - out_be32(®s->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) | - (NAND_CMD_READSTART << FCR_CMD1_SHIFT)); - out_be32(®s->fir, - (FIR_OP_CW0 << FIR_OP0_SHIFT) | - (FIR_OP_CA << FIR_OP1_SHIFT) | - (FIR_OP_PA << FIR_OP2_SHIFT) | - (FIR_OP_CW1 << FIR_OP3_SHIFT) | - (FIR_OP_RBW << FIR_OP4_SHIFT)); + __raw_writel((NAND_CMD_READ0 << FCR_CMD0_SHIFT) | + (NAND_CMD_READSTART << FCR_CMD1_SHIFT), + ®s->fcr); + __raw_writel( + (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CA << FIR_OP1_SHIFT) | + (FIR_OP_PA << FIR_OP2_SHIFT) | + (FIR_OP_CW1 << FIR_OP3_SHIFT) | + (FIR_OP_RBW << FIR_OP4_SHIFT), + ®s->fir); } else { - out_be32(®s->fcr, NAND_CMD_READ0 << FCR_CMD0_SHIFT); - out_be32(®s->fir, - (FIR_OP_CW0 << FIR_OP0_SHIFT) | - (FIR_OP_CA << FIR_OP1_SHIFT) | - (FIR_OP_PA << FIR_OP2_SHIFT) | - (FIR_OP_RBW << FIR_OP3_SHIFT)); + __raw_writel(NAND_CMD_READ0 << FCR_CMD0_SHIFT, ®s->fcr); + __raw_writel( + (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CA << FIR_OP1_SHIFT) | + (FIR_OP_PA << FIR_OP2_SHIFT) | + (FIR_OP_RBW << FIR_OP3_SHIFT), + ®s->fir); } - out_be32(®s->fbcr, 0); - clrsetbits_be32(®s->bank[0].br, BR_DECC, BR_DECC_CHK_GEN); + __raw_writel(0, ®s->fbcr); while (pos < uboot_size) { int i = 0; - out_be32(®s->fbar, offs >> block_shift); + __raw_writel(offs >> block_shift, ®s->fbar); do { int j; unsigned int page_offs = (offs & (block_size - 1)) << 1; - out_be32(®s->ltesr, ~0); - out_be32(®s->lteatr, 0); - out_be32(®s->fpar, page_offs); - out_be32(®s->fmr, fmr); - out_be32(®s->lsor, 0); + __raw_writel(~0, ®s->ltesr); + __raw_writel(0, ®s->lteatr); + __raw_writel(page_offs, ®s->fpar); + __raw_writel(fmr, ®s->fmr); + sync(); + __raw_writel(0, ®s->lsor); nand_wait(); page_offs %= WINDOW_SIZE; -- cgit v1.1 From 57125f222e410c35ac745a912d5f4b52b654932a Mon Sep 17 00:00:00 2001 From: York Sun Date: Wed, 8 Aug 2012 18:04:53 +0000 Subject: powerpc/mpc85xx: Make NMG_CPU_A011 workaround conditional This erratum applies to the following SoCs: P4080 rev 1.0, 2.0, fixed in rev 3.0 P2041 rev 1.0, 1.1, fixed in rev 2.0 P3041 rev 1.0, 1.1, fixed in rev 2.0. Workaround for erratum NMG_CPU_A011 is enabled by default. This workaround may degrade performance. P4080 erratum CPU22 shares the same workaround. So it is always enabled for P4080. For other SoCs, it can be disabled by hwconfig with syntax: fsl_cpu_a011:disable Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/cmd_errata.c | 6 ++++- arch/powerpc/cpu/mpc85xx/cpu_init.c | 37 +++++++++++++++++++++++++++++-- arch/powerpc/cpu/mpc85xx/release.S | 15 +++++++++++++ arch/powerpc/include/asm/config_mpc85xx.h | 1 + 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 4e1a54a..858b3f8 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -27,6 +27,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 + extern int enable_cpu_a011_workaround; +#endif __maybe_unused u32 svr = get_svr(); #if defined(CONFIG_FSL_SATA_V2) && defined(CONFIG_FSL_SATA_ERRATUM_A001) @@ -56,8 +59,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) /* * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0 * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1 + * The SVR has been checked by cpu_init_r(). */ - if (SVR_SOC_VER(svr) != SVR_P4080 || SVR_MAJ(svr) < 3) + if (enable_cpu_a011_workaround) puts("Work-around for Erratum CPU-A011 enabled\n"); #endif #if defined(CONFIG_SYS_FSL_ERRATUM_CPU_A003999) diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index fc6c287..74863b4 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "mp.h" #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND @@ -47,6 +48,8 @@ #include "../../../../drivers/block/fsl_sata.h" +#define HWCONFIG_BUFFER_SIZE 128 + DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_QE @@ -311,11 +314,41 @@ int cpu_init_r(void) #if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \ defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011) /* + * CPU22 and NMG_CPU_A011 share the same workaround. * CPU22 applies to P4080 rev 1.0, 2.0, fixed in 3.0 * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0 - * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1 + * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1, both + * fixed in 2.0. NMG_CPU_A011 is activated by default and can + * be disabled by hwconfig with syntax: + * + * fsl_cpu_a011:disable */ - if (SVR_SOC_VER(svr) != SVR_P4080 || SVR_MAJ(svr) < 3) { + extern int enable_cpu_a011_workaround; +#ifdef CONFIG_SYS_P4080_ERRATUM_CPU22 + enable_cpu_a011_workaround = (SVR_MAJ(svr) < 3); +#else + char buffer[HWCONFIG_BUFFER_SIZE]; + char *buf = NULL; + int n, res; + + n = getenv_f("hwconfig", buffer, sizeof(buffer)); + if (n > 0) + buf = buffer; + + res = hwconfig_arg_cmp_f("fsl_cpu_a011", "disable", buf); + if (res > 0) + enable_cpu_a011_workaround = 0; + else { + if (n >= HWCONFIG_BUFFER_SIZE) { + printf("fsl_cpu_a011 was not found. hwconfig variable " + "may be too long\n"); + } + enable_cpu_a011_workaround = + (SVR_SOC_VER(svr) == SVR_P4080 && SVR_MAJ(svr) < 3) || + (SVR_SOC_VER(svr) != SVR_P4080 && SVR_MAJ(svr) < 2); + } +#endif + if (enable_cpu_a011_workaround) { flush_dcache(); mtspr(L1CSR2, (mfspr(L1CSR2) | L1CSR2_DCWS)); sync(); diff --git a/arch/powerpc/cpu/mpc85xx/release.S b/arch/powerpc/cpu/mpc85xx/release.S index 1860684..1555a9b 100644 --- a/arch/powerpc/cpu/mpc85xx/release.S +++ b/arch/powerpc/cpu/mpc85xx/release.S @@ -163,6 +163,12 @@ __secondary_start_page: cmpw r3,r5 bge 2f 1: +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 + lis r3,toreset(enable_cpu_a011_workaround)@ha + lwz r3,toreset(enable_cpu_a011_workaround)@l(r3) + cmpwi r3,0 + beq 2f +#endif mfspr r3,L1CSR2 oris r3,r3,(L1CSR2_DCWS)@h mtspr L1CSR2,r3 @@ -346,6 +352,15 @@ __bootpg_addr: __spin_table: .space CONFIG_MAX_CPUS*ENTRY_SIZE + /* + * This variable is set by cpu_init_r() after parsing hwconfig + * to enable workaround for erratum NMG_CPU_A011. + */ + .align L1_CACHE_SHIFT + .global enable_cpu_a011_workaround +enable_cpu_a011_workaround: + .long 1 + /* Fill in the empty space. The actual reset vector is * the last word of the page */ __secondary_start_code_end: diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index b6c44bb..7e61f71 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -399,6 +399,7 @@ #define CONFIG_SYS_FSL_USB2_PHY_ENABLE #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 +#define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -- cgit v1.1 From 51928df64ce29ca4c412fe5f3e063cb05e5411c7 Mon Sep 17 00:00:00 2001 From: Liu Gang Date: Thu, 9 Aug 2012 05:09:58 +0000 Subject: powerpc/corenet_ds: Update README.srio-boot-corenet Update some descriptions due to the implementation changes: For master: Get rid of the SRIOBOOT_MASTER build target, and to support for serving as a SRIO boot master via environment variable. For slave: 1. When compile the slave image for boot from SRIO, no longer need to specify which SRIO port it will boot from. 2. All slave's cores should be in hold off. Signed-off-by: Liu Gang Signed-off-by: Andy Fleming --- doc/README.srio-boot-corenet | 70 +++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/doc/README.srio-boot-corenet b/doc/README.srio-boot-corenet index 56b094c..6a13e9c 100644 --- a/doc/README.srio-boot-corenet +++ b/doc/README.srio-boot-corenet @@ -18,7 +18,7 @@ Environment of the SRIO boot: U-Boot images, UCodes will be stored in this flash. d) Slave has its own EEPROM for RCW and PBI. e) Slave's RCW should configure the SerDes for SRIO boot port, set the boot - location to SRIO, and holdoff all the cores if needed. + location to SRIO, and holdoff all the cores. ---------- ----------- ----------- | | | | | | @@ -30,63 +30,55 @@ Environment of the SRIO boot: The example based on P4080DS platform: Two P4080DS platforms can be used to implement the boot from SRIO. Their SRIO - ports 0 will be connected directly and will be used for the boot from SRIO. + ports 1 will be connected directly and will be used for the boot from SRIO. - 1. Slave's RCW example for boot from SRIO port 0 and core 0 not in holdoff. - 00000000: aa55 aa55 010e 0100 0c58 0000 0000 0000 - 00000010: 1818 1818 0000 8888 7440 4000 0000 2000 - 00000020: f400 0000 0100 0000 0000 0000 0000 0000 - 00000030: 0000 0000 0083 0000 0000 0000 0000 0000 - 00000040: 0000 0000 0000 0000 0813 8040 698b 93fe - - 2. Slave's RCW example for boot from SRIO port 0 and all cores in holdoff. + 1. Slave's RCW example for boot from SRIO port 1 and all cores in holdoff. 00000000: aa55 aa55 010e 0100 0c58 0000 0000 0000 00000010: 1818 1818 0000 8888 7440 4000 0000 2000 00000020: f440 0000 0100 0000 0000 0000 0000 0000 00000030: 0000 0000 0083 0000 0000 0000 0000 0000 00000040: 0000 0000 0000 0000 0813 8040 063c 778f - 3. Sequence in Step by Step. - a) Update RCW for slave with boot from SRIO port 0 configuration. + 2. Sequence in Step by Step. + a) Update RCW for slave with boot from SRIO port 1 configuration. b) Program slave's U-Boot image, UCode, and ENV parameters into master's NorFlash. - c) Start up master and it will boot up normally from its NorFlash. + c) Set environment variable "bootmaster" to "SRIO1" and save environment + for master. + setenv bootmaster SRIO1 + saveenv + d) Restart up master and it will boot up normally from its NorFlash. Then, it will finish necessary configurations for slave's boot from - SRIO port 0. - d) Master will set inbound SRIO windows covered slave's U-Boot image stored + SRIO port 1. + e) Master will set inbound SRIO windows covered slave's U-Boot image stored in master's NorFlash. - e) Master will set an inbound SRIO window covered slave's UCode stored in - master's NorFlash. - f) Master will set an inbound SRIO window covered slave's ENV stored in - master's NorFlash. - g) If need to release slave's core, master will set outbound SRIO windows - in order to configure slave's registers for the core's releasing. - h) If all cores of slave in holdoff, slave should be powered on before all - the above master's steps, and wait to be released by master. If not all - cores in holdoff, that means core 0 will start up normally, slave should - be powered on after all the above master's steps. In the startup phase - of the slave from SRIO, it will finish some necessary configurations. + f) Master will set an inbound SRIO window covered slave's UCode and ENV + stored in master's NorFlash. + g) Master will set outbound SRIO windows in order to configure slave's + registers for the core's releasing. + h) Since all cores of slave in holdoff, slave should be powered on before all + the above master's steps, and wait to be released by master. In the + startup phase of the slave from SRIO, it will finish some necessary + configurations. i) Slave will set a specific TLB entry for the boot process. - j) Slave will set a LAW entry with the TargetID SRIO port 0 for the boot. + j) Slave will set a LAW entry with the TargetID SRIO port 1 for the boot. k) Slave will set a specific TLB entry in order to fetch UCode and ENV from master. - l) Slave will set a LAW entry with the TargetID SRIO port 0 for UCode and ENV. + l) Slave will set a LAW entry with the TargetID SRIO port 1 for UCode and ENV. How to use this feature: - To use this feature, you need to focus three points. + To use this feature, you need to focus those points. 1. Slave's RCW with SRIO boot configurations, and all cores in holdoff - configurations if needed. + configurations. Please refer to the examples given above. 2. U-Boot image's compilation. - For master, U-Boot image should be generated specifically by - - make xxxx_SRIOBOOT_MASTER_config. + For master, U-Boot image should be generated normally. For example, master U-Boot image used on P4080DS should be compiled with - make P4080DS_SRIOBOOT_MASTER_config. + make P4080DS_config. For slave, U-Boot image should be generated specifically by @@ -97,7 +89,11 @@ How to use this feature: make P4080DS_SRIOBOOT_SLAVE_config. 3. Necessary modifications based on a specific environment. - For a specific environment, the SRIO port for boot, the addresses of the - slave's U-Boot image, UCode, ENV stored in master's NorFlash, and any other - configurations can be modified in the file: + For a specific environment, the addresses of the slave's U-Boot image, + UCode, ENV stored in master's NorFlash, and any other configurations + can be modified in the file: include/configs/corenet_ds.h. + + 4. Set and save the environment variable "bootmaster" with "SRIO1" or "SRIO2" + for master, and then restart it in order to perform the role as a master + for boot from SRIO. -- cgit v1.1 From ff65f12699b4181b777cbc03b057510bc4605f5e Mon Sep 17 00:00:00 2001 From: Liu Gang Date: Thu, 9 Aug 2012 05:09:59 +0000 Subject: powerpc/corenet_ds: Get rid of the SRIOBOOT_MASTER build target Get rid of the SRIOBOOT_MASTER build target, and to support for serving as a SRIO boot master via environment variable. Set the environment variable "bootmaster" to "SRIO1" or "SRIO2" using the following command: setenv bootmaster SRIO1 saveenv The "bootmaster" will enable the function of the SRIO boot master, and this has the following advantages compared with SRIOBOOT_MASTER build configuration: 1. Reduce a build configuration item in boards.cfg file. No longer need to build a special image for master, just use a normal target image and set the "bootmaster" variable. 2. No longer need to rebuild an image when change the SRIO port for boot from SRIO, just set the corresponding value to "bootmaster" based on the using SRIO port. Signed-off-by: Liu Gang Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/cpu_init.c | 17 +++-- arch/powerpc/cpu/mpc8xxx/srio.c | 137 +++++++++++++----------------------- arch/powerpc/include/asm/fsl_srio.h | 8 +-- boards.cfg | 4 +- include/configs/P2041RDB.h | 59 +++++++++++++++- include/configs/corenet_ds.h | 32 +++------ 6 files changed, 129 insertions(+), 128 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index 74863b4..f293265 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -480,11 +480,18 @@ skip_l2: #ifdef CONFIG_SYS_SRIO srio_init(); -#ifdef CONFIG_SRIOBOOT_MASTER - srio_boot_master(); -#ifdef CONFIG_SRIOBOOT_SLAVE_HOLDOFF - srio_boot_master_release_slave(); -#endif +#ifdef CONFIG_FSL_CORENET + char *s = getenv("bootmaster"); + if (s) { + if (!strcmp(s, "SRIO1")) { + srio_boot_master(1); + srio_boot_master_release_slave(1); + } + if (!strcmp(s, "SRIO2")) { + srio_boot_master(2); + srio_boot_master_release_slave(2); + } + } #endif #endif diff --git a/arch/powerpc/cpu/mpc8xxx/srio.c b/arch/powerpc/cpu/mpc8xxx/srio.c index c7f3949..ae83d6e 100644 --- a/arch/powerpc/cpu/mpc8xxx/srio.c +++ b/arch/powerpc/cpu/mpc8xxx/srio.c @@ -95,126 +95,92 @@ void srio_init(void) } } -#ifdef CONFIG_SRIOBOOT_MASTER -void srio_boot_master(void) +#ifdef CONFIG_FSL_CORENET +void srio_boot_master(int port) { struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR; /* set port accept-all */ - out_be32((void *)&srio->impl.port[CONFIG_SRIOBOOT_MASTER_PORT].ptaacr, + out_be32((void *)&srio->impl.port[port - 1].ptaacr, SRIO_PORT_ACCEPT_ALL); - debug("SRIOBOOT - MASTER: Master port [ %d ] for srio boot.\n", - CONFIG_SRIOBOOT_MASTER_PORT); + debug("SRIOBOOT - MASTER: Master port [ %d ] for srio boot.\n", port); /* configure inbound window for slave's u-boot image */ debug("SRIOBOOT - MASTER: Inbound window for slave's image; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS1, - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS1, + (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1, CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwtar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS1 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwbar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS1 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[0].riwar, + out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwtar, + CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwbar, + CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1 >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwar, SRIO_IB_ATMU_AR | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE)); /* configure inbound window for slave's u-boot image */ debug("SRIOBOOT - MASTER: Inbound window for slave's image; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS2, - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS2, + (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2, CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwtar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS2 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwbar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS2 >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[1].riwar, + out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwtar, + CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwbar, + CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2 >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwar, SRIO_IB_ATMU_AR | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE)); - /* configure inbound window for slave's ucode */ - debug("SRIOBOOT - MASTER: Inbound window for slave's ucode; " + /* configure inbound window for slave's ucode and ENV */ + debug("SRIOBOOT - MASTER: Inbound window for slave's ucode and ENV; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_LAW_PHYS, - (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_SRIO_PHYS, - CONFIG_SRIOBOOT_SLAVE_UCODE_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwtar, - CONFIG_SRIOBOOT_SLAVE_UCODE_LAW_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwbar, - CONFIG_SRIOBOOT_SLAVE_UCODE_SRIO_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[2].riwar, - SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_UCODE_SIZE)); - - /* configure inbound window for slave's ENV */ - debug("SRIOBOOT - MASTER: Inbound window for slave's ENV; " - "Local = 0x%llx, Siro = 0x%llx, Size = 0x%x\n", - CONFIG_SRIOBOOT_SLAVE_ENV_LAW_PHYS, - CONFIG_SRIOBOOT_SLAVE_ENV_SRIO_PHYS, - CONFIG_SRIOBOOT_SLAVE_ENV_SIZE); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwtar, - CONFIG_SRIOBOOT_SLAVE_ENV_LAW_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwbar, - CONFIG_SRIOBOOT_SLAVE_ENV_SRIO_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT].inbw[3].riwar, + (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS, + (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS, + CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE); + out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwtar, + CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwbar, + CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS >> 12); + out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwar, SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_ENV_SIZE)); + | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE)); } -#ifdef CONFIG_SRIOBOOT_SLAVE_HOLDOFF -void srio_boot_master_release_slave(void) +void srio_boot_master_release_slave(int port) { struct ccsr_rio *srio = (void *)CONFIG_SYS_FSL_SRIO_ADDR; u32 escsr; debug("SRIOBOOT - MASTER: " "Check the port status and release slave core ...\n"); - escsr = in_be32((void *)&srio->lp_serial - .port[CONFIG_SRIOBOOT_MASTER_PORT].pescsr); + escsr = in_be32((void *)&srio->lp_serial.port[port - 1].pescsr); if (escsr & 0x2) { if (escsr & 0x10100) { debug("SRIOBOOT - MASTER: Port [ %d ] is error.\n", - CONFIG_SRIOBOOT_MASTER_PORT); + port); } else { debug("SRIOBOOT - MASTER: " - "Port [ %d ] is ready, now release slave's core ...\n", - CONFIG_SRIOBOOT_MASTER_PORT); + "Port [ %d ] is ready, now release slave's core ...\n", + port); /* * configure outbound window * with maintenance attribute to set slave's LCSBA1CSR */ - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowtar, 0); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowtear, 0); - if (CONFIG_SRIOBOOT_MASTER_PORT) - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + if (port - 1) + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowbar, CONFIG_SYS_SRIO2_MEM_PHYS >> 12); else - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowbar, CONFIG_SYS_SRIO1_MEM_PHYS >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[1].rowar, SRIO_OB_ATMU_AR_MAINT | atmu_size_mask(SRIO_MAINT_WIN_SIZE)); @@ -223,27 +189,22 @@ void srio_boot_master_release_slave(void) * configure outbound window * with R/W attribute to set slave's BRR */ - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowtar, SRIO_LCSBA1CSR >> 9); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowtear, 0); - if (CONFIG_SRIOBOOT_MASTER_PORT) - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + if (port - 1) + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowbar, (CONFIG_SYS_SRIO2_MEM_PHYS + SRIO_MAINT_WIN_SIZE) >> 12); else - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowbar, (CONFIG_SYS_SRIO1_MEM_PHYS + SRIO_MAINT_WIN_SIZE) >> 12); - out_be32((void *)&srio->atmu - .port[CONFIG_SRIOBOOT_MASTER_PORT] + out_be32((void *)&srio->atmu.port[port - 1] .outbw[2].rowar, SRIO_OB_ATMU_AR_RW | atmu_size_mask(SRIO_RW_WIN_SIZE)); @@ -252,7 +213,7 @@ void srio_boot_master_release_slave(void) * Set the LCSBA1CSR register in slave * by the maint-outbound window */ - if (CONFIG_SRIOBOOT_MASTER_PORT) { + if (port - 1) { out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT + SRIO_LCSBA1CSR_OFFSET, SRIO_LCSBA1CSR); @@ -289,8 +250,6 @@ void srio_boot_master_release_slave(void) "Release slave successfully! Now the slave should start up!\n"); } } else - debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n", - CONFIG_SRIOBOOT_MASTER_PORT); + debug("SRIOBOOT - MASTER: Port [ %d ] is not ready.\n", port); } #endif -#endif diff --git a/arch/powerpc/include/asm/fsl_srio.h b/arch/powerpc/include/asm/fsl_srio.h index a905a26..dfd8e08 100644 --- a/arch/powerpc/include/asm/fsl_srio.h +++ b/arch/powerpc/include/asm/fsl_srio.h @@ -55,10 +55,8 @@ enum atmu_size { #define atmu_size_bytes(x) (1ULL << ((x & 0x3f) + 1)) extern void srio_init(void); -#ifdef CONFIG_SRIOBOOT_MASTER -extern void srio_boot_master(void); -#ifdef CONFIG_SRIOBOOT_SLAVE_HOLDOFF -extern void srio_boot_master_release_slave(void); -#endif +#ifdef CONFIG_FSL_CORENET +extern void srio_boot_master(int port); +extern void srio_boot_master_release_slave(int port); #endif #endif diff --git a/boards.cfg b/boards.cfg index fdb84ad..a408405 100644 --- a/boards.cfg +++ b/boards.cfg @@ -787,12 +787,12 @@ P2041RDB_NAND powerpc mpc85xx p2041rdb freescale P2041RDB_SDCARD powerpc mpc85xx p2041rdb freescale - P2041RDB:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P2041RDB_SECURE_BOOT powerpc mpc85xx p2041rdb freescale - P2041RDB:SECURE_BOOT P2041RDB_SPIFLASH powerpc mpc85xx p2041rdb freescale - P2041RDB:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 +P2041RDB_SRIOBOOT_SLAVE powerpc mpc85xx p2041rdb freescale - P2041RDB:SRIOBOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 P3041DS powerpc mpc85xx corenet_ds freescale P3041DS_NAND powerpc mpc85xx corenet_ds freescale - P3041DS:RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000 P3041DS_SDCARD powerpc mpc85xx corenet_ds freescale - P3041DS:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P3041DS_SECURE_BOOT powerpc mpc85xx corenet_ds freescale - P3041DS:SECURE_BOOT P3041DS_SPIFLASH powerpc mpc85xx corenet_ds freescale - P3041DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 -P3041DS_SRIOBOOT_MASTER powerpc mpc85xx corenet_ds freescale - P3041DS:SRIOBOOT_MASTER P3041DS_SRIOBOOT_SLAVE powerpc mpc85xx corenet_ds freescale - P3041DS:SRIOBOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 P3060QDS powerpc mpc85xx p3060qds freescale P3060QDS_NAND powerpc mpc85xx p3060qds freescale - P3060QDS:RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000 @@ -801,14 +801,12 @@ P4080DS powerpc mpc85xx corenet_ds freesca P4080DS_SDCARD powerpc mpc85xx corenet_ds freescale - P4080DS:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P4080DS_SECURE_BOOT powerpc mpc85xx corenet_ds freescale - P4080DS:SECURE_BOOT P4080DS_SPIFLASH powerpc mpc85xx corenet_ds freescale - P4080DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 -P4080DS_SRIOBOOT_MASTER powerpc mpc85xx corenet_ds freescale - P4080DS:SRIOBOOT_MASTER P4080DS_SRIOBOOT_SLAVE powerpc mpc85xx corenet_ds freescale - P4080DS:SRIOBOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 P5020DS powerpc mpc85xx corenet_ds freescale P5020DS_NAND powerpc mpc85xx corenet_ds freescale - P5020DS:RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000 P5020DS_SDCARD powerpc mpc85xx corenet_ds freescale - P5020DS:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P5020DS_SECURE_BOOT powerpc mpc85xx corenet_ds freescale - P5020DS:SECURE_BOOT P5020DS_SPIFLASH powerpc mpc85xx corenet_ds freescale - P5020DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 -P5020DS_SRIOBOOT_MASTER powerpc mpc85xx corenet_ds freescale - P5020DS:SRIOBOOT_MASTER P5020DS_SRIOBOOT_SLAVE powerpc mpc85xx corenet_ds freescale - P5020DS:SRIOBOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 BSC9131RDB_SPIFLASH powerpc mpc85xx bsc9131rdb freescale - BSC9131RDB:BSC9131RDB,SPIFLASH stxgp3 powerpc mpc85xx stxgp3 stx diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h index 1c0eb74..46a5e4c 100644 --- a/include/configs/P2041RDB.h +++ b/include/configs/P2041RDB.h @@ -36,6 +36,15 @@ #define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc #endif +#ifdef CONFIG_SRIOBOOT_SLAVE +/* Set 1M boot space */ +#define CONFIG_SYS_SRIOBOOT_SLAVE_ADDR (CONFIG_SYS_TEXT_BASE & 0xfff00000) +#define CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS \ + (0x300000000ull | CONFIG_SYS_SRIOBOOT_SLAVE_ADDR) +#define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc +#define CONFIG_SYS_NO_FLASH +#endif + /* High Level Configuration Options */ #define CONFIG_BOOKE #define CONFIG_E500 /* BOOKE e500 family */ @@ -73,7 +82,7 @@ #define CONFIG_ENV_OVERWRITE #ifdef CONFIG_SYS_NO_FLASH -#ifndef CONFIG_RAMBOOT_PBL +#if !defined(CONFIG_RAMBOOT_PBL) && !defined(CONFIG_SRIOBOOT_SLAVE) #define CONFIG_ENV_IS_NOWHERE #endif #else @@ -104,8 +113,12 @@ #define CONFIG_ENV_IS_IN_NAND #define CONFIG_ENV_SIZE CONFIG_SYS_NAND_BLOCK_SIZE #define CONFIG_ENV_OFFSET (5 * CONFIG_SYS_NAND_BLOCK_SIZE) +#elif defined(CONFIG_SRIOBOOT_SLAVE) +#define CONFIG_ENV_IS_IN_REMOTE +#define CONFIG_ENV_ADDR 0xffe20000 +#define CONFIG_ENV_SIZE 0x2000 #elif defined(CONFIG_ENV_IS_NOWHERE) - #define CONFIG_ENV_SIZE 0x2000 +#define CONFIG_ENV_SIZE 0x2000 #else #define CONFIG_ENV_IS_IN_FLASH #define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE \ @@ -374,6 +387,38 @@ unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_SYS_SRIO2_MEM_SIZE 0x10000000 /* 256M */ /* + * for slave u-boot IMAGE instored in master memory space, + * PHYS must be aligned based on the SIZE + */ +#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS 0xfef080000ull +#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1 0xfff80000ull +#define CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE 0x80000 /* 512K */ +#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2 0x3fff80000ull +/* + * for slave UCODE and ENV instored in master memory space, + * PHYS must be aligned based on the SIZE + */ +#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS 0xfef040000ull +#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS 0x3ffe00000ull +#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE 0x40000 /* 256K */ + +/* slave core release by master*/ +#define CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET 0xe00e4 +#define CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK 0x00000001 /* release core 0 */ + +/* + * SRIOBOOT - SLAVE + */ +#ifdef CONFIG_SRIOBOOT_SLAVE +/* slave port for srioboot */ +#define CONFIG_SRIOBOOT_SLAVE_PORT0 +/* #define CONFIG_SRIOBOOT_SLAVE_PORT1 */ +#define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR 0xFFE00000 +#define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS \ + (0x300000000ull | CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR) +#endif + +/* * eSPI - Enhanced SPI */ #define CONFIG_FSL_ESPI @@ -485,6 +530,16 @@ unsigned long get_board_sys_clk(unsigned long dummy); #elif defined(CONFIG_NAND) #define CONFIG_SYS_QE_FMAN_FW_IN_NAND #define CONFIG_SYS_QE_FMAN_FW_ADDR (6 * CONFIG_SYS_NAND_BLOCK_SIZE) +#elif defined(CONFIG_SRIOBOOT_SLAVE) +/* + * Slave has no ucode locally, it can fetch this from remote. When implementing + * in two corenet boards, slave's ucode could be stored in master's memory + * space, the address can be mapped from slave TLB->slave LAW-> + * slave SRIO outbound window->master inbound window->master LAW-> + * the ucode address in master's NOR flash. + */ +#define CONFIG_SYS_QE_FMAN_FW_IN_REMOTE +#define CONFIG_SYS_QE_FMAN_FW_ADDR 0xFFE00000 #else #define CONFIG_SYS_QE_FMAN_FW_IN_NOR #define CONFIG_SYS_QE_FMAN_FW_ADDR 0xEF000000 diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index f8f7a82..7f3af21 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -389,40 +389,24 @@ #define CONFIG_SYS_SRIO2_MEM_SIZE 0x10000000 /* 256M */ /* - * SRIOBOOT - MASTER - */ -#ifdef CONFIG_SRIOBOOT_MASTER -/* master port for srioboot*/ -#define CONFIG_SRIOBOOT_MASTER_PORT 0 -/* #define CONFIG_SRIOBOOT_MASTER_PORT 1 */ -/* * for slave u-boot IMAGE instored in master memory space, * PHYS must be aligned based on the SIZE */ -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS1 0xfef080000ull -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS1 0xfff80000ull +#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS 0xfef080000ull +#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1 0xfff80000ull #define CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE 0x80000 /* 512K */ -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_LAW_PHYS2 0xfef080000ull -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_SRIO_PHYS2 0x3fff80000ull +#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2 0x3fff80000ull /* - * for slave UCODE instored in master memory space, + * for slave UCODE and ENV instored in master memory space, * PHYS must be aligned based on the SIZE */ -#define CONFIG_SRIOBOOT_SLAVE_UCODE_LAW_PHYS 0xfef020000ull -#define CONFIG_SRIOBOOT_SLAVE_UCODE_SRIO_PHYS 0x3ffe00000ull -#define CONFIG_SRIOBOOT_SLAVE_UCODE_SIZE 0x10000 /* 64K */ -/* - * for slave ENV instored in master memory space, - * PHYS must be aligned based on the SIZE - */ -#define CONFIG_SRIOBOOT_SLAVE_ENV_LAW_PHYS 0xfef060000ull -#define CONFIG_SRIOBOOT_SLAVE_ENV_SRIO_PHYS 0x3ffe20000ull -#define CONFIG_SRIOBOOT_SLAVE_ENV_SIZE 0x20000 /* 128K */ +#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS 0xfef040000ull +#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS 0x3ffe00000ull +#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE 0x40000 /* 256K */ + /* slave core release by master*/ -#define CONFIG_SRIOBOOT_SLAVE_HOLDOFF #define CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET 0xe00e4 #define CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK 0x00000001 /* release core 0 */ -#endif /* * SRIOBOOT - SLAVE -- cgit v1.1 From 81fa73bab05f491dd6f27c9afbc6952f54173b41 Mon Sep 17 00:00:00 2001 From: Liu Gang Date: Thu, 9 Aug 2012 05:10:00 +0000 Subject: powerpc/corenet_ds: Get rid of the CONFIG_SRIOBOOT_SLAVE_PORTx macro When compile the slave image for boot from SRIO, no longer need to specify which SRIO port it will boot from. The code will get this information from RCW and then finishes corresponding configurations. This has the following advantages: 1. No longer need to rebuild an image when change the SRIO port for boot from SRIO, just rewrite the new RCW with selected port, then the code will get the port information by reading new RCW. 2. It will be easier to support other boot location options, for example, boot from PCIE. Signed-off-by: Liu Gang Signed-off-by: Andy Fleming --- arch/powerpc/include/asm/immap_85xx.h | 1 + board/freescale/common/p_corenet/law.c | 13 ------------- drivers/misc/fsl_law.c | 27 +++++++++++++++++++++++++++ include/configs/P2041RDB.h | 3 --- include/configs/corenet_ds.h | 3 --- 5 files changed, 28 insertions(+), 19 deletions(-) diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 53d563e..91228e7 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -1758,6 +1758,7 @@ typedef struct ccsr_gur { #define FSL_CORENET_RCWSR5_DDR_SYNC 0x00000080 #define FSL_CORENET_RCWSR5_DDR_SYNC_SHIFT 7 #define FSL_CORENET_RCWSR5_SRDS_EN 0x00002000 +#define FSL_CORENET_RCWSR6_BOOT_LOC 0x0f800000 #define FSL_CORENET_RCWSRn_SRDS_LPD_B2 0x3c000000 /* bits 162..165 */ #define FSL_CORENET_RCWSRn_SRDS_LPD_B3 0x003c0000 /* bits 170..173 */ #define FSL_CORENET_RCWSR7_MCK_TO_PLAT_RAT 0x00400000 diff --git a/board/freescale/common/p_corenet/law.c b/board/freescale/common/p_corenet/law.c index c4566dd..09ef561 100644 --- a/board/freescale/common/p_corenet/law.c +++ b/board/freescale/common/p_corenet/law.c @@ -48,19 +48,6 @@ struct law_entry law_table[] = { #ifdef CONFIG_SYS_NAND_BASE_PHYS SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC), #endif -#ifdef CONFIG_SRIOBOOT_SLAVE -#if defined(CONFIG_SRIOBOOT_SLAVE_PORT0) - SET_LAW(CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS, - LAW_SIZE_1M, LAW_TRGT_IF_RIO_1), - SET_LAW(CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS, - LAW_SIZE_1M, LAW_TRGT_IF_RIO_1), -#elif defined(CONFIG_SRIOBOOT_SLAVE_PORT1) - SET_LAW(CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS, - LAW_SIZE_1M, LAW_TRGT_IF_RIO_2), - SET_LAW(CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS, - LAW_SIZE_1M, LAW_TRGT_IF_RIO_2), -#endif -#endif }; int num_law_entries = ARRAY_SIZE(law_table); diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c index a7d04b7..a71a0ce 100644 --- a/drivers/misc/fsl_law.c +++ b/drivers/misc/fsl_law.c @@ -275,5 +275,32 @@ void init_laws(void) law_table[i].size, law_table[i].trgt_id); } +#ifdef CONFIG_SRIOBOOT_SLAVE + /* check RCW to get which port is used for boot */ + ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + u32 bootloc = in_be32(&gur->rcwsr[6]); + /* in SRIO boot we need to set specail LAWs for SRIO interfaces */ + switch ((bootloc & FSL_CORENET_RCWSR6_BOOT_LOC) >> 23) { + case 0x8: /* boot from SRIO1 */ + set_next_law(CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_RIO_1); + set_next_law(CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_RIO_1); + break; + case 0x9: /* boot from SRIO2 */ + set_next_law(CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_RIO_2); + set_next_law(CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_RIO_2); + break; + default: + break; + } +#endif + return ; } diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h index 46a5e4c..9d884a3 100644 --- a/include/configs/P2041RDB.h +++ b/include/configs/P2041RDB.h @@ -410,9 +410,6 @@ unsigned long get_board_sys_clk(unsigned long dummy); * SRIOBOOT - SLAVE */ #ifdef CONFIG_SRIOBOOT_SLAVE -/* slave port for srioboot */ -#define CONFIG_SRIOBOOT_SLAVE_PORT0 -/* #define CONFIG_SRIOBOOT_SLAVE_PORT1 */ #define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR 0xFFE00000 #define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS \ (0x300000000ull | CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR) diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index 7f3af21..847e607 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -412,9 +412,6 @@ * SRIOBOOT - SLAVE */ #ifdef CONFIG_SRIOBOOT_SLAVE -/* slave port for srioboot */ -#define CONFIG_SRIOBOOT_SLAVE_PORT0 -/* #define CONFIG_SRIOBOOT_SLAVE_PORT1 */ #define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR 0xFFE00000 #define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS \ (0x300000000ull | CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR) -- cgit v1.1 From fc54c7fa0addfc0e33b703be0502395920d2926b Mon Sep 17 00:00:00 2001 From: Liu Gang Date: Thu, 9 Aug 2012 05:10:01 +0000 Subject: powerpc/corenet_ds: Update README and README.srio-pcie-boot-corenet Added descriptions about boot from PCIE in the files README and doc/README.srio-pcie-boot-corenet, and changed the name of the doc/README.srio-boot-corenet to doc/README.srio-pcie-boot-corenet. Signed-off-by: Liu Gang Signed-off-by: Andy Fleming --- README | 12 ++-- doc/README.srio-boot-corenet | 99 --------------------------------- doc/README.srio-pcie-boot-corenet | 112 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 105 deletions(-) delete mode 100644 doc/README.srio-boot-corenet create mode 100644 doc/README.srio-pcie-boot-corenet diff --git a/README b/README index fb9d904..81ee7d4 100644 --- a/README +++ b/README @@ -3092,12 +3092,12 @@ to save the current settings. These two #defines specify the address and size of the environment area within the remote memory space. The local device can get the environment from remote memory - space by SRIO or other links. + space by SRIO or PCIE links. BE CAREFUL! For some special cases, the local device can not use "saveenv" command. For example, the local device will get the -environment stored in a remote NOR flash by SRIO link, but it can -not erase, write this NOR flash by SRIO interface. +environment stored in a remote NOR flash by SRIO or PCIE link, +but it can not erase, write this NOR flash by SRIO or PCIE interface. - CONFIG_ENV_IS_IN_NAND: @@ -3538,9 +3538,9 @@ within that device. - CONFIG_SYS_QE_FMAN_FW_IN_REMOTE Specifies that QE/FMAN firmware is located in the remote (master) memory space. CONFIG_SYS_FMAN_FW_ADDR is a virtual address which - can be mapped from slave TLB->slave LAW->slave SRIO outbound window - ->master inbound window->master LAW->the ucode address in master's - NOR flash. + can be mapped from slave TLB->slave LAW->slave SRIO or PCIE outbound + window->master inbound window->master LAW->the ucode address in + master's memory space. Building the Software: ====================== diff --git a/doc/README.srio-boot-corenet b/doc/README.srio-boot-corenet deleted file mode 100644 index 6a13e9c..0000000 --- a/doc/README.srio-boot-corenet +++ /dev/null @@ -1,99 +0,0 @@ ------------------------------- -SRIO Boot on Corenet Platforms ------------------------------- - -For some PowerPC processors with SRIO interface, boot location can be configured -to SRIO by RCW. The processor booting from SRIO can do without flash for u-boot -image, ucode and ENV. All the images can be fetched from another processor's -memory space by SRIO link connected between them. - -This document describes the processes based on an example implemented on P4080DS -platforms and a RCW example with boot from SRIO configuration. - -Environment of the SRIO boot: - a) Master and slave can be SOCs in one board or SOCs in separate boards. - b) They are connected with SRIO links, whether 1x or 4x, and directly or - through switch system. - c) Only Master has NorFlash for booting, and all the Master's and Slave's - U-Boot images, UCodes will be stored in this flash. - d) Slave has its own EEPROM for RCW and PBI. - e) Slave's RCW should configure the SerDes for SRIO boot port, set the boot - location to SRIO, and holdoff all the cores. - - ---------- ----------- ----------- - | | | | | | - | | | | | | - | NorFlash|<----->| Master | SRIO | Slave |<---->[EEPROM] - | | | |<===========>| | - | | | | | | - ---------- ----------- ----------- - -The example based on P4080DS platform: - Two P4080DS platforms can be used to implement the boot from SRIO. Their SRIO - ports 1 will be connected directly and will be used for the boot from SRIO. - - 1. Slave's RCW example for boot from SRIO port 1 and all cores in holdoff. - 00000000: aa55 aa55 010e 0100 0c58 0000 0000 0000 - 00000010: 1818 1818 0000 8888 7440 4000 0000 2000 - 00000020: f440 0000 0100 0000 0000 0000 0000 0000 - 00000030: 0000 0000 0083 0000 0000 0000 0000 0000 - 00000040: 0000 0000 0000 0000 0813 8040 063c 778f - - 2. Sequence in Step by Step. - a) Update RCW for slave with boot from SRIO port 1 configuration. - b) Program slave's U-Boot image, UCode, and ENV parameters into master's - NorFlash. - c) Set environment variable "bootmaster" to "SRIO1" and save environment - for master. - setenv bootmaster SRIO1 - saveenv - d) Restart up master and it will boot up normally from its NorFlash. - Then, it will finish necessary configurations for slave's boot from - SRIO port 1. - e) Master will set inbound SRIO windows covered slave's U-Boot image stored - in master's NorFlash. - f) Master will set an inbound SRIO window covered slave's UCode and ENV - stored in master's NorFlash. - g) Master will set outbound SRIO windows in order to configure slave's - registers for the core's releasing. - h) Since all cores of slave in holdoff, slave should be powered on before all - the above master's steps, and wait to be released by master. In the - startup phase of the slave from SRIO, it will finish some necessary - configurations. - i) Slave will set a specific TLB entry for the boot process. - j) Slave will set a LAW entry with the TargetID SRIO port 1 for the boot. - k) Slave will set a specific TLB entry in order to fetch UCode and ENV - from master. - l) Slave will set a LAW entry with the TargetID SRIO port 1 for UCode and ENV. - -How to use this feature: - To use this feature, you need to focus those points. - - 1. Slave's RCW with SRIO boot configurations, and all cores in holdoff - configurations. - Please refer to the examples given above. - - 2. U-Boot image's compilation. - For master, U-Boot image should be generated normally. - - For example, master U-Boot image used on P4080DS should be compiled with - - make P4080DS_config. - - For slave, U-Boot image should be generated specifically by - - make xxxx_SRIOBOOT_SLAVE_config. - - For example, slave U-Boot image used on P4080DS should be compiled with - - make P4080DS_SRIOBOOT_SLAVE_config. - - 3. Necessary modifications based on a specific environment. - For a specific environment, the addresses of the slave's U-Boot image, - UCode, ENV stored in master's NorFlash, and any other configurations - can be modified in the file: - include/configs/corenet_ds.h. - - 4. Set and save the environment variable "bootmaster" with "SRIO1" or "SRIO2" - for master, and then restart it in order to perform the role as a master - for boot from SRIO. diff --git a/doc/README.srio-pcie-boot-corenet b/doc/README.srio-pcie-boot-corenet new file mode 100644 index 0000000..cd7e7ee --- /dev/null +++ b/doc/README.srio-pcie-boot-corenet @@ -0,0 +1,112 @@ +--------------------------------------- +SRIO and PCIE Boot on Corenet Platforms +--------------------------------------- + +For some PowerPC processors with SRIO or PCIE interface, boot location can be +configured to SRIO or PCIE by RCW. The processor booting from SRIO or PCIE can +do without flash for u-boot image, ucode and ENV. All the images can be fetched +from another processor's memory space by SRIO or PCIE link connected between +them. + +This document describes the processes based on an example implemented on P4080DS +platforms and a RCW example with boot from SRIO or PCIE configuration. + +Environment of the SRIO or PCIE boot: + a) Master and slave can be SOCs in one board or SOCs in separate boards. + b) They are connected with SRIO or PCIE links, whether 1x, 2x or 4x, and + directly or through switch system. + c) Only Master has NorFlash for booting, and all the Master's and Slave's + U-Boot images, UCodes will be stored in this flash. + d) Slave has its own EEPROM for RCW and PBI. + e) Slave's RCW should configure the SerDes for SRIO or PCIE boot port, set + the boot location to SRIO or PCIE, and holdoff all the cores. + + ---------- ----------- ----------- + | | | | | | + | | | | | | + | NorFlash|<----->| Master |SRIO or PCIE | Slave |<---->[EEPROM] + | | | |<===========>| | + | | | | | | + ---------- ----------- ----------- + +The example based on P4080DS platform: + Two P4080DS platforms can be used to implement the boot from SRIO or PCIE. + Their SRIO or PCIE ports 1 will be connected directly and will be used for + the boot from SRIO or PCIE. + + 1. Slave's RCW example for boot from SRIO port 1 and all cores in holdoff. + 00000000: aa55 aa55 010e 0100 0c58 0000 0000 0000 + 00000010: 1818 1818 0000 8888 7440 4000 0000 2000 + 00000020: f440 0000 0100 0000 0000 0000 0000 0000 + 00000030: 0000 0000 0083 0000 0000 0000 0000 0000 + 00000040: 0000 0000 0000 0000 0813 8040 063c 778f + + 2. Slave's RCW example for boot from PCIE port 1 and all cores in holdoff. + 00000000: aa55 aa55 010e 0100 0c58 0000 0000 0000 + 00000010: 1818 1818 0000 8888 1440 4000 0000 2000 + 00000020: f040 0000 0100 0000 0020 0000 0000 0000 + 00000030: 0000 0000 0083 0000 0000 0000 0000 0000 + 00000040: 0000 0000 0000 0000 0813 8040 547e ffc9 + + 3. Sequence in Step by Step. + a) Update RCW for slave with boot from SRIO or PCIE port 1 configuration. + b) Program slave's U-Boot image, UCode, and ENV parameters into master's + NorFlash. + c) Set environment variable "bootmaster" to "SRIO1" or "PCIE1" and save + environment for master. + setenv bootmaster SRIO1 + or + setenv bootmaster PCIE1 + saveenv + d) Restart up master and it will boot up normally from its NorFlash. + Then, it will finish necessary configurations for slave's boot from + SRIO or PCIE port 1. + e) Master will set inbound SRIO or PCIE windows covered slave's U-Boot + image stored in master's NorFlash. + f) Master will set an inbound SRIO or PCIE window covered slave's UCode + and ENV stored in master's NorFlash. + g) Master will set outbound SRIO or PCIE windows in order to configure + slave's registers for the core's releasing. + h) Since all cores of slave in holdoff, slave should be powered on before + all the above master's steps, and wait to be released by master. In the + startup phase of the slave from SRIO or PCIE, it will finish some + necessary configurations. + i) Slave will set a specific TLB entry for the boot process. + j) Slave will set a LAW entry with the TargetID SRIO or PCIE port 1 for + the boot. + k) Slave will set a specific TLB entry in order to fetch UCode and ENV + from master. + l) Slave will set a LAW entry with the TargetID SRIO or PCIE port 1 for + UCode and ENV. + +How to use this feature: + To use this feature, you need to focus those points. + + 1. Slave's RCW with SRIO or PCIE boot configurations, and all cores in holdoff + configurations. + Please refer to the examples given above. + + 2. U-Boot image's compilation. + For master, U-Boot image should be generated normally. + + For example, master U-Boot image used on P4080DS should be compiled with + + make P4080DS_config. + + For slave, U-Boot image should be generated specifically by + + make xxxx_SRIO_PCIE_BOOT_config. + + For example, slave U-Boot image used on P4080DS should be compiled with + + make P4080DS_SRIO_PCIE_BOOT_config. + + 3. Necessary modifications based on a specific environment. + For a specific environment, the addresses of the slave's U-Boot image, + UCode, ENV stored in master's NorFlash, and any other configurations + can be modified in the file: + include/configs/corenet_ds.h. + + 4. Set and save the environment variable "bootmaster" with "SRIO1", "SRIO2" + or "PCIE1", "PCIE2", "PCIE3" for master, and then restart it in order to + perform the role as a master for boot from SRIO or PCIE. -- cgit v1.1 From b5f7c8732ad99b0c1a7fa456f706de1ab7d74eef Mon Sep 17 00:00:00 2001 From: Liu Gang Date: Thu, 9 Aug 2012 05:10:02 +0000 Subject: powerpc/corenet_ds: Master module for boot from PCIE For the powerpc processors with PCIE interface, boot location can be configured from one PCIE interface by RCW. The processor booting from PCIE can do without flash for u-boot image. The image can be fetched from another processor's memory space by PCIE link connected between them. The processor booting from PCIE is slave, the processor booting from normal flash memory space is master, and it can help slave to boot from master's memory space. When boot from PCIE, slave's core should be in holdoff after powered on for some specific requirements. Master will release the slave's core at the right time by PCIE interface. Environment and requirement: master: 1. NOR flash for its own u-boot image, ucode and ENV space. 2. Slave's u-boot image is in master NOR flash. 3. Normally boot from local NOR flash. 4. Configure PCIE system if needed. slave: 1. Just has EEPROM for RCW. No flash for u-boot image, ucode and ENV. 2. Boot location should be set to one PCIE interface by RCW. 3. RCW should configure the SerDes, PCIE interfaces correctly. 4. Must set all the cores in holdoff by RCW. 5. Must be powered on before master's boot. For the master module, need to finish these processes: 1. Initialize the PCIE port and address space. 2. Set inbound PCIE windows covered slave's u-boot image stored in master's NOR flash. 3. Set outbound windows in order to configure slave's registers for the core's releasing. 4. Should set the environment variable "bootmaster" to "PCIE1", "PCIE2" or "PCIE3" using the following command: setenv bootmaster PCIE1 saveenv Signed-off-by: Liu Gang Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc8xxx/srio.c | 44 +++++++-------- drivers/pci/fsl_pci_init.c | 116 ++++++++++++++++++++++++++++++++++++++++ include/configs/P2041RDB.h | 18 +++---- include/configs/corenet_ds.h | 18 +++---- 4 files changed, 156 insertions(+), 40 deletions(-) diff --git a/arch/powerpc/cpu/mpc8xxx/srio.c b/arch/powerpc/cpu/mpc8xxx/srio.c index ae83d6e..0cb65b3 100644 --- a/arch/powerpc/cpu/mpc8xxx/srio.c +++ b/arch/powerpc/cpu/mpc8xxx/srio.c @@ -108,44 +108,44 @@ void srio_boot_master(int port) /* configure inbound window for slave's u-boot image */ debug("SRIOBOOT - MASTER: Inbound window for slave's image; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS, - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE); + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwtar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS >> 12); + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12); out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwbar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1 >> 12); + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 >> 12); out_be32((void *)&srio->atmu.port[port - 1].inbw[0].riwar, SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE)); + | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE)); /* configure inbound window for slave's u-boot image */ debug("SRIOBOOT - MASTER: Inbound window for slave's image; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS, - (u64)CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2, - CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE); + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwtar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS >> 12); + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS >> 12); out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwbar, - CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2 >> 12); + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 >> 12); out_be32((void *)&srio->atmu.port[port - 1].inbw[1].riwar, SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE)); + | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE)); /* configure inbound window for slave's ucode and ENV */ debug("SRIOBOOT - MASTER: Inbound window for slave's ucode and ENV; " "Local = 0x%llx, Srio = 0x%llx, Size = 0x%x\n", - (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS, - (u64)CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS, - CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE); + (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE); out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwtar, - CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS >> 12); + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS >> 12); out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwbar, - CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS >> 12); + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS >> 12); out_be32((void *)&srio->atmu.port[port - 1].inbw[2].riwar, SRIO_IB_ATMU_AR - | atmu_size_mask(CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE)); + | atmu_size_mask(CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE)); } void srio_boot_master_release_slave(int port) @@ -227,8 +227,8 @@ void srio_boot_master_release_slave(int port) */ out_be32((void *)CONFIG_SYS_SRIO2_MEM_VIRT + SRIO_MAINT_WIN_SIZE - + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET, - CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK); + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET, + CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); } else { out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT + SRIO_LCSBA1CSR_OFFSET, @@ -243,8 +243,8 @@ void srio_boot_master_release_slave(int port) */ out_be32((void *)CONFIG_SYS_SRIO1_MEM_VIRT + SRIO_MAINT_WIN_SIZE - + CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET, - CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK); + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET, + CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); } debug("SRIOBOOT - MASTER: " "Release slave successfully! Now the slave should start up!\n"); diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index 1d75a82..0d46c96 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -211,6 +211,95 @@ static int fsl_pci_setup_inbound_windows(struct pci_controller *hose, return 1; } +#ifdef CONFIG_FSL_CORENET +static void fsl_pcie_boot_master(pit_t *pi) +{ + /* configure inbound window for slave's u-boot image */ + debug("PCIEBOOT - MASTER: Inbound window for slave's image; " + "Local = 0x%llx, Bus = 0x%llx, Size = 0x%x\n", + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + struct pci_region r_inbound; + u32 sz_inbound = __ilog2_u64(CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE) + - 1; + pci_set_region(&r_inbound, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + sz_inbound, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + set_inbound_window(pi--, &r_inbound, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + + /* configure inbound window for slave's u-boot image */ + debug("PCIEBOOT - MASTER: Inbound window for slave's image; " + "Local = 0x%llx, Bus = 0x%llx, Size = 0x%x\n", + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + pci_set_region(&r_inbound, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2, + CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS, + sz_inbound, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + set_inbound_window(pi--, &r_inbound, + CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE); + + /* configure inbound window for slave's ucode and ENV */ + debug("PCIEBOOT - MASTER: Inbound window for slave's " + "ucode and ENV; " + "Local = 0x%llx, Bus = 0x%llx, Size = 0x%x\n", + (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS, + (u64)CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE); + sz_inbound = __ilog2_u64(CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE) + - 1; + pci_set_region(&r_inbound, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS, + sz_inbound, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + set_inbound_window(pi--, &r_inbound, + CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE); +} + +static void fsl_pcie_boot_master_release_slave(int port) +{ + unsigned long release_addr; + + /* now release slave's core 0 */ + switch (port) { + case 1: + release_addr = CONFIG_SYS_PCIE1_MEM_VIRT + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET; + break; + case 2: + release_addr = CONFIG_SYS_PCIE2_MEM_VIRT + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET; + break; + case 3: + release_addr = CONFIG_SYS_PCIE3_MEM_VIRT + + CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET; + break; + default: + release_addr = 0; + break; + } + if (release_addr != 0) { + out_be32((void *)release_addr, + CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK); + debug("PCIEBOOT - MASTER: " + "Release slave successfully! Now the slave should start up!\n"); + } else { + debug("PCIEBOOT - MASTER: " + "Release slave failed!\n"); + } +} +#endif + void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info) { u32 cfg_addr = (u32)&((ccsr_fsl_pci_t *)pci_info->regs)->cfg_addr; @@ -295,8 +384,25 @@ void fsl_pci_init(struct pci_controller *hose, struct fsl_pci_info *pci_info) /* see if we are a PCIe or PCI controller */ pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap); +#ifdef CONFIG_FSL_CORENET + /* boot from PCIE --master */ + char *s = getenv("bootmaster"); + char pcie[6]; + sprintf(pcie, "PCIE%d", pci_info->pci_num); + + if (s && (strcmp(s, pcie) == 0)) { + debug("PCIEBOOT - MASTER: Master port [ %d ] for pcie boot.\n", + pci_info->pci_num); + fsl_pcie_boot_master((pit_t *)pi); + } else { + /* inbound */ + inbound = fsl_pci_setup_inbound_windows(hose, + out_lo, pcie_cap, pi); + } +#else /* inbound */ inbound = fsl_pci_setup_inbound_windows(hose, out_lo, pcie_cap, pi); +#endif for (r = 0; r < hose->region_count; r++) debug("PCI reg:%d %016llx:%016llx %016llx %08lx\n", r, @@ -488,6 +594,16 @@ int fsl_pci_init_port(struct fsl_pci_info *pci_info, if (fsl_is_pci_agent(hose)) { fsl_pci_config_unlock(hose); hose->last_busno = hose->first_busno; +#ifdef CONFIG_FSL_CORENET + } else { + /* boot from PCIE --master releases slave's core 0 */ + char *s = getenv("bootmaster"); + char pcie[6]; + sprintf(pcie, "PCIE%d", pci_info->pci_num); + + if (s && (strcmp(s, pcie) == 0)) + fsl_pcie_boot_master_release_slave(pci_info->pci_num); +#endif } pci_hose_read_config_byte(hose, dev, FSL_PCIE_CAP_ID, &pcie_cap); diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h index 9d884a3..18e4bce 100644 --- a/include/configs/P2041RDB.h +++ b/include/configs/P2041RDB.h @@ -390,21 +390,21 @@ unsigned long get_board_sys_clk(unsigned long dummy); * for slave u-boot IMAGE instored in master memory space, * PHYS must be aligned based on the SIZE */ -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS 0xfef080000ull -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1 0xfff80000ull -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE 0x80000 /* 512K */ -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2 0x3fff80000ull +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS 0xfef080000ull +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 0xfff80000ull +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE 0x80000 /* 512K */ +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 0x3fff80000ull /* * for slave UCODE and ENV instored in master memory space, * PHYS must be aligned based on the SIZE */ -#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS 0xfef040000ull -#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS 0x3ffe00000ull -#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE 0x40000 /* 256K */ +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS 0xfef040000ull +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS 0x3ffe00000ull +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE 0x40000 /* 256K */ /* slave core release by master*/ -#define CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET 0xe00e4 -#define CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK 0x00000001 /* release core 0 */ +#define CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET 0xe00e4 +#define CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK 0x00000001 /* release core 0 */ /* * SRIOBOOT - SLAVE diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index 847e607..1d25fc1 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -392,21 +392,21 @@ * for slave u-boot IMAGE instored in master memory space, * PHYS must be aligned based on the SIZE */ -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_PHYS 0xfef080000ull -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS1 0xfff80000ull -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_SIZE 0x80000 /* 512K */ -#define CONFIG_SRIOBOOT_SLAVE_IMAGE_MEM_BUS2 0x3fff80000ull +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_PHYS 0xfef080000ull +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS1 0xfff80000ull +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_SIZE 0x80000 /* 512K */ +#define CONFIG_SRIO_PCIE_BOOT_IMAGE_MEM_BUS2 0x3fff80000ull /* * for slave UCODE and ENV instored in master memory space, * PHYS must be aligned based on the SIZE */ -#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_PHYS 0xfef040000ull -#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_MEM_BUS 0x3ffe00000ull -#define CONFIG_SRIOBOOT_SLAVE_UCODE_ENV_SIZE 0x40000 /* 256K */ +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_PHYS 0xfef040000ull +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_MEM_BUS 0x3ffe00000ull +#define CONFIG_SRIO_PCIE_BOOT_UCODE_ENV_SIZE 0x40000 /* 256K */ /* slave core release by master*/ -#define CONFIG_SRIOBOOT_SLAVE_BRR_OFFSET 0xe00e4 -#define CONFIG_SRIOBOOT_SLAVE_RELEASE_MASK 0x00000001 /* release core 0 */ +#define CONFIG_SRIO_PCIE_BOOT_BRR_OFFSET 0xe00e4 +#define CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK 0x00000001 /* release core 0 */ /* * SRIOBOOT - SLAVE -- cgit v1.1 From 461632bd71152fefd7f6b155d6b870e586212416 Mon Sep 17 00:00:00 2001 From: Liu Gang Date: Thu, 9 Aug 2012 05:10:03 +0000 Subject: powerpc/corenet_ds: Slave module for boot from PCIE When boot from PCIE, slave's core should be in holdoff after powered on for some specific requirements. Master will release the slave's core at the right time by PCIE interface. Slave's ucode and ENV can be stored in master's memory space, then slave can fetch them through PCIE interface. For the corenet platform, ucode is for Fman. NOTE: Because the slave can not erase, write master's NOR flash by PCIE interface, so it can not modify the ENV parameters stored in master's NOR flash using "saveenv" or other commands. environment and requirement: master: 1. NOR flash for its own u-boot image, ucode and ENV space. 2. Slave's u-boot image is in master NOR flash. 3. Put the slave's ucode and ENV into it's own memory space. 4. Normally boot from local NOR flash. 5. Configure PCIE system if needed. slave: 1. Just has EEPROM for RCW. No flash for u-boot image, ucode and ENV. 2. Boot location should be set to one PCIE interface by RCW. 3. RCW should configure the SerDes, PCIE interfaces correctly. 4. Must set all the cores in holdoff by RCW. 5. Must be powered on before master's boot. For the slave module, need to finish these processes: 1. Set the boot location to one PCIE interface by RCW. 2. Set a specific TLB entry for the boot process. 3. Set a LAW entry with the TargetID of one PCIE for the boot. 4. Set a specific TLB entry in order to fetch ucode and ENV from master. 5. Set a LAW entry with the TargetID one of the PCIE ports for ucode and ENV. 6. Slave's u-boot image should be generated specifically by make xxxx_SRIO_PCIE_BOOT_config. This will set SYS_TEXT_BASE=0xFFF80000 and other configurations. In addition, the processes are very similar between boot from SRIO and boot from PCIE. Some configurations like the address spaces can be set to the same. So the module of boot from PCIE was added based on the existing module of boot from SRIO, and the following changes were needed: 1. Updated the README.srio-boot-corenet to add descriptions about boot from PCIE, and change the name to README.srio-pcie-boot-corenet. 2. Changed the compile config "xxxx_SRIOBOOT_SLAVE" to "xxxx_SRIO_PCIE_BOOT", and the image builded with "xxxx_SRIO_PCIE_BOOT" can support both the boot from SRIO and from PCIE. 3. Updated other macros and documents if needed to add information about boot from PCIE. Signed-off-by: Liu Gang Signed-off-by: Andy Fleming --- board/freescale/common/p_corenet/tlb.c | 18 ++++++++-------- boards.cfg | 8 +++---- common/env_remote.c | 4 ++-- drivers/misc/fsl_law.c | 39 ++++++++++++++++++++++++++++------ include/configs/P2041RDB.h | 28 ++++++++++++------------ include/configs/corenet_ds.h | 28 ++++++++++++------------ 6 files changed, 76 insertions(+), 49 deletions(-) diff --git a/board/freescale/common/p_corenet/tlb.c b/board/freescale/common/p_corenet/tlb.c index da21627..e5cf208 100644 --- a/board/freescale/common/p_corenet/tlb.c +++ b/board/freescale/common/p_corenet/tlb.c @@ -66,13 +66,13 @@ struct fsl_e_tlb_entry tlb_table[] = { SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L3_ADDR, CONFIG_SYS_INIT_L3_ADDR, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 0, BOOKE_PAGESZ_1M, 1), -#elif defined(CONFIG_SRIOBOOT_SLAVE) +#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) /* - * SRIOBOOT-SLAVE. When slave boot, the address of the + * SRIO_PCIE_BOOT-SLAVE. When slave boot, the address of the * space is at 0xfff00000, it covered the 0xfffff000. */ - SET_TLB_ENTRY(1, CONFIG_SYS_SRIOBOOT_SLAVE_ADDR, - CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS, + SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR, + CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_W|MAS2_G, 0, 0, BOOKE_PAGESZ_1M, 1), #else @@ -147,13 +147,13 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 16, BOOKE_PAGESZ_1M, 1), #endif -#ifdef CONFIG_SRIOBOOT_SLAVE +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE /* - * SRIOBOOT-SLAVE. 1M space from 0xffe00000 for fetching ucode - * and ENV from master + * SRIO_PCIE_BOOT-SLAVE. 1M space from 0xffe00000 for + * fetching ucode and ENV from master */ - SET_TLB_ENTRY(1, CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR, - CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS, + SET_TLB_ENTRY(1, CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR, + CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_G, 0, 17, BOOKE_PAGESZ_1M, 1), #endif diff --git a/boards.cfg b/boards.cfg index a408405..f102f7a 100644 --- a/boards.cfg +++ b/boards.cfg @@ -787,13 +787,13 @@ P2041RDB_NAND powerpc mpc85xx p2041rdb freescale P2041RDB_SDCARD powerpc mpc85xx p2041rdb freescale - P2041RDB:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P2041RDB_SECURE_BOOT powerpc mpc85xx p2041rdb freescale - P2041RDB:SECURE_BOOT P2041RDB_SPIFLASH powerpc mpc85xx p2041rdb freescale - P2041RDB:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 -P2041RDB_SRIOBOOT_SLAVE powerpc mpc85xx p2041rdb freescale - P2041RDB:SRIOBOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 +P2041RDB_SRIO_PCIE_BOOT powerpc mpc85xx p2041rdb freescale - P2041RDB:SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 P3041DS powerpc mpc85xx corenet_ds freescale P3041DS_NAND powerpc mpc85xx corenet_ds freescale - P3041DS:RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000 P3041DS_SDCARD powerpc mpc85xx corenet_ds freescale - P3041DS:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P3041DS_SECURE_BOOT powerpc mpc85xx corenet_ds freescale - P3041DS:SECURE_BOOT P3041DS_SPIFLASH powerpc mpc85xx corenet_ds freescale - P3041DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 -P3041DS_SRIOBOOT_SLAVE powerpc mpc85xx corenet_ds freescale - P3041DS:SRIOBOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 +P3041DS_SRIO_PCIE_BOOT powerpc mpc85xx corenet_ds freescale - P3041DS:SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 P3060QDS powerpc mpc85xx p3060qds freescale P3060QDS_NAND powerpc mpc85xx p3060qds freescale - P3060QDS:RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000 P3060QDS_SECURE_BOOT powerpc mpc85xx p3060qds freescale - P3060QDS:SECURE_BOOT @@ -801,13 +801,13 @@ P4080DS powerpc mpc85xx corenet_ds freesca P4080DS_SDCARD powerpc mpc85xx corenet_ds freescale - P4080DS:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P4080DS_SECURE_BOOT powerpc mpc85xx corenet_ds freescale - P4080DS:SECURE_BOOT P4080DS_SPIFLASH powerpc mpc85xx corenet_ds freescale - P4080DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 -P4080DS_SRIOBOOT_SLAVE powerpc mpc85xx corenet_ds freescale - P4080DS:SRIOBOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 +P4080DS_SRIO_PCIE_BOOT powerpc mpc85xx corenet_ds freescale - P4080DS:SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 P5020DS powerpc mpc85xx corenet_ds freescale P5020DS_NAND powerpc mpc85xx corenet_ds freescale - P5020DS:RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000 P5020DS_SDCARD powerpc mpc85xx corenet_ds freescale - P5020DS:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P5020DS_SECURE_BOOT powerpc mpc85xx corenet_ds freescale - P5020DS:SECURE_BOOT P5020DS_SPIFLASH powerpc mpc85xx corenet_ds freescale - P5020DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 -P5020DS_SRIOBOOT_SLAVE powerpc mpc85xx corenet_ds freescale - P5020DS:SRIOBOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 +P5020DS_SRIO_PCIE_BOOT powerpc mpc85xx corenet_ds freescale - P5020DS:SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 BSC9131RDB_SPIFLASH powerpc mpc85xx bsc9131rdb freescale - BSC9131RDB:BSC9131RDB,SPIFLASH stxgp3 powerpc mpc85xx stxgp3 stx stxssa powerpc mpc85xx stxssa stx - stxssa diff --git a/common/env_remote.c b/common/env_remote.c index 3bf0f95..a7b147b 100644 --- a/common/env_remote.c +++ b/common/env_remote.c @@ -62,8 +62,8 @@ int env_init(void) #ifdef CONFIG_CMD_SAVEENV int saveenv(void) { -#ifdef CONFIG_SRIOBOOT_SLAVE - printf("Can not support the 'saveenv' when boot from SRIO!\n"); +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE + printf("Can not support the 'saveenv' when boot from SRIO or PCIE!\n"); return 1; #else return 0; diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c index a71a0ce..223cd5d 100644 --- a/drivers/misc/fsl_law.c +++ b/drivers/misc/fsl_law.c @@ -275,25 +275,52 @@ void init_laws(void) law_table[i].size, law_table[i].trgt_id); } -#ifdef CONFIG_SRIOBOOT_SLAVE +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE /* check RCW to get which port is used for boot */ ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; u32 bootloc = in_be32(&gur->rcwsr[6]); - /* in SRIO boot we need to set specail LAWs for SRIO interfaces */ + /* + * in SRIO or PCIE boot we need to set specail LAWs for + * SRIO or PCIE interfaces. + */ switch ((bootloc & FSL_CORENET_RCWSR6_BOOT_LOC) >> 23) { + case 0x0: /* boot from PCIE1 */ + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_1); + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_1); + break; + case 0x1: /* boot from PCIE2 */ + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_2); + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_2); + break; + case 0x2: /* boot from PCIE3 */ + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_3); + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, + LAW_SIZE_1M, + LAW_TRGT_IF_PCIE_3); + break; case 0x8: /* boot from SRIO1 */ - set_next_law(CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS, + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_RIO_1); - set_next_law(CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS, + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_RIO_1); break; case 0x9: /* boot from SRIO2 */ - set_next_law(CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS, + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_RIO_2); - set_next_law(CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS, + set_next_law(CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_RIO_2); break; diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h index 18e4bce..ce31fdc 100644 --- a/include/configs/P2041RDB.h +++ b/include/configs/P2041RDB.h @@ -36,11 +36,11 @@ #define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc #endif -#ifdef CONFIG_SRIOBOOT_SLAVE +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE /* Set 1M boot space */ -#define CONFIG_SYS_SRIOBOOT_SLAVE_ADDR (CONFIG_SYS_TEXT_BASE & 0xfff00000) -#define CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS \ - (0x300000000ull | CONFIG_SYS_SRIOBOOT_SLAVE_ADDR) +#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR (CONFIG_SYS_TEXT_BASE & 0xfff00000) +#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS \ + (0x300000000ull | CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR) #define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc #define CONFIG_SYS_NO_FLASH #endif @@ -82,7 +82,7 @@ #define CONFIG_ENV_OVERWRITE #ifdef CONFIG_SYS_NO_FLASH -#if !defined(CONFIG_RAMBOOT_PBL) && !defined(CONFIG_SRIOBOOT_SLAVE) +#if !defined(CONFIG_RAMBOOT_PBL) && !defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) #define CONFIG_ENV_IS_NOWHERE #endif #else @@ -113,7 +113,7 @@ #define CONFIG_ENV_IS_IN_NAND #define CONFIG_ENV_SIZE CONFIG_SYS_NAND_BLOCK_SIZE #define CONFIG_ENV_OFFSET (5 * CONFIG_SYS_NAND_BLOCK_SIZE) -#elif defined(CONFIG_SRIOBOOT_SLAVE) +#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) #define CONFIG_ENV_IS_IN_REMOTE #define CONFIG_ENV_ADDR 0xffe20000 #define CONFIG_ENV_SIZE 0x2000 @@ -407,12 +407,12 @@ unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK 0x00000001 /* release core 0 */ /* - * SRIOBOOT - SLAVE + * SRIO_PCIE_BOOT - SLAVE */ -#ifdef CONFIG_SRIOBOOT_SLAVE -#define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR 0xFFE00000 -#define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS \ - (0x300000000ull | CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR) +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE +#define CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR 0xFFE00000 +#define CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS \ + (0x300000000ull | CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR) #endif /* @@ -527,13 +527,13 @@ unsigned long get_board_sys_clk(unsigned long dummy); #elif defined(CONFIG_NAND) #define CONFIG_SYS_QE_FMAN_FW_IN_NAND #define CONFIG_SYS_QE_FMAN_FW_ADDR (6 * CONFIG_SYS_NAND_BLOCK_SIZE) -#elif defined(CONFIG_SRIOBOOT_SLAVE) +#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) /* * Slave has no ucode locally, it can fetch this from remote. When implementing * in two corenet boards, slave's ucode could be stored in master's memory * space, the address can be mapped from slave TLB->slave LAW-> - * slave SRIO outbound window->master inbound window->master LAW-> - * the ucode address in master's NOR flash. + * slave SRIO or PCIE outbound window->master inbound window-> + * master LAW->the ucode address in master's memory space. */ #define CONFIG_SYS_QE_FMAN_FW_IN_REMOTE #define CONFIG_SYS_QE_FMAN_FW_ADDR 0xFFE00000 diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index 1d25fc1..8f6f39a 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -33,11 +33,11 @@ #define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc #endif -#ifdef CONFIG_SRIOBOOT_SLAVE +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE /* Set 1M boot space */ -#define CONFIG_SYS_SRIOBOOT_SLAVE_ADDR (CONFIG_SYS_TEXT_BASE & 0xfff00000) -#define CONFIG_SYS_SRIOBOOT_SLAVE_ADDR_PHYS \ - (0x300000000ull | CONFIG_SYS_SRIOBOOT_SLAVE_ADDR) +#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR (CONFIG_SYS_TEXT_BASE & 0xfff00000) +#define CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR_PHYS \ + (0x300000000ull | CONFIG_SYS_SRIO_PCIE_BOOT_SLAVE_ADDR) #define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc #define CONFIG_SYS_NO_FLASH #endif @@ -77,7 +77,7 @@ #define CONFIG_ENV_OVERWRITE #ifdef CONFIG_SYS_NO_FLASH -#if !defined(CONFIG_SRIOBOOT_SLAVE) && !defined(CONFIG_RAMBOOT_PBL) +#if !defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) && !defined(CONFIG_RAMBOOT_PBL) #define CONFIG_ENV_IS_NOWHERE #endif #else @@ -108,7 +108,7 @@ #define CONFIG_ENV_IS_IN_NAND #define CONFIG_ENV_SIZE CONFIG_SYS_NAND_BLOCK_SIZE #define CONFIG_ENV_OFFSET (5 * CONFIG_SYS_NAND_BLOCK_SIZE) -#elif defined(CONFIG_SRIOBOOT_SLAVE) +#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) #define CONFIG_ENV_IS_IN_REMOTE #define CONFIG_ENV_ADDR 0xffe20000 #define CONFIG_ENV_SIZE 0x2000 @@ -409,12 +409,12 @@ #define CONFIG_SRIO_PCIE_BOOT_RELEASE_MASK 0x00000001 /* release core 0 */ /* - * SRIOBOOT - SLAVE + * SRIO_PCIE_BOOT - SLAVE */ -#ifdef CONFIG_SRIOBOOT_SLAVE -#define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR 0xFFE00000 -#define CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR_PHYS \ - (0x300000000ull | CONFIG_SYS_SRIOBOOT_UCODE_ENV_ADDR) +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE +#define CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR 0xFFE00000 +#define CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR_PHYS \ + (0x300000000ull | CONFIG_SYS_SRIO_PCIE_BOOT_UCODE_ENV_ADDR) #endif /* @@ -537,13 +537,13 @@ #elif defined(CONFIG_NAND) #define CONFIG_SYS_QE_FMAN_FW_IN_NAND #define CONFIG_SYS_QE_FMAN_FW_ADDR (6 * CONFIG_SYS_NAND_BLOCK_SIZE) -#elif defined(CONFIG_SRIOBOOT_SLAVE) +#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE) /* * Slave has no ucode locally, it can fetch this from remote. When implementing * in two corenet boards, slave's ucode could be stored in master's memory * space, the address can be mapped from slave TLB->slave LAW-> - * slave SRIO outbound window->master inbound window->master LAW-> - * the ucode address in master's NOR flash. + * slave SRIO or PCIE outbound window->master inbound window-> + * master LAW->the ucode address in master's memory space. */ #define CONFIG_SYS_QE_FMAN_FW_IN_REMOTE #define CONFIG_SYS_QE_FMAN_FW_ADDR 0xFFE00000 -- cgit v1.1 From 5d898a00f3929fbe18427d15524c4da6b7575b95 Mon Sep 17 00:00:00 2001 From: Shaohui Xie Date: Fri, 10 Aug 2012 02:49:35 +0000 Subject: powerpc/CoreNet: add tool to support pbl image build. Provides a tool to build boot Image for PBL(Pre boot loader) which is used on Freescale CoreNet SoCs, PBL can be used to load some instructions and/or data for pre-initialization. The default output image is u-boot.pbl, for more details please refer to doc/README.pblimage. Signed-off-by: Shaohui Xie Signed-off-by: Andy Fleming --- Makefile | 6 + board/freescale/corenet_ds/pbi.cfg | 51 +++++ board/freescale/corenet_ds/rcw_p3041ds.cfg | 11 + board/freescale/corenet_ds/rcw_p4080ds.cfg | 11 + board/freescale/corenet_ds/rcw_p5020ds.cfg | 11 + common/image.c | 1 + doc/README.pblimage | 114 ++++++++++ include/configs/corenet_ds.h | 8 + include/image.h | 1 + tools/Makefile | 2 + tools/mkimage.c | 15 ++ tools/mkimage.h | 3 + tools/pblimage.c | 331 +++++++++++++++++++++++++++++ tools/pblimage.h | 36 ++++ 14 files changed, 601 insertions(+) create mode 100644 board/freescale/corenet_ds/pbi.cfg create mode 100644 board/freescale/corenet_ds/rcw_p3041ds.cfg create mode 100644 board/freescale/corenet_ds/rcw_p4080ds.cfg create mode 100644 board/freescale/corenet_ds/rcw_p5020ds.cfg create mode 100644 doc/README.pblimage create mode 100644 tools/pblimage.c create mode 100644 tools/pblimage.h diff --git a/Makefile b/Makefile index 947f3ff..02b2ede 100644 --- a/Makefile +++ b/Makefile @@ -422,6 +422,11 @@ $(obj)u-boot.kwb: $(obj)u-boot.bin $(obj)tools/mkimage -n $(CONFIG_SYS_KWD_CONFIG) -T kwbimage \ -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) -d $< $@ +$(obj)u-boot.pbl: $(obj)u-boot.bin + $(obj)tools/mkimage -n $(CONFIG_PBLRCW_CONFIG) \ + -R $(CONFIG_PBLPBI_CONFIG) -T pblimage \ + -d $< $@ + $(obj)u-boot.sha1: $(obj)u-boot.bin $(obj)tools/ubsha1 $(obj)u-boot.bin @@ -782,6 +787,7 @@ clobber: tidy $(obj)cscope.* $(obj)*.*~ @rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL-y) @rm -f $(obj)u-boot.kwb + @rm -f $(obj)u-boot.pbl @rm -f $(obj)u-boot.imx @rm -f $(obj)u-boot.ubl @rm -f $(obj)u-boot.ais diff --git a/board/freescale/corenet_ds/pbi.cfg b/board/freescale/corenet_ds/pbi.cfg new file mode 100644 index 0000000..50806ca --- /dev/null +++ b/board/freescale/corenet_ds/pbi.cfg @@ -0,0 +1,51 @@ +# +# Copyright 2012 Freescale Semiconductor, Inc. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA +# +# Refer docs/README.pblimage for more details about how-to configure +# and create PBL boot image +# + +#PBI commands +#Initialize CPC1 as 1MB SRAM +09010000 00200400 +09138000 00000000 +091380c0 00000100 +09010100 00000000 +09010104 fff0000b +09010f00 08000000 +09010000 80000000 +#Configure LAW for CPC1 +09000d00 00000000 +09000d04 fff00000 +09000d08 81000013 +09000010 00000000 +09000014 ff000000 +09000018 81000000 +#Initialize eSPI controller, default configuration is slow for eSPI to +#load data, this configuration comes from u-boot eSPI driver. +09110000 80000403 +09110020 2d170008 +09110024 00100008 +09110028 00100008 +0911002c 00100008 +#Flush PBL data +09138000 00000000 +091380c0 00000000 diff --git a/board/freescale/corenet_ds/rcw_p3041ds.cfg b/board/freescale/corenet_ds/rcw_p3041ds.cfg new file mode 100644 index 0000000..8813156 --- /dev/null +++ b/board/freescale/corenet_ds/rcw_p3041ds.cfg @@ -0,0 +1,11 @@ +# +# Default RCW for P3041DS. +# + +#PBL preamble and RCW header +aa55aa55 010e0100 +#64 bytes RCW data +12600000 00000000 241C0000 00000000 +D8984A01 03002000 58000000 41000000 +00000000 00000000 00000000 10070000 +00000000 00000000 00000000 00000000 diff --git a/board/freescale/corenet_ds/rcw_p4080ds.cfg b/board/freescale/corenet_ds/rcw_p4080ds.cfg new file mode 100644 index 0000000..6a26339 --- /dev/null +++ b/board/freescale/corenet_ds/rcw_p4080ds.cfg @@ -0,0 +1,11 @@ +# +# Default RCW for P4080DS. +# + +#PBL preamble and RCW header +aa55aa55 010e0100 +#64 bytes RCW data +105a0000 00000000 1e1e181e 0000cccc +58400000 3c3c2000 58000000 e1000000 +00000000 00000000 00000000 008b6000 +00000000 00000000 00000000 00000000 diff --git a/board/freescale/corenet_ds/rcw_p5020ds.cfg b/board/freescale/corenet_ds/rcw_p5020ds.cfg new file mode 100644 index 0000000..b09e409 --- /dev/null +++ b/board/freescale/corenet_ds/rcw_p5020ds.cfg @@ -0,0 +1,11 @@ +# +# Default RCW for P5020DS. +# + +#PBL preamble and RCW header +aa55aa55 010e0100 +#64 bytes RCW data +0C540000 00000000 1E120000 00000000 +D8984A01 03002000 58000000 41000000 +00000000 00000000 00000000 10070000 +00000000 00000000 00000000 00000000 diff --git a/common/image.c b/common/image.c index 91954ac..0c601bb 100644 --- a/common/image.c +++ b/common/image.c @@ -143,6 +143,7 @@ static const table_entry_t uimage_type[] = { { IH_TYPE_INVALID, NULL, "Invalid Image", }, { IH_TYPE_MULTI, "multi", "Multi-File Image", }, { IH_TYPE_OMAPIMAGE, "omapimage", "TI OMAP SPL With GP CH",}, + { IH_TYPE_PBLIMAGE, "pblimage", "Freescale PBL Boot Image",}, { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, { IH_TYPE_SCRIPT, "script", "Script", }, { IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, diff --git a/doc/README.pblimage b/doc/README.pblimage new file mode 100644 index 0000000..2b9bb5c --- /dev/null +++ b/doc/README.pblimage @@ -0,0 +1,114 @@ +------------------------------------------------------------------ +Freescale PBL(pre-boot loader) Boot Image generation using mkimage +------------------------------------------------------------------ + +The CoreNet SoC's can boot directly from eSPI FLASH, SD/MMC and +NAND, etc. These SoCs use PBL to load RCW and/or pre-initialization +instructions. For more details refer section 5 Pre-boot loader +specifications of reference manual P3041RM/P4080RM/P5020RM at link: +http://www.freescale.com/webapp/search/Serp.jsp?Reference+Manuals + +Building PBL Boot Image and boot steps +-------------------------------------- + +1. Building PBL Boot Image. + The default Image is u-boot.pbl. + + For eSPI boot(available on P3041/P4080/P5020): + To build the eSPI boot image: + make _SPIFLASH_config + make u-boot.pbl + + For SD boot(available on P3041/P4080/P5020): + To build the SD boot image: + make _SDCARD_config + make u-boot.pbl + + For Nand boot(available on P3041/P5020): + To build the NAND boot image: + make _NAND_config + make u-boot.pbl + + +2. pblimage support available with mkimage utility will generate Freescale PBL +boot image that can be flashed on the board eSPI flash, SD/MMC and NAND. +Following steps describe it in detail. + + 1). Boot from eSPI flash + Write u-boot.pbl to eSPI flash from offset 0x0. + for ex in u-boot: + =>tftp 100000 u-boot.pbl + =>sf probe 0 + =>sf erase 0 100000 + =>sf write 100000 0 $filesize + Change SW1[1:5] = off off on off on. + + 2). Boot from SD/MMC + Write u-boot.pbl to SD/MMC from offset 0x1000. + for ex in u-boot: + =>tftp 100000 u-boot.pbl + =>mmcinfo + =>mmc write 100000 8 441 + Change SW1[1:5] = off off on on off. + + 3). Boot from Nand + Write u-boot.pbl to Nand from offset 0x0. + for ex in u-boot: + =>tftp 100000 u-boot.pbl + =>nand info + =>nand erase 0 100000 + =>nand write 100000 0 $filesize + Change SW1[1:5] = off on off off on + Change SW7[1:4] = on off off on + +Board specific configuration file specifications: +------------------------------------------------ +1. Configuration files rcw.cfg and pbi.cfg must present in the +board/freescale/corenet_ds/, rcw.cfg is for RCW, pbi.cfg is for +PBI instructions. File name must not be changed since they are used +in Makefile. +2. These files can have empty lines and lines starting with "#" as first +character to put comments + +Typical example of rcw.cfg file: +----------------------------------- + +#PBL preamble and RCW header +aa55aa55 010e0100 +#64 bytes RCW data +4c580000 00000000 18185218 0000cccc +40464000 3c3c2000 58000000 61000000 +00000000 00000000 00000000 008b6000 +00000000 00000000 00000000 00000000 + +Typical example of pbi.cfg file: +----------------------------------- + +#PBI commands +#Initialize CPC1 +09010000 00200400 +09138000 00000000 +091380c0 00000100 +09010100 00000000 +09010104 fff0000b +09010f00 08000000 +09010000 80000000 +#Configure LAW for CPC1 +09000d00 00000000 +09000d04 fff00000 +09000d08 81000013 +09000010 00000000 +09000014 ff000000 +09000018 81000000 +#Initialize eSPI controller +09110000 80000403 +09110020 2d170008 +09110024 00100008 +09110028 00100008 +0911002c 00100008 +#Flush PBL data +09138000 00000000 +091380c0 00000000 + +------------------------------------------------ +Author: Shaohui Xie diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index 8f6f39a..ad3622c 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -31,6 +31,14 @@ #ifdef CONFIG_RAMBOOT_PBL #define CONFIG_RAMBOOT_TEXT_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc +#define CONFIG_PBLPBI_CONFIG $(SRCTREE)/board/freescale/corenet_ds/pbi.cfg +#if defined(CONFIG_P3041DS) +#define CONFIG_PBLRCW_CONFIG $(SRCTREE)/board/freescale/corenet_ds/rcw_p3041ds.cfg +#elif defined(CONFIG_P4080DS) +#define CONFIG_PBLRCW_CONFIG $(SRCTREE)/board/freescale/corenet_ds/rcw_p4080ds.cfg +#elif defined(CONFIG_P5020DS) +#define CONFIG_PBLRCW_CONFIG $(SRCTREE)/board/freescale/corenet_ds/rcw_p5020ds.cfg +#endif #endif #ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE diff --git a/include/image.h b/include/image.h index aa9daa2..e5f6649 100644 --- a/include/image.h +++ b/include/image.h @@ -164,6 +164,7 @@ #define IH_TYPE_OMAPIMAGE 12 /* TI OMAP Config Header Image */ #define IH_TYPE_AISIMAGE 13 /* TI Davinci AIS Image */ #define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image, can run from any load address */ +#define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */ /* * Compression Types diff --git a/tools/Makefile b/tools/Makefile index a7d1e18..c31437e 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -92,6 +92,7 @@ OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o NOPED_OBJ_FILES-y += aisimage.o NOPED_OBJ_FILES-y += kwbimage.o +NOPED_OBJ_FILES-y += pblimage.o NOPED_OBJ_FILES-y += imximage.o NOPED_OBJ_FILES-y += omapimage.o NOPED_OBJ_FILES-y += mkenvimage.o @@ -208,6 +209,7 @@ $(obj)mkimage$(SFX): $(obj)aisimage.o \ $(obj)image.o \ $(obj)imximage.o \ $(obj)kwbimage.o \ + $(obj)pblimage.o \ $(obj)md5.o \ $(obj)mkimage.o \ $(obj)os_support.o \ diff --git a/tools/mkimage.c b/tools/mkimage.c index eeb1b10..e43b09f 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -39,6 +39,7 @@ struct mkimage_params params = { .comp = IH_COMP_GZIP, .dtc = MKIMAGE_DEFAULT_DTC_OPTIONS, .imagename = "", + .imagename2 = "", }; /* @@ -150,6 +151,8 @@ main (int argc, char **argv) int retval = 0; struct image_type_params *tparams = NULL; + /* Init Freescale PBL Boot image generation/list support */ + init_pbl_image_type(); /* Init Kirkwood Boot image generation/list support */ init_kwb_image_type (); /* Init Freescale imx Boot image generation/list support */ @@ -250,6 +253,15 @@ main (int argc, char **argv) usage (); params.imagename = *++argv; goto NXTARG; + case 'R': + if (--argc <= 0) + usage(); + /* + * This entry is for the second configuration + * file, if only one is not enough. + */ + params.imagename2 = *++argv; + goto NXTARG; case 's': params.skipcpy = 1; break; @@ -440,6 +452,9 @@ NXTARG: ; break; } } + } else if (params.type == IH_TYPE_PBLIMAGE) { + /* PBL has special Image format, implements its' own */ + pbl_load_uboot(ifd, ¶ms); } else { copy_file (ifd, params.datafile, 0); } diff --git a/tools/mkimage.h b/tools/mkimage.h index 5fe1a48..ea45f5c 100644 --- a/tools/mkimage.h +++ b/tools/mkimage.h @@ -69,6 +69,7 @@ struct mkimage_params { unsigned int addr; unsigned int ep; char *imagename; + char *imagename2; char *datafile; char *imagefile; char *cmdname; @@ -147,6 +148,8 @@ void mkimage_register (struct image_type_params *tparams); * * Supported image types init functions */ +void pbl_load_uboot(int fd, struct mkimage_params *mparams); +void init_pbl_image_type(void); void init_ais_image_type(void); void init_kwb_image_type (void); void init_imx_image_type (void); diff --git a/tools/pblimage.c b/tools/pblimage.c new file mode 100644 index 0000000..508a747 --- /dev/null +++ b/tools/pblimage.c @@ -0,0 +1,331 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#define _GNU_SOURCE + +#include "mkimage.h" +#include +#include "pblimage.h" + +/* + * The PBL can load up to 64 bytes at a time, so we split the U-Boot + * image into 64 byte chunks. PBL needs a command for each piece, of + * the form "81xxxxxx", where "xxxxxx" is the offset. SYS_TEXT_BASE + * is 0xFFF80000 for PBL boot, and PBL only cares about low 24-bit, + * so it starts from 0x81F80000. + */ +static uint32_t next_pbl_cmd = 0x81F80000; +/* + * need to store all bytes in memory for calculating crc32, then write the + * bytes to image file for PBL boot. + */ +static unsigned char mem_buf[600000]; +static unsigned char *pmem_buf = mem_buf; +static int pbl_size; +static char *fname = "Unknown"; +static int lineno = -1; +static struct pbl_header pblimage_header; + +static union +{ + char c[4]; + unsigned char l; +} endian_test = { {'l', '?', '?', 'b'} }; + +#define ENDIANNESS ((char)endian_test.l) + +static void generate_pbl_cmd(void) +{ + uint32_t val = next_pbl_cmd; + next_pbl_cmd += 0x40; + int i; + + for (i = 3; i >= 0; i--) { + *pmem_buf++ = (val >> (i * 8)) & 0xff; + pbl_size++; + } +} + +static void pbl_fget(size_t size, FILE *stream) +{ + unsigned char c; + int c_temp; + + while (size && (c_temp = fgetc(stream)) != EOF) { + c = (unsigned char)c_temp; + *pmem_buf++ = c; + pbl_size++; + size--; + } +} + +/* load split u-boot with PBI command 81xxxxxx. */ +static void load_uboot(FILE *fp_uboot) +{ + while (next_pbl_cmd < 0x82000000) { + generate_pbl_cmd(); + pbl_fget(64, fp_uboot); + } +} + +static void check_get_hexval(char *token) +{ + uint32_t hexval; + int i; + + if (!sscanf(token, "%x", &hexval)) { + printf("Error:%s[%d] - Invalid hex data(%s)\n", fname, + lineno, token); + exit(EXIT_FAILURE); + } + for (i = 3; i >= 0; i--) { + *pmem_buf++ = (hexval >> (i * 8)) & 0xff; + pbl_size++; + } +} + +static void pbl_parser(char *name) +{ + FILE *fd = NULL; + char *line = NULL; + char *token, *saveptr1, *saveptr2; + size_t len = 0; + + fname = name; + fd = fopen(name, "r"); + if (fd == NULL) { + printf("Error:%s - Can't open\n", fname); + exit(EXIT_FAILURE); + } + + while ((getline(&line, &len, fd)) > 0) { + lineno++; + token = strtok_r(line, "\r\n", &saveptr1); + /* drop all lines with zero tokens (= empty lines) */ + if (token == NULL) + continue; + for (line = token;; line = NULL) { + token = strtok_r(line, " \t", &saveptr2); + if (token == NULL) + break; + /* Drop all text starting with '#' as comments */ + if (token[0] == '#') + break; + check_get_hexval(token); + } + } + if (line) + free(line); + fclose(fd); +} + +static uint32_t crc_table[256]; + +static void make_crc_table(void) +{ + uint32_t mask; + int i, j; + uint32_t poly; /* polynomial exclusive-or pattern */ + + /* + * the polynomial used by PBL is 1 + x1 + x2 + x4 + x5 + x7 + x8 + x10 + * + x11 + x12 + x16 + x22 + x23 + x26 + x32. + */ + poly = 0x04c11db7; + + for (i = 0; i < 256; i++) { + mask = i << 24; + for (j = 0; j < 8; j++) { + if (mask & 0x80000000) + mask = (mask << 1) ^ poly; + else + mask <<= 1; + } + crc_table[i] = mask; + } +} + +unsigned long pbl_crc32(unsigned long crc, const char *buf, uint32_t len) +{ + uint32_t crc32_val = 0xffffffff; + uint32_t xor = 0x0; + int i; + + make_crc_table(); + + for (i = 0; i < len; i++) + crc32_val = (crc32_val << 8) ^ + crc_table[(crc32_val >> 24) ^ (*buf++ & 0xff)]; + + crc32_val = crc32_val ^ xor; + if (crc32_val < 0) { + crc32_val += 0xffffffff; + crc32_val += 1; + } + return crc32_val; +} + +static uint32_t reverse_byte(uint32_t val) +{ + uint32_t temp; + unsigned char *p1; + int j; + + temp = val; + p1 = (unsigned char *)&temp; + for (j = 3; j >= 0; j--) + *p1++ = (val >> (j * 8)) & 0xff; + return temp; +} + +/* write end command and crc command to memory. */ +static void add_end_cmd(void) +{ + uint32_t pbl_end_cmd[4] = {0x09138000, 0x00000000, + 0x091380c0, 0x00000000}; + uint32_t crc32_pbl; + int i; + unsigned char *p = (unsigned char *)&pbl_end_cmd; + + if (ENDIANNESS == 'l') { + for (i = 0; i < 4; i++) + pbl_end_cmd[i] = reverse_byte(pbl_end_cmd[i]); + } + + for (i = 0; i < 16; i++) { + *pmem_buf++ = *p++; + pbl_size++; + } + + /* Add PBI CRC command. */ + *pmem_buf++ = 0x08; + *pmem_buf++ = 0x13; + *pmem_buf++ = 0x80; + *pmem_buf++ = 0x40; + pbl_size += 4; + + /* calculated CRC32 and write it to memory. */ + crc32_pbl = pbl_crc32(0, (const char *)mem_buf, pbl_size); + *pmem_buf++ = (crc32_pbl >> 24) & 0xff; + *pmem_buf++ = (crc32_pbl >> 16) & 0xff; + *pmem_buf++ = (crc32_pbl >> 8) & 0xff; + *pmem_buf++ = (crc32_pbl) & 0xff; + pbl_size += 4; + + if ((pbl_size % 16) != 0) { + for (i = 0; i < 8; i++) { + *pmem_buf++ = 0x0; + pbl_size++; + } + } + if ((pbl_size % 16 != 0)) { + printf("Error: Bad size of image file\n"); + exit(EXIT_FAILURE); + } +} + +void pbl_load_uboot(int ifd, struct mkimage_params *params) +{ + FILE *fp_uboot; + int size; + + /* parse the rcw.cfg file. */ + pbl_parser(params->imagename); + + /* parse the pbi.cfg file. */ + pbl_parser(params->imagename2); + + fp_uboot = fopen(params->datafile, "r"); + if (fp_uboot == NULL) { + printf("Error: %s open failed\n", params->datafile); + exit(EXIT_FAILURE); + } + + load_uboot(fp_uboot); + add_end_cmd(); + fclose(fp_uboot); + lseek(ifd, 0, SEEK_SET); + + size = pbl_size; + if (write(ifd, (const void *)&mem_buf, size) != size) { + fprintf(stderr, "Write error on %s: %s\n", + params->imagefile, strerror(errno)); + exit(EXIT_FAILURE); + } +} + +static int pblimage_check_image_types(uint8_t type) +{ + if (type == IH_TYPE_PBLIMAGE) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; +} + +static int pblimage_verify_header(unsigned char *ptr, int image_size, + struct mkimage_params *params) +{ + struct pbl_header *pbl_hdr = (struct pbl_header *) ptr; + + /* Only a few checks can be done: search for magic numbers */ + if (ENDIANNESS == 'l') { + if (pbl_hdr->preamble != reverse_byte(RCW_PREAMBLE)) + return -FDT_ERR_BADSTRUCTURE; + + if (pbl_hdr->rcwheader != reverse_byte(RCW_HEADER)) + return -FDT_ERR_BADSTRUCTURE; + } else { + if (pbl_hdr->preamble != RCW_PREAMBLE) + return -FDT_ERR_BADSTRUCTURE; + + if (pbl_hdr->rcwheader != RCW_HEADER) + return -FDT_ERR_BADSTRUCTURE; + } + return 0; +} + +static void pblimage_print_header(const void *ptr) +{ + printf("Image Type: Freescale PBL Boot Image\n"); +} + +static void pblimage_set_header(void *ptr, struct stat *sbuf, int ifd, + struct mkimage_params *params) +{ + /*nothing need to do, pbl_load_uboot takes care of whole file. */ +} + +/* pblimage parameters */ +static struct image_type_params pblimage_params = { + .name = "Freescale PBL Boot Image support", + .header_size = sizeof(struct pbl_header), + .hdr = (void *)&pblimage_header, + .check_image_type = pblimage_check_image_types, + .verify_header = pblimage_verify_header, + .print_header = pblimage_print_header, + .set_header = pblimage_set_header, +}; + +void init_pbl_image_type(void) +{ + pbl_size = 0; + mkimage_register(&pblimage_params); +} diff --git a/tools/pblimage.h b/tools/pblimage.h new file mode 100644 index 0000000..514a477 --- /dev/null +++ b/tools/pblimage.h @@ -0,0 +1,36 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef PBLIMAGE_H +#define PBLIMAGE_H + +#define RCW_BYTES 64 +#define RCW_PREAMBLE 0xaa55aa55 +#define RCW_HEADER 0x010e0100 + +struct pbl_header { + uint32_t preamble; + uint32_t rcwheader; + uint8_t rcw_data[RCW_BYTES]; +}; + +#endif /* PBLIMAGE_H */ -- cgit v1.1 From be7bebeac24f33bd7eef2f5047579c1a680d8df1 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 10 Aug 2012 11:07:26 +0000 Subject: powerpc/mpc8xxx: Remove P1015 and P1016 from CPU list P1015 is the same as P1011 and P1016 is the same as P1012 from software point of view. They have different packages but share SVRs. Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/Makefile | 4 ---- arch/powerpc/cpu/mpc85xx/speed.c | 3 +-- arch/powerpc/cpu/mpc8xxx/cpu.c | 2 -- arch/powerpc/include/asm/config_mpc85xx.h | 27 --------------------------- arch/powerpc/include/asm/immap_85xx.h | 3 +-- arch/powerpc/include/asm/processor.h | 2 -- drivers/qe/uec.c | 15 +++++---------- 7 files changed, 7 insertions(+), 49 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile index 34f6c54..2f79a03 100644 --- a/arch/powerpc/cpu/mpc85xx/Makefile +++ b/arch/powerpc/cpu/mpc85xx/Makefile @@ -55,8 +55,6 @@ COBJS-$(CONFIG_P1011) += ddr-gen3.o COBJS-$(CONFIG_P1012) += ddr-gen3.o COBJS-$(CONFIG_P1013) += ddr-gen3.o COBJS-$(CONFIG_P1014) += ddr-gen3.o -COBJS-$(CONFIG_P1015) += ddr-gen3.o -COBJS-$(CONFIG_P1016) += ddr-gen3.o COBJS-$(CONFIG_P1020) += ddr-gen3.o COBJS-$(CONFIG_P1021) += ddr-gen3.o COBJS-$(CONFIG_P1022) += ddr-gen3.o @@ -103,8 +101,6 @@ COBJS-$(CONFIG_P1011) += p1021_serdes.o COBJS-$(CONFIG_P1012) += p1021_serdes.o COBJS-$(CONFIG_P1013) += p1022_serdes.o COBJS-$(CONFIG_P1014) += p1010_serdes.o -COBJS-$(CONFIG_P1015) += p1021_serdes.o -COBJS-$(CONFIG_P1016) += p1021_serdes.o COBJS-$(CONFIG_P1017) += p1023_serdes.o COBJS-$(CONFIG_P1020) += p1021_serdes.o COBJS-$(CONFIG_P1021) += p1021_serdes.o diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c index ce47532..abfeb26 100644 --- a/arch/powerpc/cpu/mpc85xx/speed.c +++ b/arch/powerpc/cpu/mpc85xx/speed.c @@ -186,8 +186,7 @@ void get_sys_info (sys_info_t * sysInfo) #endif #ifdef CONFIG_QE -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) sysInfo->freqQE = sysInfo->freqSystemBus; #else qe_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_QE_RATIO) diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index cbc6742..1c615d0 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -57,8 +57,6 @@ struct cpu_type cpu_type_list [] = { CPU_TYPE_ENTRY(P1012, P1012, 1), CPU_TYPE_ENTRY(P1013, P1013, 1), CPU_TYPE_ENTRY(P1014, P1014, 1), - CPU_TYPE_ENTRY(P1015, P1015, 1), - CPU_TYPE_ENTRY(P1016, P1016, 1), CPU_TYPE_ENTRY(P1017, P1017, 1), CPU_TYPE_ENTRY(P1020, P1020, 2), CPU_TYPE_ENTRY(P1021, P1021, 2), diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 7e61f71..0a780d7 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -191,33 +191,6 @@ #define CONFIG_SYS_FSL_ERRATUM_P1010_A003549 #define CONFIG_SYS_FSL_ERRATUM_IFC_A003399 -/* P1015 is single core version of P1024 */ -#elif defined(CONFIG_P1015) -#define CONFIG_MAX_CPUS 1 -#define CONFIG_SYS_FSL_NUM_LAWS 12 -#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2 -#define CONFIG_TSECV2 -#define CONFIG_FSL_PCIE_DISABLE_ASPM -#define CONFIG_SYS_FSL_SEC_COMPAT 2 -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 -#define CONFIG_SYS_FSL_ERRATUM_ELBC_A001 -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 - -/* P1016 is single core version of P1025 */ -#elif defined(CONFIG_P1016) -#define CONFIG_MAX_CPUS 1 -#define CONFIG_SYS_FSL_NUM_LAWS 12 -#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2 -#define CONFIG_TSECV2 -#define CONFIG_FSL_PCIE_DISABLE_ASPM -#define CONFIG_SYS_FSL_SEC_COMPAT 2 -#define CONFIG_SYS_FSL_ERRATUM_ELBC_A001 -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 -#define QE_MURAM_SIZE 0x6000UL -#define MAX_QE_RISC 1 -#define QE_NUM_OF_SNUM 28 -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 - /* P1017 is single core version of P1023 */ #elif defined(CONFIG_P1017) #define CONFIG_MAX_CPUS 1 diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 91228e7..83f8813 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -2260,8 +2260,7 @@ typedef struct ccsr_gur { u8 res11a[76]; par_io_t qe_par_io[7]; u8 res11b[1600]; -#elif defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#elif defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) u8 res11a[12]; u32 iovselsr; u8 res11b[60]; diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index dc009d6..095b99f 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -1075,8 +1075,6 @@ #define SVR_P1012 0x80E501 #define SVR_P1013 0x80E700 #define SVR_P1014 0x80F101 -#define SVR_P1015 0x80E502 -#define SVR_P1016 0x80E503 #define SVR_P1017 0x80F700 #define SVR_P1020 0x80E400 #define SVR_P1021 0x80E401 diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c index 216c898..e6ae709 100644 --- a/drivers/qe/uec.c +++ b/drivers/qe/uec.c @@ -580,8 +580,7 @@ static void phy_change(struct eth_device *dev) { uec_private_t *uec = (uec_private_t *)dev->priv; -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); /* QE9 and QE12 need to be set for enabling QE MII managment signals */ @@ -592,8 +591,7 @@ static void phy_change(struct eth_device *dev) /* Update the link, speed, duplex */ uec->mii_info->phyinfo->read_status(uec->mii_info); -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) /* * QE12 is muxed with LBCTL, it needs to be released for enabling * LBCTL signal for LBC usage. @@ -1208,16 +1206,14 @@ static int uec_init(struct eth_device* dev, bd_t *bd) uec_private_t *uec; int err, i; struct phy_info *curphy; -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); #endif uec = (uec_private_t *)dev->priv; if (uec->the_first_run == 0) { -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) /* QE9 and QE12 need to be set for enabling QE MII managment signals */ setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_QE9); setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_QE12); @@ -1249,8 +1245,7 @@ static int uec_init(struct eth_device* dev, bd_t *bd) udelay(100000); } while (1); -#if defined(CONFIG_P1012) || defined(CONFIG_P1016) || \ - defined(CONFIG_P1021) || defined(CONFIG_P1025) +#if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025) /* QE12 needs to be released for enabling LBCTL signal*/ clrbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_QE12); #endif -- cgit v1.1 From 9c6b47d53ed329b31c5f26e9ec710f67559c07f0 Mon Sep 17 00:00:00 2001 From: Matthew McClintock Date: Mon, 13 Aug 2012 08:10:37 +0000 Subject: p1014rdb: set ddr bus width properly depending on SVR Currently, for NAND boot for the P1010/4RDB we hard code the DDR configuration. We can still dynamically set the DDR bus width in the nand spl so the P1010/4RDB boards can boot from the same u-boot image Signed-off-by: Matthew McClintock Signed-off-by: Andy Fleming --- arch/powerpc/include/asm/fsl_ddr_sdram.h | 1 + nand_spl/board/freescale/p1010rdb/nand_boot.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/arch/powerpc/include/asm/fsl_ddr_sdram.h b/arch/powerpc/include/asm/fsl_ddr_sdram.h index 93639ba..157ae24 100644 --- a/arch/powerpc/include/asm/fsl_ddr_sdram.h +++ b/arch/powerpc/include/asm/fsl_ddr_sdram.h @@ -88,6 +88,7 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t; #define SDRAM_CFG_SDRAM_TYPE_MASK 0x07000000 #define SDRAM_CFG_SDRAM_TYPE_SHIFT 24 #define SDRAM_CFG_DYN_PWR 0x00200000 +#define SDRAM_CFG_DBW_MASK 0x00180000 #define SDRAM_CFG_32_BE 0x00080000 #define SDRAM_CFG_16_BE 0x00100000 #define SDRAM_CFG_8_BE 0x00040000 diff --git a/nand_spl/board/freescale/p1010rdb/nand_boot.c b/nand_spl/board/freescale/p1010rdb/nand_boot.c index 16eeb61..1f89ab5 100644 --- a/nand_spl/board/freescale/p1010rdb/nand_boot.c +++ b/nand_spl/board/freescale/p1010rdb/nand_boot.c @@ -35,6 +35,7 @@ unsigned long ddr_freq_mhz; void sdram_init(void) { ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR; + u32 svr = mfspr(SPRN_SVR); out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL | SDRAM_CFG_32_BE); out_be32(&ddr->cs0_bnds, CONFIG_SYS_DDR_CS0_BNDS); @@ -70,6 +71,16 @@ void sdram_init(void) out_be32(&ddr->timing_cfg_5, CONFIG_SYS_DDR_TIMING_5); out_be32(&ddr->ddr_zq_cntl, CONFIG_SYS_DDR_ZQ_CONTROL); + /* P1014 and it's derivatives support max 16bit DDR width */ + if (svr == SVR_P1014) { + __raw_writel(ddr->sdram_cfg & ~SDRAM_CFG_DBW_MASK, &ddr->sdram_cfg); + __raw_writel(ddr->sdram_cfg | SDRAM_CFG_16_BE, &ddr->sdram_cfg); + /* For CS0_BNDS we divide the start and end address by 2, so we can just + * shift the entire register to achieve the desired result and the mask + * the value so we don't write reserved fields */ + __raw_writel((CONFIG_SYS_DDR_CS0_BNDS >> 1) & 0x0fff0fff, &ddr->cs0_bnds); + } + /* mimic 500us delay, with busy isync() loop */ udelay(100); -- cgit v1.1 From c8f9802a72030e783152040b07c3c7694f953dd3 Mon Sep 17 00:00:00 2001 From: Matthew McClintock Date: Mon, 13 Aug 2012 08:10:38 +0000 Subject: p1010rdb: fix ddr values for p1014rdb (setting bus width to 16bit) There was an extra 0 in front of the value we were using to mask, remove it to improve the code. Also fix the value written to ddr_sdram_cfg to set the bus width properly to 16 bits Signed-off-by: Matthew McClintock Signed-off-by: Andy Fleming --- board/freescale/p1010rdb/ddr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/board/freescale/p1010rdb/ddr.c b/board/freescale/p1010rdb/ddr.c index 10c5a42..6d00caf 100644 --- a/board/freescale/p1010rdb/ddr.c +++ b/board/freescale/p1010rdb/ddr.c @@ -147,10 +147,11 @@ phys_size_t fixed_sdram(void) cpu = gd->cpu; /* P1014 and it's derivatives support max 16bit DDR width */ if (cpu->soc_ver == SVR_P1014) { + ddr_cfg_regs.ddr_sdram_cfg &= ~SDRAM_CFG_DBW_MASK; ddr_cfg_regs.ddr_sdram_cfg |= SDRAM_CFG_16_BE; - ddr_cfg_regs.cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS >> 1; - ddr_cfg_regs.ddr_sdram_cfg &= ~0x00180000; - ddr_cfg_regs.ddr_sdram_cfg |= 0x001080000; + /* divide SA and EA by two and then mask the rest so we don't + * write to reserved fields */ + ddr_cfg_regs.cs[0].bnds = (CONFIG_SYS_DDR_CS0_BNDS >> 1) & 0x0fff0fff; } ddr_size = (phys_size_t) CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; -- cgit v1.1 From abbe536ebc3ee974593b115de716705f0091344a Mon Sep 17 00:00:00 2001 From: Matthew McClintock Date: Mon, 13 Aug 2012 08:10:39 +0000 Subject: powerpc/p1010rdb: nandboot: compare SVR properly We were not comparing the SVRs properly previously. This comparison will properly shift the SVR and mask off the E bit This fixes the boot output to show the correct DDR bus width: 512 MiB (DDR3, 16-bit, CL=5, ECC off) instead of 512 MiB (DDR3, 32-bit, CL=5, ECC off) Signed-off-by: Matthew McClintock Signed-off-by: Andy Fleming --- nand_spl/board/freescale/p1010rdb/nand_boot.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nand_spl/board/freescale/p1010rdb/nand_boot.c b/nand_spl/board/freescale/p1010rdb/nand_boot.c index 1f89ab5..f5294d0 100644 --- a/nand_spl/board/freescale/p1010rdb/nand_boot.c +++ b/nand_spl/board/freescale/p1010rdb/nand_boot.c @@ -35,7 +35,8 @@ unsigned long ddr_freq_mhz; void sdram_init(void) { ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR; - u32 svr = mfspr(SPRN_SVR); + /* mask off E bit */ + u32 svr = SVR_SOC_VER(mfspr(SPRN_SVR)); out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL | SDRAM_CFG_32_BE); out_be32(&ddr->cs0_bnds, CONFIG_SYS_DDR_CS0_BNDS); -- cgit v1.1 From 8c454047fe9c08a51410dca01b945cdcecb18b7e Mon Sep 17 00:00:00 2001 From: Matthew McClintock Date: Mon, 13 Aug 2012 13:21:19 +0000 Subject: nand_spl: update udelay for Freescale boards Let's use the more appropriate udelay for the nand_spl. While we can't make use of u-boot's full udelay we can atl east use a for loop that won't get optimized away .Since we have the bus clock we can use the timebase to calculate wall time. Looked at reusing the u-boot udelay functions but it pulls in a lot of code and would require quite a bit of work to keep us within the very small space constrains we currently have Signed-off-by: Matthew McClintock Signed-off-by: Andy Fleming --- nand_spl/board/freescale/common.c | 40 +++++++++++++++++++++++ nand_spl/board/freescale/p1010rdb/Makefile | 6 +++- nand_spl/board/freescale/p1010rdb/nand_boot.c | 11 +++---- nand_spl/board/freescale/p1_p2_rdb_pc/Makefile | 6 +++- nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c | 12 +++---- 5 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 nand_spl/board/freescale/common.c diff --git a/nand_spl/board/freescale/common.c b/nand_spl/board/freescale/common.c new file mode 100644 index 0000000..0e099bc --- /dev/null +++ b/nand_spl/board/freescale/common.c @@ -0,0 +1,40 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Author: Matthew McClintock + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_SYS_FSL_TBCLK_DIV +#define CONFIG_SYS_FSL_TBCLK_DIV 8 +#endif + +void udelay(unsigned long usec) +{ + u32 ticks_per_usec = gd->bus_clk / (CONFIG_SYS_FSL_TBCLK_DIV * 1000000); + u32 ticks = ticks_per_usec * usec; + u32 s = mfspr(SPRN_TBRL); + + while ((mfspr(SPRN_TBRL) - s) < ticks); +} diff --git a/nand_spl/board/freescale/p1010rdb/Makefile b/nand_spl/board/freescale/p1010rdb/Makefile index 8d240ea..cdbd492 100644 --- a/nand_spl/board/freescale/p1010rdb/Makefile +++ b/nand_spl/board/freescale/p1010rdb/Makefile @@ -39,7 +39,8 @@ CFLAGS += -DCONFIG_NAND_SPL SOBJS = start.o resetvec.o ticks.o COBJS = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \ - nand_boot.o nand_boot_fsl_ifc.o ns16550.o tlb.o tlb_table.o + nand_boot.o nand_boot_fsl_ifc.o ns16550.o tlb.o tlb_table.o \ + ../common.o SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) @@ -123,6 +124,9 @@ ifneq ($(OBJTREE), $(SRCTREE)) $(obj)nand_boot.c: @rm -f $(obj)nand_boot.c ln -s $(SRCTREE)/nand_spl/board/$(BOARDDIR)/nand_boot.c $(obj)nand_boot.c +$(obj)../common.c: + @rm -f $(obj)../common.c + ln -s $(SRCTREE)/nand_spl/board/freescale/common.c $(obj)../common.c endif ######################################################################### diff --git a/nand_spl/board/freescale/p1010rdb/nand_boot.c b/nand_spl/board/freescale/p1010rdb/nand_boot.c index f5294d0..a075509 100644 --- a/nand_spl/board/freescale/p1010rdb/nand_boot.c +++ b/nand_spl/board/freescale/p1010rdb/nand_boot.c @@ -27,8 +27,9 @@ #include #include #include +#include -#define udelay(x) { int j; for (j = 0; j < x * 10000; j++) isync(); } +DECLARE_GLOBAL_DATA_PTR; unsigned long ddr_freq_mhz; @@ -82,8 +83,7 @@ void sdram_init(void) __raw_writel((CONFIG_SYS_DDR_CS0_BNDS >> 1) & 0x0fff0fff, &ddr->cs0_bnds); } - /* mimic 500us delay, with busy isync() loop */ - udelay(100); + udelay(500); /* Let the controller go */ out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN); @@ -94,20 +94,19 @@ void sdram_init(void) void board_init_f(ulong bootflag) { u32 plat_ratio, ddr_ratio; - unsigned long bus_clk; ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; /* initialize selected port with appropriate baud rate */ plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; plat_ratio >>= 1; - bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; + gd->bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; ddr_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO; ddr_ratio = ddr_ratio >> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT; ddr_freq_mhz = (CONFIG_SYS_CLK_FREQ * ddr_ratio) / 0x1000000; NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, - bus_clk / 16 / CONFIG_BAUDRATE); + gd->bus_clk / 16 / CONFIG_BAUDRATE); puts("\nNAND boot... "); diff --git a/nand_spl/board/freescale/p1_p2_rdb_pc/Makefile b/nand_spl/board/freescale/p1_p2_rdb_pc/Makefile index 475cc49..46cf709 100644 --- a/nand_spl/board/freescale/p1_p2_rdb_pc/Makefile +++ b/nand_spl/board/freescale/p1_p2_rdb_pc/Makefile @@ -39,7 +39,8 @@ CFLAGS += -DCONFIG_NAND_SPL SOBJS = start.o resetvec.o COBJS = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \ - nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o + nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o \ + ../common.o SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) @@ -119,6 +120,9 @@ ifneq ($(OBJTREE), $(SRCTREE)) $(obj)nand_boot.c: @rm -f $(obj)nand_boot.c ln -s $(SRCTREE)/nand_spl/board/$(BOARDDIR)/nand_boot.c $(obj)nand_boot.c +$(obj)../common.c: + @rm -f $(obj)../common.c + ln -s $(SRCTREE)/nand_spl/board/freescale/common.c $(obj)../common.c endif ######################################################################### diff --git a/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c b/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c index b9796ea..fcff382 100644 --- a/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c +++ b/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c @@ -25,11 +25,9 @@ #include #include #include +#include -#define udelay(x) {int i, j; \ - for (i = 0; i < x; i++) \ - for (j = 0; j < 10000; j++) \ - ; } +DECLARE_GLOBAL_DATA_PTR; /* * Fixed sdram init -- doesn't use serial presence detect. @@ -76,7 +74,7 @@ void sdram_init(void) void board_init_f(ulong bootflag) { - u32 plat_ratio, bus_clk; + u32 plat_ratio; ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; #ifndef CONFIG_QE ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); @@ -85,10 +83,10 @@ void board_init_f(ulong bootflag) /* initialize selected port with appropriate baud rate */ plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; plat_ratio >>= 1; - bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; + gd->bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, - bus_clk / 16 / CONFIG_BAUDRATE); + gd->bus_clk / 16 / CONFIG_BAUDRATE); puts("\nNAND boot... "); -- cgit v1.1 From 02ea538ce9fa8325f7d15c69cf87c950c5fe1f57 Mon Sep 17 00:00:00 2001 From: Matthew McClintock Date: Mon, 13 Aug 2012 10:00:40 +0000 Subject: nand_spl: p1023rds: wait before enabling DDR controller We have a requirement to wait a period of time before enabling the DDR controller Signed-off-by: Matthew McClintock Signed-off-by: Andy Fleming --- nand_spl/board/freescale/p1023rds/Makefile | 6 +++++- nand_spl/board/freescale/p1023rds/nand_boot.c | 19 +++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/nand_spl/board/freescale/p1023rds/Makefile b/nand_spl/board/freescale/p1023rds/Makefile index 168e868..da43521 100644 --- a/nand_spl/board/freescale/p1023rds/Makefile +++ b/nand_spl/board/freescale/p1023rds/Makefile @@ -34,7 +34,8 @@ CFLAGS += -DCONFIG_NAND_SPL SOBJS = start.o resetvec.o COBJS = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \ - nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o + nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o \ + ../common.o SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) @@ -114,6 +115,9 @@ ifneq ($(OBJTREE), $(SRCTREE)) $(obj)nand_boot.c: @rm -f $(obj)nand_boot.c ln -s $(SRCTREE)/nand_spl/board/$(BOARDDIR)/nand_boot.c $(obj)nand_boot.c +$(obj)../common.c: + @rm -f $(obj)../common.c + ln -s $(SRCTREE)/nand_spl/board/freescale/common.c $(obj)../common.c endif ######################################################################### diff --git a/nand_spl/board/freescale/p1023rds/nand_boot.c b/nand_spl/board/freescale/p1023rds/nand_boot.c index 0065c87..6ab1f50 100644 --- a/nand_spl/board/freescale/p1023rds/nand_boot.c +++ b/nand_spl/board/freescale/p1023rds/nand_boot.c @@ -25,6 +25,10 @@ #include #include #include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; /* Fixed sdram init -- doesn't use serial presence detect. */ void sdram_init(void) @@ -53,20 +57,27 @@ void sdram_init(void) out_be32(&ddr->ddr_wrlvl_cntl, CONFIG_SYS_DDR_WRLVL_CNTL); out_be32(&ddr->ddr_cdr1, CONFIG_SYS_DDR_CDR_1); out_be32(&ddr->ddr_cdr2, CONFIG_SYS_DDR_CDR_2); - out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL); + /* Set, but do not enable the memory */ + out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN); + + asm volatile("sync;isync"); + udelay(500); + + /* Let the controller go */ + out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN); } void board_init_f(ulong bootflag) { - u32 plat_ratio, bus_clk; + u32 plat_ratio; ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; /* initialize selected port with appropriate baud rate */ plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; plat_ratio >>= 1; - bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; + gd->bus_clk = CONFIG_SYS_CLK_FREQ * plat_ratio; NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, - bus_clk / 16 / CONFIG_BAUDRATE); + gd->bus_clk / 16 / CONFIG_BAUDRATE); puts("\nNAND boot... "); /* Initialize the DDR3 */ -- cgit v1.1 From ae6beb24d7589f1b8b7aa3519afb3c7cdf8e66e5 Mon Sep 17 00:00:00 2001 From: Matthew McClintock Date: Mon, 13 Aug 2012 08:10:42 +0000 Subject: nand_spl: change out_be32 to raw_writel and depend on subsequent sync This change reduces the SPL size by removing the redundant syncs produced by out_be32 and just replies on one final sync Done with: sed -r '/in_be32/b; s/(out_be32)\(([^,]*),\s+(.*)\)/__raw_writel(\3, \2)/g' -i `git grep --name-only sdram_init nand_spl/` Signed-off-by: Matthew McClintock Acked-by: Scott Wood Signed-off-by: Andy Fleming --- nand_spl/board/freescale/p1010rdb/nand_boot.c | 54 +++++++++++------------ nand_spl/board/freescale/p1023rds/nand_boot.c | 42 +++++++++--------- nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c | 48 ++++++++++---------- 3 files changed, 71 insertions(+), 73 deletions(-) diff --git a/nand_spl/board/freescale/p1010rdb/nand_boot.c b/nand_spl/board/freescale/p1010rdb/nand_boot.c index a075509..9c35690 100644 --- a/nand_spl/board/freescale/p1010rdb/nand_boot.c +++ b/nand_spl/board/freescale/p1010rdb/nand_boot.c @@ -39,39 +39,37 @@ void sdram_init(void) /* mask off E bit */ u32 svr = SVR_SOC_VER(mfspr(SPRN_SVR)); - out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL | SDRAM_CFG_32_BE); - out_be32(&ddr->cs0_bnds, CONFIG_SYS_DDR_CS0_BNDS); - out_be32(&ddr->cs0_config, CONFIG_SYS_DDR_CS0_CONFIG); - out_be32(&ddr->sdram_cfg_2, CONFIG_SYS_DDR_CONTROL_2); - out_be32(&ddr->sdram_data_init, CONFIG_SYS_DDR_DATA_INIT); + __raw_writel(CONFIG_SYS_DDR_CONTROL | SDRAM_CFG_32_BE, &ddr->sdram_cfg); + __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds); + __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config); + __raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2); + __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init); if (ddr_freq_mhz < 700) { - out_be32(&ddr->timing_cfg_3, CONFIG_SYS_DDR_TIMING_3_667); - out_be32(&ddr->timing_cfg_0, CONFIG_SYS_DDR_TIMING_0_667); - out_be32(&ddr->timing_cfg_1, CONFIG_SYS_DDR_TIMING_1_667); - out_be32(&ddr->timing_cfg_2, CONFIG_SYS_DDR_TIMING_2_667); - out_be32(&ddr->sdram_mode, CONFIG_SYS_DDR_MODE_1_667); - out_be32(&ddr->sdram_mode_2, CONFIG_SYS_DDR_MODE_2_667); - out_be32(&ddr->sdram_interval, CONFIG_SYS_DDR_INTERVAL_667); - out_be32(&ddr->sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CTRL_667); - out_be32(&ddr->ddr_wrlvl_cntl, - CONFIG_SYS_DDR_WRLVL_CONTROL_667); + __raw_writel(CONFIG_SYS_DDR_TIMING_3_667, &ddr->timing_cfg_3); + __raw_writel(CONFIG_SYS_DDR_TIMING_0_667, &ddr->timing_cfg_0); + __raw_writel(CONFIG_SYS_DDR_TIMING_1_667, &ddr->timing_cfg_1); + __raw_writel(CONFIG_SYS_DDR_TIMING_2_667, &ddr->timing_cfg_2); + __raw_writel(CONFIG_SYS_DDR_MODE_1_667, &ddr->sdram_mode); + __raw_writel(CONFIG_SYS_DDR_MODE_2_667, &ddr->sdram_mode_2); + __raw_writel(CONFIG_SYS_DDR_INTERVAL_667, &ddr->sdram_interval); + __raw_writel(CONFIG_SYS_DDR_CLK_CTRL_667, &ddr->sdram_clk_cntl); + __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_667, &ddr->ddr_wrlvl_cntl); } else { - out_be32(&ddr->timing_cfg_3, CONFIG_SYS_DDR_TIMING_3_800); - out_be32(&ddr->timing_cfg_0, CONFIG_SYS_DDR_TIMING_0_800); - out_be32(&ddr->timing_cfg_1, CONFIG_SYS_DDR_TIMING_1_800); - out_be32(&ddr->timing_cfg_2, CONFIG_SYS_DDR_TIMING_2_800); - out_be32(&ddr->sdram_mode, CONFIG_SYS_DDR_MODE_1_800); - out_be32(&ddr->sdram_mode_2, CONFIG_SYS_DDR_MODE_2_800); - out_be32(&ddr->sdram_interval, CONFIG_SYS_DDR_INTERVAL_800); - out_be32(&ddr->sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CTRL_800); - out_be32(&ddr->ddr_wrlvl_cntl, - CONFIG_SYS_DDR_WRLVL_CONTROL_800); + __raw_writel(CONFIG_SYS_DDR_TIMING_3_800, &ddr->timing_cfg_3); + __raw_writel(CONFIG_SYS_DDR_TIMING_0_800, &ddr->timing_cfg_0); + __raw_writel(CONFIG_SYS_DDR_TIMING_1_800, &ddr->timing_cfg_1); + __raw_writel(CONFIG_SYS_DDR_TIMING_2_800, &ddr->timing_cfg_2); + __raw_writel(CONFIG_SYS_DDR_MODE_1_800, &ddr->sdram_mode); + __raw_writel(CONFIG_SYS_DDR_MODE_2_800, &ddr->sdram_mode_2); + __raw_writel(CONFIG_SYS_DDR_INTERVAL_800, &ddr->sdram_interval); + __raw_writel(CONFIG_SYS_DDR_CLK_CTRL_800, &ddr->sdram_clk_cntl); + __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL_800, &ddr->ddr_wrlvl_cntl); } - out_be32(&ddr->timing_cfg_4, CONFIG_SYS_DDR_TIMING_4); - out_be32(&ddr->timing_cfg_5, CONFIG_SYS_DDR_TIMING_5); - out_be32(&ddr->ddr_zq_cntl, CONFIG_SYS_DDR_ZQ_CONTROL); + __raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4); + __raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5); + __raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl); /* P1014 and it's derivatives support max 16bit DDR width */ if (svr == SVR_P1014) { diff --git a/nand_spl/board/freescale/p1023rds/nand_boot.c b/nand_spl/board/freescale/p1023rds/nand_boot.c index 6ab1f50..89e339d 100644 --- a/nand_spl/board/freescale/p1023rds/nand_boot.c +++ b/nand_spl/board/freescale/p1023rds/nand_boot.c @@ -37,28 +37,28 @@ void sdram_init(void) set_next_law(0, LAW_SIZE_2G, LAW_TRGT_IF_DDR_1); - out_be32(&ddr->cs0_bnds, CONFIG_SYS_DDR_CS0_BNDS); - out_be32(&ddr->cs0_config, CONFIG_SYS_DDR_CS0_CONFIG); - out_be32(&ddr->cs1_bnds, CONFIG_SYS_DDR_CS1_BNDS); - out_be32(&ddr->cs1_config, CONFIG_SYS_DDR_CS1_CONFIG); - out_be32(&ddr->timing_cfg_3, CONFIG_SYS_DDR_TIMING_3); - out_be32(&ddr->timing_cfg_0, CONFIG_SYS_DDR_TIMING_0); - out_be32(&ddr->timing_cfg_1, CONFIG_SYS_DDR_TIMING_1); - out_be32(&ddr->timing_cfg_2, CONFIG_SYS_DDR_TIMING_2); - out_be32(&ddr->sdram_cfg_2, CONFIG_SYS_DDR_CONTROL2); - out_be32(&ddr->sdram_mode, CONFIG_SYS_DDR_MODE_1); - out_be32(&ddr->sdram_mode_2, CONFIG_SYS_DDR_MODE_2); - out_be32(&ddr->sdram_interval, CONFIG_SYS_DDR_INTERVAL); - out_be32(&ddr->sdram_data_init, CONFIG_SYS_DDR_DATA_INIT); - out_be32(&ddr->sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CTRL); - out_be32(&ddr->timing_cfg_4, CONFIG_SYS_DDR_TIMING_4); - out_be32(&ddr->timing_cfg_5, CONFIG_SYS_DDR_TIMING_5); - out_be32(&ddr->ddr_zq_cntl, CONFIG_SYS_DDR_ZQ_CNTL); - out_be32(&ddr->ddr_wrlvl_cntl, CONFIG_SYS_DDR_WRLVL_CNTL); - out_be32(&ddr->ddr_cdr1, CONFIG_SYS_DDR_CDR_1); - out_be32(&ddr->ddr_cdr2, CONFIG_SYS_DDR_CDR_2); + __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds); + __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config); + __raw_writel(CONFIG_SYS_DDR_CS1_BNDS, &ddr->cs1_bnds); + __raw_writel(CONFIG_SYS_DDR_CS1_CONFIG, &ddr->cs1_config); + __raw_writel(CONFIG_SYS_DDR_TIMING_3, &ddr->timing_cfg_3); + __raw_writel(CONFIG_SYS_DDR_TIMING_0, &ddr->timing_cfg_0); + __raw_writel(CONFIG_SYS_DDR_TIMING_1, &ddr->timing_cfg_1); + __raw_writel(CONFIG_SYS_DDR_TIMING_2, &ddr->timing_cfg_2); + __raw_writel(CONFIG_SYS_DDR_CONTROL2, &ddr->sdram_cfg_2); + __raw_writel(CONFIG_SYS_DDR_MODE_1, &ddr->sdram_mode); + __raw_writel(CONFIG_SYS_DDR_MODE_2, &ddr->sdram_mode_2); + __raw_writel(CONFIG_SYS_DDR_INTERVAL, &ddr->sdram_interval); + __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init); + __raw_writel(CONFIG_SYS_DDR_CLK_CTRL, &ddr->sdram_clk_cntl); + __raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4); + __raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5); + __raw_writel(CONFIG_SYS_DDR_ZQ_CNTL, &ddr->ddr_zq_cntl); + __raw_writel(CONFIG_SYS_DDR_WRLVL_CNTL, &ddr->ddr_wrlvl_cntl); + __raw_writel(CONFIG_SYS_DDR_CDR_1, &ddr->ddr_cdr1); + __raw_writel(CONFIG_SYS_DDR_CDR_2, &ddr->ddr_cdr2); /* Set, but do not enable the memory */ - out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN); + __raw_writel(CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN, &ddr->sdram_cfg); asm volatile("sync;isync"); udelay(500); diff --git a/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c b/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c index fcff382..4c140c1 100644 --- a/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c +++ b/nand_spl/board/freescale/p1_p2_rdb_pc/nand_boot.c @@ -36,32 +36,32 @@ void sdram_init(void) { ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC85xx_DDR_ADDR; - out_be32(&ddr->cs0_bnds, CONFIG_SYS_DDR_CS0_BNDS); - out_be32(&ddr->cs0_config, CONFIG_SYS_DDR_CS0_CONFIG); + __raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds); + __raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config); #if CONFIG_CHIP_SELECTS_PER_CTRL > 1 - out_be32(&ddr->cs1_bnds, CONFIG_SYS_DDR_CS1_BNDS); - out_be32(&ddr->cs1_config, CONFIG_SYS_DDR_CS1_CONFIG); + __raw_writel(CONFIG_SYS_DDR_CS1_BNDS, &ddr->cs1_bnds); + __raw_writel(CONFIG_SYS_DDR_CS1_CONFIG, &ddr->cs1_config); #endif - out_be32(&ddr->timing_cfg_3, CONFIG_SYS_DDR_TIMING_3); - out_be32(&ddr->timing_cfg_0, CONFIG_SYS_DDR_TIMING_0); - out_be32(&ddr->timing_cfg_1, CONFIG_SYS_DDR_TIMING_1); - out_be32(&ddr->timing_cfg_2, CONFIG_SYS_DDR_TIMING_2); + __raw_writel(CONFIG_SYS_DDR_TIMING_3, &ddr->timing_cfg_3); + __raw_writel(CONFIG_SYS_DDR_TIMING_0, &ddr->timing_cfg_0); + __raw_writel(CONFIG_SYS_DDR_TIMING_1, &ddr->timing_cfg_1); + __raw_writel(CONFIG_SYS_DDR_TIMING_2, &ddr->timing_cfg_2); - out_be32(&ddr->sdram_cfg_2, CONFIG_SYS_DDR_CONTROL_2); - out_be32(&ddr->sdram_mode, CONFIG_SYS_DDR_MODE_1); - out_be32(&ddr->sdram_mode_2, CONFIG_SYS_DDR_MODE_2); + __raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2); + __raw_writel(CONFIG_SYS_DDR_MODE_1, &ddr->sdram_mode); + __raw_writel(CONFIG_SYS_DDR_MODE_2, &ddr->sdram_mode_2); - out_be32(&ddr->sdram_interval, CONFIG_SYS_DDR_INTERVAL); - out_be32(&ddr->sdram_data_init, CONFIG_SYS_DDR_DATA_INIT); - out_be32(&ddr->sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CTRL); + __raw_writel(CONFIG_SYS_DDR_INTERVAL, &ddr->sdram_interval); + __raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init); + __raw_writel(CONFIG_SYS_DDR_CLK_CTRL, &ddr->sdram_clk_cntl); - out_be32(&ddr->timing_cfg_4, CONFIG_SYS_DDR_TIMING_4); - out_be32(&ddr->timing_cfg_5, CONFIG_SYS_DDR_TIMING_5); - out_be32(&ddr->ddr_zq_cntl, CONFIG_SYS_DDR_ZQ_CONTROL); - out_be32(&ddr->ddr_wrlvl_cntl, CONFIG_SYS_DDR_WRLVL_CONTROL); + __raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4); + __raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5); + __raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl); + __raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL, &ddr->ddr_wrlvl_cntl); /* Set, but do not enable the memory */ - out_be32(&ddr->sdram_cfg, CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN); + __raw_writel(CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN, &ddr->sdram_cfg); asm volatile("sync;isync"); udelay(500); @@ -92,13 +92,13 @@ void board_init_f(ulong bootflag) #ifndef CONFIG_QE /* init DDR3 reset signal */ - out_be32(&pgpio->gpdir, 0x02000000); - out_be32(&pgpio->gpodr, 0x00200000); - out_be32(&pgpio->gpdat, 0x00000000); + __raw_writel(0x02000000, &pgpio->gpdir); + __raw_writel(0x00200000, &pgpio->gpodr); + __raw_writel(0x00000000, &pgpio->gpdat); udelay(1000); - out_be32(&pgpio->gpdat, 0x00200000); + __raw_writel(0x00200000, &pgpio->gpdat); udelay(1000); - out_be32(&pgpio->gpdir, 0x00000000); + __raw_writel(0x00000000, &pgpio->gpdir); #endif /* Initialize the DDR3 */ -- cgit v1.1 From a2af6a7a84c32ee3c1500000d2a0238052a4f5e1 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 13 Aug 2012 13:48:57 +0000 Subject: mpc85xx: use LCRR_DBYP define instead of raw constant Using the raw value of 0x80000000 directly in the code can lead to "count the zeros" bugs like that fixed in commit 718e9d13b98 ("MPC85xxCDS: Fix missing LCRR_DBYP bits for 66-133MHz LBC") Change all existing raw values to use the symbolic value of LCRR_DBYP instead. Cc: Kumar Gala Cc: Scott Wood Signed-off-by: Paul Gortmaker Signed-off-by: Andy Fleming --- board/freescale/mpc8540ads/mpc8540ads.c | 6 +++--- board/freescale/mpc8541cds/mpc8541cds.c | 6 +++--- board/freescale/mpc8555cds/mpc8555cds.c | 6 +++--- board/freescale/mpc8560ads/mpc8560ads.c | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/board/freescale/mpc8540ads/mpc8540ads.c b/board/freescale/mpc8540ads/mpc8540ads.c index c75585e..a275d3a 100644 --- a/board/freescale/mpc8540ads/mpc8540ads.c +++ b/board/freescale/mpc8540ads/mpc8540ads.c @@ -87,10 +87,10 @@ local_bus_init(void) lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { - lbc->lcrr = CONFIG_SYS_LBC_LCRR | 0x80000000; /* DLL Bypass */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR | LCRR_DBYP; /* DLL Bypass */ } else if (lbc_hz >= 133) { - lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~0x80000000); /* DLL Enabled */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */ } else { /* @@ -105,7 +105,7 @@ local_bus_init(void) lbc->lcrr = 0x10000004; } - lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~0x80000000); /* DLL Enabled */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */ udelay(200); /* diff --git a/board/freescale/mpc8541cds/mpc8541cds.c b/board/freescale/mpc8541cds/mpc8541cds.c index 532d32a..13ca84b 100644 --- a/board/freescale/mpc8541cds/mpc8541cds.c +++ b/board/freescale/mpc8541cds/mpc8541cds.c @@ -269,13 +269,13 @@ local_bus_init(void) lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { - lbc->lcrr |= 0x80000000; /* DLL Bypass */ + lbc->lcrr |= LCRR_DBYP; /* DLL Bypass */ } else if (lbc_hz >= 133) { - lbc->lcrr &= (~0x80000000); /* DLL Enabled */ + lbc->lcrr &= (~LCRR_DBYP); /* DLL Enabled */ } else { - lbc->lcrr &= (~0x80000000); /* DLL Enabled */ + lbc->lcrr &= (~LCRR_DBYP); /* DLL Enabled */ udelay(200); /* diff --git a/board/freescale/mpc8555cds/mpc8555cds.c b/board/freescale/mpc8555cds/mpc8555cds.c index 3361614..4cfd61c 100644 --- a/board/freescale/mpc8555cds/mpc8555cds.c +++ b/board/freescale/mpc8555cds/mpc8555cds.c @@ -267,13 +267,13 @@ local_bus_init(void) lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { - lbc->lcrr |= 0x80000000; /* DLL Bypass */ + lbc->lcrr |= LCRR_DBYP; /* DLL Bypass */ } else if (lbc_hz >= 133) { - lbc->lcrr &= (~0x80000000); /* DLL Enabled */ + lbc->lcrr &= (~LCRR_DBYP); /* DLL Enabled */ } else { - lbc->lcrr &= (~0x80000000); /* DLL Enabled */ + lbc->lcrr &= (~LCRR_DBYP); /* DLL Enabled */ udelay(200); /* diff --git a/board/freescale/mpc8560ads/mpc8560ads.c b/board/freescale/mpc8560ads/mpc8560ads.c index 1a165bf..285edbc 100644 --- a/board/freescale/mpc8560ads/mpc8560ads.c +++ b/board/freescale/mpc8560ads/mpc8560ads.c @@ -292,10 +292,10 @@ local_bus_init(void) lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv; if (lbc_hz < 66) { - lbc->lcrr = CONFIG_SYS_LBC_LCRR | 0x80000000; /* DLL Bypass */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR | LCRR_DBYP; /* DLL Bypass */ } else if (lbc_hz >= 133) { - lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~0x80000000); /* DLL Enabled */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */ } else { /* @@ -310,7 +310,7 @@ local_bus_init(void) lbc->lcrr = 0x10000004; } - lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~0x80000000);/* DLL Enabled */ + lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP);/* DLL Enabled */ udelay(200); /* -- cgit v1.1 From 99abf7ded3b8daf82bdf1a60d1a92cb76c482c9a Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 14 Aug 2012 06:47:21 +0000 Subject: powerpc/85xx: add support for FM2 DTSEC5 Unlike previous SOCs, the Freescale P5040 has a fifth DTSEC on the second Fman, so add the Fman and SerDes macros for that DTSEC. Signed-off-by: Timur Tabi Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c | 6 ++++++ arch/powerpc/include/asm/fsl_serdes.h | 1 + arch/powerpc/include/asm/immap_85xx.h | 1 + drivers/net/fm/init.c | 3 +++ include/fm_eth.h | 1 + 5 files changed, 12 insertions(+) diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index 4b52dad..8aac1de 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -68,6 +68,7 @@ static const char *serdes_prtcl_str[] = { [SGMII_FM2_DTSEC2] = "SGMII_FM2_DTSEC2", [SGMII_FM2_DTSEC3] = "SGMII_FM2_DTSEC3", [SGMII_FM2_DTSEC4] = "SGMII_FM2_DTSEC4", + [SGMII_FM2_DTSEC5] = "SGMII_FM2_DTSEC5", [XAUI_FM1] = "XAUI_FM1", [XAUI_FM2] = "XAUI_FM2", [AURORA] = "DEBUG", @@ -658,6 +659,7 @@ void fsl_serdes_init(void) case SGMII_FM2_DTSEC2: case SGMII_FM2_DTSEC3: case SGMII_FM2_DTSEC4: + case SGMII_FM2_DTSEC5: case XAUI_FM1: case XAUI_FM2: case SRIO1: @@ -717,6 +719,10 @@ void fsl_serdes_init(void) serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 | FSL_CORENET_DEVDISR2_DTSEC2_4; break; + case SGMII_FM2_DTSEC5: + serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 | + FSL_CORENET_DEVDISR2_DTSEC2_5; + break; case XAUI_FM1: serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 | FSL_CORENET_DEVDISR2_10GEC1; diff --git a/arch/powerpc/include/asm/fsl_serdes.h b/arch/powerpc/include/asm/fsl_serdes.h index 0f31af1..22525f1 100644 --- a/arch/powerpc/include/asm/fsl_serdes.h +++ b/arch/powerpc/include/asm/fsl_serdes.h @@ -41,6 +41,7 @@ enum srds_prtcl { SGMII_FM2_DTSEC2, SGMII_FM2_DTSEC3, SGMII_FM2_DTSEC4, + SGMII_FM2_DTSEC5, SGMII_TSEC1, SGMII_TSEC2, SGMII_TSEC3, diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 83f8813..9bdfd97 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -1729,6 +1729,7 @@ typedef struct ccsr_gur { #define FSL_CORENET_DEVDISR2_DTSEC2_2 0x00004000 #define FSL_CORENET_DEVDISR2_DTSEC2_3 0x00002000 #define FSL_CORENET_DEVDISR2_DTSEC2_4 0x00001000 +#define FSL_CORENET_DEVDISR2_DTSEC2_5 0x00000800 #define FSL_CORENET_NUM_DEVDISR 2 u8 res7[8]; u32 powmgtcsr; /* Power management status & control */ diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index 953c359..9834cd9 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -50,6 +50,9 @@ struct fm_eth_info fm_info[] = { #if (CONFIG_SYS_NUM_FM2_DTSEC >= 4) FM_DTSEC_INFO_INITIALIZER(2, 4), #endif +#if (CONFIG_SYS_NUM_FM2_DTSEC >= 5) + FM_DTSEC_INFO_INITIALIZER(2, 5), +#endif #if (CONFIG_SYS_NUM_FM1_10GEC >= 1) FM_TGEC_INFO_INITIALIZER(1, 1), #endif diff --git a/include/fm_eth.h b/include/fm_eth.h index c7c6882..05121ea 100644 --- a/include/fm_eth.h +++ b/include/fm_eth.h @@ -35,6 +35,7 @@ enum fm_port { FM2_DTSEC2, FM2_DTSEC3, FM2_DTSEC4, + FM2_DTSEC5, FM2_10GEC1, NUM_FM_PORTS, }; -- cgit v1.1 From ae2291fbe0f9858d332423a97c6b09157005050f Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 14 Aug 2012 06:47:22 +0000 Subject: fm-eth: add function fm_info_get_phy_address() Function fm_info_get_phy_address() returns the PHY address for a given Fman port. This is handy when the MDIO code needs to fixup the Ethernet nodes in the device tree to point to PHY nodes for a specific PHY address. Signed-off-by: Timur Tabi Signed-off-by: Andy Fleming --- drivers/net/fm/init.c | 16 ++++++++++++++++ include/fm_eth.h | 1 + 2 files changed, 17 insertions(+) diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index 9834cd9..8a5311c 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -155,6 +155,22 @@ void fm_info_set_phy_address(enum fm_port port, int address) } /* + * Returns the PHY address for a given Fman port + * + * The port must be set via a prior call to fm_info_set_phy_address(). + * A negative error code is returned if the port is invalid. + */ +int fm_info_get_phy_address(enum fm_port port) +{ + int i = fm_port_to_index(port); + + if (i == -1) + return -1; + + return fm_info[i].phy_addr; +} + +/* * Returns the type of the data interface between the given MAC and its PHY. * This is typically determined by the RCW. */ diff --git a/include/fm_eth.h b/include/fm_eth.h index 05121ea..e56541d 100644 --- a/include/fm_eth.h +++ b/include/fm_eth.h @@ -110,6 +110,7 @@ void fman_enet_init(void); void fdt_fixup_fman_ethernet(void *fdt); phy_interface_t fm_info_get_enet_if(enum fm_port port); void fm_info_set_phy_address(enum fm_port port, int address); +int fm_info_get_phy_address(enum fm_port port); void fm_info_set_mdio(enum fm_port port, struct mii_dev *bus); void fm_disable_port(enum fm_port port); -- cgit v1.1 From 45b092d3010caa8d9a1f8c4f89afcbb6c5e5bee6 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 14 Aug 2012 06:47:23 +0000 Subject: powerpc/85xx: introduce function serdes_device_from_fm_port() In order to figure out which SerDes lane a given Fman port is connected to, we need a function that maps the fm_port namespace to the srds_prtcl namespace. Signed-off-by: Timur Tabi Signed-off-by: Andy Fleming --- board/freescale/common/fman.c | 31 +++++++++++++++++++++++++++++++ board/freescale/common/fman.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/board/freescale/common/fman.c b/board/freescale/common/fman.c index 6ddf816..3ef4936 100644 --- a/board/freescale/common/fman.c +++ b/board/freescale/common/fman.c @@ -25,6 +25,9 @@ #include #include +#include +#include + /* * Given the following ... * @@ -67,3 +70,31 @@ int fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr, return fdt_setprop(fdt, offset, "phy-handle", &ph, sizeof(ph)); } + +/* + * Return the SerDes device enum for a given Fman port + * + * This function just maps the fm_port namespace to the srds_prtcl namespace. + */ +enum srds_prtcl serdes_device_from_fm_port(enum fm_port port) +{ + static const enum srds_prtcl srds_table[] = { + [FM1_DTSEC1] = SGMII_FM1_DTSEC1, + [FM1_DTSEC2] = SGMII_FM1_DTSEC2, + [FM1_DTSEC3] = SGMII_FM1_DTSEC3, + [FM1_DTSEC4] = SGMII_FM1_DTSEC4, + [FM1_DTSEC5] = SGMII_FM1_DTSEC5, + [FM1_10GEC1] = XAUI_FM1, + [FM2_DTSEC1] = SGMII_FM2_DTSEC1, + [FM2_DTSEC2] = SGMII_FM2_DTSEC2, + [FM2_DTSEC3] = SGMII_FM2_DTSEC3, + [FM2_DTSEC4] = SGMII_FM2_DTSEC4, + [FM2_DTSEC5] = SGMII_FM2_DTSEC5, + [FM2_10GEC1] = XAUI_FM2, + }; + + if ((port < FM1_DTSEC1) || (port > FM2_10GEC1)) + return NONE; + else + return srds_table[port]; +} diff --git a/board/freescale/common/fman.h b/board/freescale/common/fman.h index d39ef08..734b1da 100644 --- a/board/freescale/common/fman.h +++ b/board/freescale/common/fman.h @@ -23,4 +23,6 @@ int fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr, const char *alias); +enum srds_prtcl serdes_device_from_fm_port(enum fm_port port); + #endif -- cgit v1.1 From 4376b4c00e7ff81d950410a5fffe1e4c495e42d3 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 14 Aug 2012 06:47:24 +0000 Subject: fm-eth: use fdt_status_disabled() function in ft_fixup_port() We have a dedicated function for setting the node status now, so use it. Also improve a comment and fix the type of the phandle variable. Signed-off-by: Timur Tabi Signed-off-by: Andy Fleming --- drivers/net/fm/init.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index 8a5311c..736b8b9 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -200,7 +200,8 @@ void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) { - int off, ph; + int off; + uint32_t ph; phys_addr_t paddr = CONFIG_SYS_CCSRBAR_PHYS + info->compat_offset; u64 dtsec1_addr = (u64)CONFIG_SYS_CCSRBAR_PHYS + CONFIG_SYS_FSL_FM1_DTSEC1_OFFSET; @@ -217,12 +218,10 @@ static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) off = fdt_node_offset_by_compat_reg(blob, prop, paddr); /* Don't disable FM1-DTSEC1 MAC as its used for MDIO */ - if (paddr != dtsec1_addr) { - /* disable the mac node */ - fdt_setprop_string(blob, off, "status", "disabled"); - } + if (paddr != dtsec1_addr) + fdt_status_disabled(blob, off); /* disable the MAC node */ - /* disable the node point to the mac */ + /* disable the fsl,dpa-ethernet node that points to the MAC */ ph = fdt_get_phandle(blob, off); do_fixup_by_prop(blob, "fsl,fman-mac", &ph, sizeof(ph), "status", "disabled", strlen("disabled") + 1, 1); -- cgit v1.1 From 61fc52b660cba005cb73df2c546293f3ba608409 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 14 Aug 2012 06:47:25 +0000 Subject: powerpc/85xx: get rid of enum board_slots in P4080 MDIO driver enum board_slots contained six values, where SLOT1 == 1, SLOT2 == 2, and so on. This is pointless, so remove it. Also move the lane_to_slot[] array to the top of the file so that it can be used by other functions. Signed-off-by: Timur Tabi Signed-off-by: Andy Fleming --- board/freescale/corenet_ds/eth_p4080.c | 59 +++++++++++----------------------- 1 file changed, 19 insertions(+), 40 deletions(-) diff --git a/board/freescale/corenet_ds/eth_p4080.c b/board/freescale/corenet_ds/eth_p4080.c index b87b092..2c69c51 100644 --- a/board/freescale/corenet_ds/eth_p4080.c +++ b/board/freescale/corenet_ds/eth_p4080.c @@ -68,6 +68,15 @@ static char *mdio_names[16] = { NULL, NULL, NULL, }; +/* + * Mapping of all 18 SERDES lanes to board slots. A value of '0' here means + * that the mapping must be determined dynamically, or that the lane maps to + * something other than a board slot. + */ +static u8 lane_to_slot[] = { + 1, 1, 2, 2, 3, 3, 3, 3, 6, 6, 4, 4, 4, 4, 5, 5, 5, 5 +}; + static char *p4080ds_mdio_name_for_muxval(u32 muxval) { return mdio_names[(muxval & EMI_MASK) >> 28]; @@ -290,15 +299,6 @@ void fdt_fixup_board_enet(void *fdt) } } -enum board_slots { - SLOT1 = 1, - SLOT2, - SLOT3, - SLOT4, - SLOT5, - SLOT6, -}; - int board_eth_init(bd_t *bis) { #ifdef CONFIG_FMAN_ENET @@ -307,27 +307,6 @@ int board_eth_init(bd_t *bis) struct fsl_pq_mdio_info dtsec_mdio_info; struct tgec_mdio_info tgec_mdio_info; - u8 lane_to_slot[] = { - SLOT1, /* 0 - Bank 1:A */ - SLOT1, /* 1 - Bank 1:B */ - SLOT2, /* 2 - Bank 1:C */ - SLOT2, /* 3 - Bank 1:D */ - SLOT3, /* 4 - Bank 1:E */ - SLOT3, /* 5 - Bank 1:F */ - SLOT3, /* 6 - Bank 1:G */ - SLOT3, /* 7 - Bank 1:H */ - SLOT6, /* 8 - Bank 1:I */ - SLOT6, /* 9 - Bank 1:J */ - SLOT4, /* 10 - Bank 2:A */ - SLOT4, /* 11 - Bank 2:B */ - SLOT4, /* 12 - Bank 2:C */ - SLOT4, /* 13 - Bank 2:D */ - SLOT5, /* 14 - Bank 3:A */ - SLOT5, /* 15 - Bank 3:B */ - SLOT5, /* 16 - Bank 3:C */ - SLOT5, /* 17 - Bank 3:D */ - }; - /* Initialize the mdio_mux array so we can recognize empty elements */ for (i = 0; i < NUM_FM_PORTS; i++) mdio_mux[i] = EMI_NONE; @@ -380,17 +359,17 @@ int board_eth_init(bd_t *bis) break; slot = lane_to_slot[lane]; switch (slot) { - case SLOT3: + case 3: mdio_mux[i] = EMI1_SLOT3; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT4: + case 4: mdio_mux[i] = EMI1_SLOT4; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT5: + case 5: mdio_mux[i] = EMI1_SLOT5; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); @@ -417,12 +396,12 @@ int board_eth_init(bd_t *bis) break; slot = lane_to_slot[lane]; switch (slot) { - case SLOT4: + case 4: mdio_mux[i] = EMI2_SLOT4; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT5: + case 5: mdio_mux[i] = EMI2_SLOT5; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); @@ -444,17 +423,17 @@ int board_eth_init(bd_t *bis) break; slot = lane_to_slot[lane]; switch (slot) { - case SLOT3: + case 3: mdio_mux[i] = EMI1_SLOT3; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT4: + case 4: mdio_mux[i] = EMI1_SLOT4; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT5: + case 5: mdio_mux[i] = EMI1_SLOT5; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); @@ -481,12 +460,12 @@ int board_eth_init(bd_t *bis) break; slot = lane_to_slot[lane]; switch (slot) { - case SLOT4: + case 4: mdio_mux[i] = EMI2_SLOT4; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); break; - case SLOT5: + case 5: mdio_mux[i] = EMI2_SLOT5; fm_info_set_mdio(i, mii_dev_for_muxval(mdio_mux[i])); -- cgit v1.1 From 055ce08004136333fd237fa8f0a5ab3dd82c7a49 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 14 Aug 2012 06:47:27 +0000 Subject: powerpc/85xx: remove support for the Freescale P3060 The P3060 was cancelled before it went into production, so there's no point in supporting it. Signed-off-by: Timur Tabi Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/Makefile | 3 - arch/powerpc/cpu/mpc85xx/fdt.c | 2 +- arch/powerpc/cpu/mpc85xx/p3060_ids.c | 117 -------- arch/powerpc/cpu/mpc85xx/p3060_serdes.c | 118 -------- arch/powerpc/cpu/mpc8xxx/cpu.c | 1 - arch/powerpc/include/asm/config_mpc85xx.h | 19 -- arch/powerpc/include/asm/immap_85xx.h | 2 +- arch/powerpc/include/asm/processor.h | 1 - board/freescale/common/Makefile | 2 - board/freescale/p3060qds/Makefile | 54 ---- board/freescale/p3060qds/README | 110 ------- board/freescale/p3060qds/ddr.c | 248 --------------- board/freescale/p3060qds/eth.c | 482 ------------------------------ board/freescale/p3060qds/fixed_ddr.c | 214 ------------- board/freescale/p3060qds/p3060qds.c | 342 --------------------- board/freescale/p3060qds/p3060qds.h | 30 -- board/freescale/p3060qds/p3060qds_qixis.h | 74 ----- boards.cfg | 3 - drivers/net/fm/Makefile | 1 - drivers/net/fm/p3060.c | 97 ------ include/configs/P3060QDS.h | 48 --- include/configs/corenet_ds.h | 6 +- 22 files changed, 3 insertions(+), 1971 deletions(-) delete mode 100644 arch/powerpc/cpu/mpc85xx/p3060_ids.c delete mode 100644 arch/powerpc/cpu/mpc85xx/p3060_serdes.c delete mode 100644 board/freescale/p3060qds/Makefile delete mode 100644 board/freescale/p3060qds/README delete mode 100644 board/freescale/p3060qds/ddr.c delete mode 100644 board/freescale/p3060qds/eth.c delete mode 100644 board/freescale/p3060qds/fixed_ddr.c delete mode 100644 board/freescale/p3060qds/p3060qds.c delete mode 100644 board/freescale/p3060qds/p3060qds.h delete mode 100644 board/freescale/p3060qds/p3060qds_qixis.h delete mode 100644 drivers/net/fm/p3060.c delete mode 100644 include/configs/P3060QDS.h diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile index 2f79a03..71b8bb7 100644 --- a/arch/powerpc/cpu/mpc85xx/Makefile +++ b/arch/powerpc/cpu/mpc85xx/Makefile @@ -65,7 +65,6 @@ COBJS-$(CONFIG_P2020) += ddr-gen3.o COBJS-$(CONFIG_PPC_P2040) += ddr-gen3.o COBJS-$(CONFIG_PPC_P2041) += ddr-gen3.o COBJS-$(CONFIG_PPC_P3041) += ddr-gen3.o -COBJS-$(CONFIG_PPC_P3060) += ddr-gen3.o COBJS-$(CONFIG_PPC_P4080) += ddr-gen3.o COBJS-$(CONFIG_PPC_P5020) += ddr-gen3.o COBJS-$(CONFIG_BSC9131) += ddr-gen3.o @@ -81,7 +80,6 @@ COBJS-$(CONFIG_SYS_DPAA_QBMAN) += portals.o COBJS-$(CONFIG_PPC_P2040) += p2041_ids.o COBJS-$(CONFIG_PPC_P2041) += p2041_ids.o COBJS-$(CONFIG_PPC_P3041) += p3041_ids.o -COBJS-$(CONFIG_PPC_P3060) += p3060_ids.o COBJS-$(CONFIG_PPC_P4080) += p4080_ids.o COBJS-$(CONFIG_PPC_P5020) += p5020_ids.o @@ -113,7 +111,6 @@ COBJS-$(CONFIG_P2020) += p2020_serdes.o COBJS-$(CONFIG_PPC_P2040) += p2041_serdes.o COBJS-$(CONFIG_PPC_P2041) += p2041_serdes.o COBJS-$(CONFIG_PPC_P3041) += p3041_serdes.o -COBJS-$(CONFIG_PPC_P3060) += p3060_serdes.o COBJS-$(CONFIG_PPC_P4080) += p4080_serdes.o COBJS-$(CONFIG_PPC_P5020) += p5020_serdes.o diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 21c3ad4..2ef2078 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -534,7 +534,7 @@ void fdt_fixup_fman_firmware(void *blob) #define fdt_fixup_fman_firmware(x) #endif -#if defined(CONFIG_PPC_P4080) || defined(CONFIG_PPC_P3060) +#if defined(CONFIG_PPC_P4080) static void fdt_fixup_usb(void *fdt) { ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); diff --git a/arch/powerpc/cpu/mpc85xx/p3060_ids.c b/arch/powerpc/cpu/mpc85xx/p3060_ids.c deleted file mode 100644 index d32142f..0000000 --- a/arch/powerpc/cpu/mpc85xx/p3060_ids.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#ifdef CONFIG_SYS_DPAA_QBMAN -struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = { - /* dqrr liodn, frame data liodn, liodn off, sdest */ - SET_QP_INFO( 1, 2, 1, 0), - SET_QP_INFO( 3, 4, 2, 1), - SET_QP_INFO( 5, 6, 3, 2), - SET_QP_INFO( 7, 8, 4, 3), - SET_QP_INFO( 9, 10, 5, 4), - SET_QP_INFO(11, 12, 6, 5), - SET_QP_INFO(13, 14, 7, 6), - SET_QP_INFO(15, 16, 8, 7), - SET_QP_INFO(17, 18, 9, 0), /* for now sdest to 0 */ - SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */ -}; -#endif - -struct srio_liodn_id_table srio_liodn_tbl[] = { - SET_SRIO_LIODN_1(1, 198), - SET_SRIO_LIODN_1(2, 199), -}; -int srio_liodn_tbl_sz = ARRAY_SIZE(srio_liodn_tbl); - -struct liodn_id_table liodn_tbl[] = { - SET_USB_LIODN(1, "fsl-usb2-mph", 127), - SET_USB_LIODN(2, "fsl-usb2-dr", 157), - - SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 1, 193), - SET_PCI_LIODN("fsl,qoriq-pcie-v2.2", 2, 194), - - SET_DMA_LIODN(1, 196), - SET_DMA_LIODN(2, 197), - - SET_GUTS_LIODN("fsl,srio-rmu", 200, rmuliodnr, 0xd3000), - -#ifdef CONFIG_SYS_DPAA_QBMAN - SET_QMAN_LIODN(31), - SET_BMAN_LIODN(32), -#endif - SET_PME_LIODN(128), -}; -int liodn_tbl_sz = ARRAY_SIZE(liodn_tbl); - -#ifdef CONFIG_SYS_DPAA_FMAN -struct liodn_id_table fman1_liodn_tbl[] = { - SET_FMAN_RX_1G_LIODN(1, 0, 11), - SET_FMAN_RX_1G_LIODN(1, 1, 12), - SET_FMAN_RX_1G_LIODN(1, 2, 13), - SET_FMAN_RX_1G_LIODN(1, 3, 14), -}; -int fman1_liodn_tbl_sz = ARRAY_SIZE(fman1_liodn_tbl); - -#if (CONFIG_SYS_NUM_FMAN == 2) -struct liodn_id_table fman2_liodn_tbl[] = { - SET_FMAN_RX_1G_LIODN(2, 0, 16), - SET_FMAN_RX_1G_LIODN(2, 1, 17), - SET_FMAN_RX_1G_LIODN(2, 2, 18), - SET_FMAN_RX_1G_LIODN(2, 3, 19), -}; -int fman2_liodn_tbl_sz = ARRAY_SIZE(fman2_liodn_tbl); -#endif -#endif - -struct liodn_id_table sec_liodn_tbl[] = { - SET_SEC_JR_LIODN_ENTRY(0, 146, 154), - SET_SEC_JR_LIODN_ENTRY(1, 147, 155), - SET_SEC_JR_LIODN_ENTRY(2, 178, 186), - SET_SEC_JR_LIODN_ENTRY(3, 179, 187), - SET_SEC_RTIC_LIODN_ENTRY(a, 144), - SET_SEC_RTIC_LIODN_ENTRY(b, 145), - SET_SEC_RTIC_LIODN_ENTRY(c, 176), - SET_SEC_RTIC_LIODN_ENTRY(d, 177), - SET_SEC_DECO_LIODN_ENTRY(0, 129, 161), - SET_SEC_DECO_LIODN_ENTRY(1, 130, 162), - SET_SEC_DECO_LIODN_ENTRY(2, 131, 163), - SET_SEC_DECO_LIODN_ENTRY(3, 132, 164), - SET_SEC_DECO_LIODN_ENTRY(4, 133, 165), -}; -int sec_liodn_tbl_sz = ARRAY_SIZE(sec_liodn_tbl); - -struct liodn_id_table liodn_bases[] = { - [FSL_HW_PORTAL_SEC] = SET_LIODN_BASE_2(96, 106), -#ifdef CONFIG_SYS_DPAA_FMAN - [FSL_HW_PORTAL_FMAN1] = SET_LIODN_BASE_1(32), -#if (CONFIG_SYS_NUM_FMAN == 2) - [FSL_HW_PORTAL_FMAN2] = SET_LIODN_BASE_1(64), -#endif -#endif -#ifdef CONFIG_SYS_DPAA_PME - [FSL_HW_PORTAL_PME] = SET_LIODN_BASE_2(116, 133), -#endif -}; diff --git a/arch/powerpc/cpu/mpc85xx/p3060_serdes.c b/arch/powerpc/cpu/mpc85xx/p3060_serdes.c deleted file mode 100644 index e720dcf..0000000 --- a/arch/powerpc/cpu/mpc85xx/p3060_serdes.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include "fsl_corenet_serdes.h" - -static u8 serdes_cfg_tbl[][SRDS_MAX_LANES] = { - [0x03] = {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2, - SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4, SGMII_FM2_DTSEC1, - SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, - NONE, NONE, AURORA, AURORA}, - [0x06] = {PCIE1, PCIE1, PCIE1, PCIE1, NONE, NONE, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4, - SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, SGMII_FM2_DTSEC2, - SGMII_FM1_DTSEC2, NONE, NONE, AURORA, AURORA}, - [0x16] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, - AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, - SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, - [0x19] = {SRIO2, SRIO2, SRIO2, SRIO2, SRIO1, SRIO1, SRIO1, SRIO1, - AURORA, AURORA, PCIE2, PCIE2, PCIE2, PCIE2, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, - [0x1c] = {NONE, NONE, SRIO1, SRIO2, NONE, NONE, NONE, NONE, - AURORA, AURORA, SGMII_FM2_DTSEC1, SGMII_FM1_DTSEC1, - SGMII_FM2_DTSEC2, SGMII_FM1_DTSEC2, SGMII_FM2_DTSEC3, - SGMII_FM1_DTSEC3, SGMII_FM2_DTSEC4, SGMII_FM1_DTSEC4}, -}; - -enum srds_prtcl serdes_get_prtcl(int cfg, int lane) -{ - if (!serdes_lane_enabled(lane)) - return NONE; - - return serdes_cfg_tbl[cfg][lane]; -} - -int is_serdes_prtcl_valid(u32 prtcl) -{ - int i; - - if (prtcl > ARRAY_SIZE(serdes_cfg_tbl)) - return 0; - - for (i = 0; i < SRDS_MAX_LANES; i++) { - if (serdes_cfg_tbl[prtcl][i] != NONE) - return 1; - } - - return 0; -} - -void soc_serdes_init(void) -{ - /* - * On the P3060 the devdisr2 register does not correctly reflect - * the state of the MACs based on the RCW fields. So disable the MACs - * based on the srds_prtcl and ec1, ec2, ec3 fields - */ - - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr2 = in_be32(&gur->devdisr2); - u32 rcwsr11 = in_be32(&gur->rcwsr[11]); - - /* NOTE: Leave FM1-1,FM1-2 alone for MDIO access */ - - if (!is_serdes_configured(SGMII_FM1_DTSEC3)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_3; - - if (!is_serdes_configured(SGMII_FM1_DTSEC4)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC1_4; - - if (!is_serdes_configured(SGMII_FM2_DTSEC1)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_1; - - if (!is_serdes_configured(SGMII_FM2_DTSEC2)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_2; - - if (!is_serdes_configured(SGMII_FM2_DTSEC3)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_3; - - if (!is_serdes_configured(SGMII_FM2_DTSEC4)) - devdisr2 |= FSL_CORENET_DEVDISR2_DTSEC2_4; - - if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) { - devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC1_2; - } - - if ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1) { - devdisr2 &= ~FSL_CORENET_DEVDISR2_DTSEC2_1; - } - - out_be32(&gur->devdisr2, devdisr2); -} diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index 1c615d0..6cc5c4b 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -69,7 +69,6 @@ struct cpu_type cpu_type_list [] = { CPU_TYPE_ENTRY(P2040, P2040, 4), CPU_TYPE_ENTRY(P2041, P2041, 4), CPU_TYPE_ENTRY(P3041, P3041, 4), - CPU_TYPE_ENTRY_MASK(P3060, P3060, 6, 0xf3), CPU_TYPE_ENTRY(P4040, P4040, 4), CPU_TYPE_ENTRY(P4080, P4080, 8), CPU_TYPE_ENTRY(P5010, P5010, 1), diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 0a780d7..7dd9395 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -379,25 +379,6 @@ #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 -#elif defined(CONFIG_PPC_P3060) -#define CONFIG_MAX_CPUS 8 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 4 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_SYS_NUM_FMAN 2 -#define CONFIG_SYS_NUM_FM1_DTSEC 4 -#define CONFIG_SYS_NUM_FM2_DTSEC 4 -#define CONFIG_NUM_DDR_CONTROLLERS 1 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 16 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003 -#define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - #elif defined(CONFIG_PPC_P4040) #define CONFIG_MAX_CPUS 4 #define CONFIG_SYS_FSL_NUM_CC_PLLS 4 diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 9bdfd97..80101bb 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -1766,7 +1766,7 @@ typedef struct ccsr_gur { #define FSL_CORENET_RCWSR8_HOST_AGT_B1 0x00e00000 #define FSL_CORENET_RCWSR8_HOST_AGT_B2 0x00100000 #define FSL_CORENET_RCWSR11_EC1 0x00c00000 /* bits 360..361 */ -#if defined(CONFIG_PPC_P4080) || defined(CONFIG_PPC_P3060) +#ifdef CONFIG_PPC_P4080 #define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1 0x00000000 #define FSL_CORENET_RCWSR11_EC1_FM1_USB1 0x00800000 #define FSL_CORENET_RCWSR11_EC2 0x001c0000 /* bits 363..365 */ diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 095b99f..c942bec 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -1087,7 +1087,6 @@ #define SVR_P2040 0x821000 #define SVR_P2041 0x821001 #define SVR_P3041 0x821103 -#define SVR_P3060 0x820002 #define SVR_P4040 0x820100 #define SVR_P4080 0x820000 #define SVR_P5010 0x822100 diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 0b40dc7..54cb098 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -51,14 +51,12 @@ COBJS-$(CONFIG_MPC8572DS) += ics307_clk.o COBJS-$(CONFIG_P1022DS) += ics307_clk.o COBJS-$(CONFIG_P2020DS) += ics307_clk.o COBJS-$(CONFIG_P3041DS) += ics307_clk.o -COBJS-$(CONFIG_P3060QDS) += ics307_clk.o COBJS-$(CONFIG_P4080DS) += ics307_clk.o COBJS-$(CONFIG_P5020DS) += ics307_clk.o # deal with common files for P-series corenet based devices SUBLIB-$(CONFIG_P2041RDB) += p_corenet/libp_corenet.o SUBLIB-$(CONFIG_P3041DS) += p_corenet/libp_corenet.o -SUBLIB-$(CONFIG_P3060QDS) += p_corenet/libp_corenet.o SUBLIB-$(CONFIG_P4080DS) += p_corenet/libp_corenet.o SUBLIB-$(CONFIG_P5020DS) += p_corenet/libp_corenet.o diff --git a/board/freescale/p3060qds/Makefile b/board/freescale/p3060qds/Makefile deleted file mode 100644 index ae136f4..0000000 --- a/board/freescale/p3060qds/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright 2011 Freescale Semiconductor, Inc. -# (C) Copyright 2001-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(BOARD).o - -COBJS-y += $(BOARD).o -COBJS-y += ddr.o -COBJS-y += eth.o -COBJS-y += fixed_ddr.o - -SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS-y)) -SOBJS := $(addprefix $(obj),$(SOBJS)) - -$(LIB): $(obj).depend $(OBJS) $(SOBJS) - $(call cmd_link_o_target, $(OBJS)) - -clean: - rm -f $(OBJS) $(SOBJS) - -distclean: clean - rm -f $(LIB) core *.bak .depend - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/board/freescale/p3060qds/README b/board/freescale/p3060qds/README deleted file mode 100644 index ec62798..0000000 --- a/board/freescale/p3060qds/README +++ /dev/null @@ -1,110 +0,0 @@ -Overview -========= -The P3060QDS is a Freescale reference board that hosts the six-core P3060 SOC. - -The P3060 Processor combines six e500mc Power Architecture processor -cores(1.2GHz) with high-performance datapath acceleration -architecture(DPAA), CoreNet fabric infrastructure, as well as network -and peripheral bus interfaces required for networking, telecom/datacom, -wireless infrastructure, and military/aerospace applications. - - -P3060QDS Board Specifications: -============================== -Memory subsystem: - * 2G Bytes UDIMM DDR3(64bit bus) with ECC on - * 128M Bytes NOR flash single-chip memory - * 16M Bytes SPI flash - * 8K Bytes AT24C64 I2C EEPROM for RCW - -Ethernet(Default SERDES 0x19): - * FM1-dTSEC1: connected to RGMII PHY1 (Vitesse VSC8641 on board,Bottom of dual RJ45) - * FM1-dTSEC2: connected to RGMII PHY2 (Vitesse VSC8641 on board,Top of dual RJ45) - * FM1-dTSEC3: connected to SGMII PHY (Vitesse VSC8234 port1 in slot1) - * FM1-dTSEC4: connected to SGMII PHY (Vitesse VSC8234 port3 in slot1) - * FM2-dTSEC1: connected to SGMII PHY (Vitesse VSC8234 port0 in slot2) - * FM2-dTSEC2: connected to SGMII PHY (Vitesse VSC8234 port2 in slot2) - * FM2-dTSEC3: connected to SGMII PHY (Vitesse VSC8234 port0 in slot1) - * FM2-dTSEC4: connected to SGMII PHY (Vitesse VSC8234 port2 in slot1) - -PCIe: - * PCIe1: Lanes A, B, C and D of Bank1 are connected to one x4 PCIe SLOT4 - * PCIe2: Lanes E, F, G and H of Bank1 are connected to one x4 PCIe SLOT3 - -RapidIO: - * sRIO1: Lanes E, F, G and H of Bank1 are connected to sRIO1 (SLOT3) - * sRIO2: Lanes A, B, C and D of Bank1 are connected to sRIO2 (SLOT4) - -USB: - * USB1: connected via an external ULPI PHY SMC3315 to a TYPE-A interface - * USB2: connected via an external ULPI PHY SMC3315 to a TYPE-AB interface - -I2C: - * I2C1_CH0: EEPROM AT24C64(0x50) RCW, AT24C02(0x51) DDR SPD, - AT24C02(0x53) DDR SPD, AT24C02(0x57) SystemID, RTC DS3232(0x68) - * I2C1_CH1: 1588 RiserCard(0x55), HSLB Testport, TempMon - ADT7461(0x4C), SerDesMux DS64MB201(0x51/59/5C/5D) - * I2C1_CH2: VDD/GVDD/GIDD ZL6100 (0x21/0x22/0x23/0x24/0x40) - * I2C1_CH3: OCM CFG AT24C02(0x55), OCM IPL AT24C64(0x56) - * I2C1_CH4: PCIe SLOT1 - * I2C1_CH5: PCIe SLOT2 - * I2C1_CH6: PCIe SLOT3 - * I2C1_CH7: PCIe SLOT4 - * I2C2: NULL - * I2C3: NULL - -UART: - * Supports two UARTs up to 115200 bps for console - - -Boot from NOR flash -=================== -1. Build image - export ARCH=powerpc - export CROSS_COMPILE=/your_path/gcc-4.5.xx-eglibc-2.11.xx/powerpc-linux-gnu/bin/powerpc-linux-gnu- - make P3060QDS_config - make - -2. Program image - => tftp 1000000 u-boot.bin - => protect off all - => erase eff80000 efffffff - => cp.b 1000000 eff80000 80000 - -3. Program RCW - => tftp 1000000 rcw.bin - => protect off all - => erase e8000000 e801ffff - => cp.b 1000000 e8000000 50 - -4. Program FMAN Firmware ucode - => tftp 1000000 ucode.bin - => protect off all - => erase ef000000 ef0fffff - => cp.b 1000000 ef000000 2000 - -5. Change DIP-switch - RCW Location: SW1[1-5] = 01101 (eLBC 16bit NOR flash) - Note: 1 stands for 'on', 0 stands for 'off' - - -Using the Device Tree Source File -================================= -To create the DTB (Device Tree Binary) image file, use a command -similar to this: - dtc -O dtb -b 0 -p 1024 p3060qds.dts > p3060qds.dtb - -Or use the following command: - {linux-2.6}/make p3060qds.dtb ARCH=powerpc - -then the dtb file will be generated under the following directory: - {linux-2.6}/arch/powerpc/boot/p3060qds.dtb - - -Booting Linux -============= -Place a linux uImage in the TFTP disk area. - tftp 1000000 uImage - tftp 2000000 rootfs.ext2.gz.uboot - tftp 3000000 p3060rdb.dtb - bootm 1000000 2000000 3000000 diff --git a/board/freescale/p3060qds/ddr.c b/board/freescale/p3060qds/ddr.c deleted file mode 100644 index 9affbf0..0000000 --- a/board/freescale/p3060qds/ddr.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2009-2011 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * Version 2 as published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "p3060qds.h" - -/* - * Fixed sdram init -- doesn't use serial presence detect. - */ - -phys_size_t fixed_sdram(void) -{ - int i; - char buf[32]; - fsl_ddr_cfg_regs_t ddr_cfg_regs; - phys_size_t ddr_size; - unsigned int lawbar1_target_id; - ulong ddr_freq, ddr_freq_mhz; - - ddr_freq = get_ddr_freq(0); - ddr_freq_mhz = ddr_freq / 1000000; - - printf("Configuring DDR for %s MT/s data rate\n", - strmhz(buf, ddr_freq)); - - for (i = 0; fixed_ddr_parm_0[i].max_freq > 0; i++) { - if ((ddr_freq_mhz > fixed_ddr_parm_0[i].min_freq) && - (ddr_freq_mhz <= fixed_ddr_parm_0[i].max_freq)) { - memcpy(&ddr_cfg_regs, - fixed_ddr_parm_0[i].ddr_settings, - sizeof(ddr_cfg_regs)); - break; - } - } - - if (fixed_ddr_parm_0[i].max_freq == 0) - panic("Unsupported DDR data rate %s MT/s data rate\n", - strmhz(buf, ddr_freq)); - - ddr_size = (phys_size_t) CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; - ddr_cfg_regs.ddr_cdr1 = DDR_CDR1_DHC_EN; - fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0); - - /* - * setup laws for DDR. If not interleaving, presuming half memory on - * DDR1 and the other half on DDR2 - */ - if (fixed_ddr_parm_0[i].ddr_settings->cs[0].config & 0x20000000) { - if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE, - ddr_size, - LAW_TRGT_IF_DDR_INTRLV) < 0) { - printf("ERROR setting Local Access Windows for DDR\n"); - return 0; - } - } else { - lawbar1_target_id = LAW_TRGT_IF_DDR_1; - if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE, - ddr_size, - lawbar1_target_id) < 0) { - printf("ERROR setting Local Access Windows for DDR\n"); - return 0; - } - } - return ddr_size; -} - -struct board_specific_params { - u32 n_ranks; - u32 datarate_mhz_high; - u32 clk_adjust; - u32 wrlvl_start; - u32 cpo; - u32 write_data_delay; - u32 force_2T; -}; - -/* - * This table contains all valid speeds we want to override with board - * specific parameters. datarate_mhz_high values need to be in ascending order - * for each n_ranks group. - */ -static const struct board_specific_params udimm[] = { - /* - * memory controller 0 - * num| hi| clk| wrlvl | cpo |wrdata|2T - * ranks| mhz|adjst| start | |delay | - */ - {4, 850, 4, 6, 0xff, 2, 0}, - {4, 950, 5, 7, 0xff, 2, 0}, - {4, 1050, 5, 8, 0xff, 2, 0}, - {4, 1250, 5, 10, 0xff, 2, 0}, - {4, 1350, 5, 11, 0xff, 2, 0}, - {4, 1666, 5, 12, 0xff, 2, 0}, - {2, 850, 5, 6, 0xff, 2, 0}, - {2, 950, 5, 7, 0xff, 2, 0}, - {2, 1250, 4, 6, 0xff, 2, 0}, - {2, 1350, 5, 7, 0xff, 2, 0}, - {2, 1666, 5, 8, 0xff, 2, 0}, - {1, 850, 4, 5, 0xff, 2, 0}, - {1, 950, 4, 7, 0xff, 2, 0}, - {1, 1666, 4, 8, 0xff, 2, 0}, - {} -}; - -static const struct board_specific_params rdimm[] = { - /* - * memory controller 0 - * num| hi| clk| wrlvl | cpo |wrdata|2T - * ranks| mhz|adjst| start | |delay | - */ - {4, 850, 4, 6, 0xff, 2, 0}, - {4, 950, 5, 7, 0xff, 2, 0}, - {4, 1050, 5, 8, 0xff, 2, 0}, - {4, 1250, 5, 10, 0xff, 2, 0}, - {4, 1350, 5, 11, 0xff, 2, 0}, - {4, 1666, 5, 12, 0xff, 2, 0}, - {2, 850, 4, 6, 0xff, 2, 0}, - {2, 1050, 4, 7, 0xff, 2, 0}, - {2, 1666, 4, 8, 0xff, 2, 0}, - {1, 850, 4, 5, 0xff, 2, 0}, - {1, 950, 4, 7, 0xff, 2, 0}, - {1, 1666, 4, 8, 0xff, 2, 0}, - {} -}; - -void fsl_ddr_board_options(memctl_options_t *popts, - dimm_params_t *pdimm, - unsigned int ctrl_num) -{ - const struct board_specific_params *pbsp, *pbsp_highest = NULL; - ulong ddr_freq; - - if (ctrl_num) { - printf("Wrong parameter for controller number %d", ctrl_num); - return; - } - if (!pdimm->n_ranks) - return; - - if (popts->registered_dimm_en) - pbsp = rdimm; - else - pbsp = udimm; - - /* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr - * freqency and n_banks specified in board_specific_parameters table. - */ - ddr_freq = get_ddr_freq(0) / 1000000; - while (pbsp->datarate_mhz_high) { - if (pbsp->n_ranks == pdimm->n_ranks) { - if (ddr_freq <= pbsp->datarate_mhz_high) { - popts->cpo_override = pbsp->cpo; - popts->write_data_delay = - pbsp->write_data_delay; - popts->clk_adjust = pbsp->clk_adjust; - popts->wrlvl_start = pbsp->wrlvl_start; - popts->twoT_en = pbsp->force_2T; - goto found; - } - pbsp_highest = pbsp; - } - pbsp++; - } - - if (pbsp_highest) { - printf("Error: board specific timing not found " - "for data rate %lu MT/s!\n" - "Trying to use the highest speed (%u) parameters\n", - ddr_freq, pbsp_highest->datarate_mhz_high); - popts->cpo_override = pbsp_highest->cpo; - popts->write_data_delay = pbsp_highest->write_data_delay; - popts->clk_adjust = pbsp_highest->clk_adjust; - popts->wrlvl_start = pbsp_highest->wrlvl_start; - popts->twoT_en = pbsp_highest->force_2T; - } else { - panic("DIMM is not supported by this board"); - } - - -found: - - /* - * The datasheet of HMT125U7BFR8C-H9 blocks CL=7 as reservered. - * However SPD still claims CL=7 is supported. Extensive tests - * confirmed this board cannot work stably with CL=7 with this - * particular DIMM. - */ - if (ddr_freq >= 800 && ddr_freq < 1066 && \ - !strncmp(pdimm[0].mpart, "HMT125U7BFR8C-H9", 16)) { - popts->cas_latency_override = 1; - popts->cas_latency_override_value = 8; - debug("Override CL to 8\n"); - } - /* - * Factors to consider for half-strength driver enable: - * - number of DIMMs installed - */ - popts->half_strength_driver_enable = 0; - /* - * Write leveling override - */ - popts->wrlvl_override = 1; - popts->wrlvl_sample = 0xf; - - /* - * Rtt and Rtt_WR override - */ - popts->rtt_override = 0; - - /* Enable ZQ calibration */ - popts->zq_en = 1; - - /* DHC_EN =1, ODT = 60 Ohm */ - popts->ddr_cdr1 = DDR_CDR1_DHC_EN; -} - -phys_size_t initdram(int board_type) -{ - phys_size_t dram_size; - - puts("Initializing...."); - - if (fsl_use_spd()) { - puts("using SPD\n"); - dram_size = fsl_ddr_sdram(); - } else { - puts("using fixed parameters\n"); - dram_size = fixed_sdram(); - } - - dram_size = setup_ddr_tlbs(dram_size / 0x100000); - dram_size *= 0x100000; - - debug(" DDR: "); - return dram_size; -} diff --git a/board/freescale/p3060qds/eth.c b/board/freescale/p3060qds/eth.c deleted file mode 100644 index 3f812db..0000000 --- a/board/freescale/p3060qds/eth.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../common/qixis.h" -#include "../common/fman.h" - -#include "p3060qds_qixis.h" - -#define EMI_NONE 0xffffffff -#define EMI1_RGMII1 0 -#define EMI1_SLOT1 1 -#define EMI1_SLOT2 2 -#define EMI1_SLOT3 3 -#define EMI1_RGMII2 4 - -static int mdio_mux[NUM_FM_PORTS]; - -static char *mdio_names[5] = { - "P3060QDS_MDIO0", - "P3060QDS_MDIO1", - "P3060QDS_MDIO2", - "P3060QDS_MDIO3", - "P3060QDS_MDIO4", -}; - -/* - * Mapping of all 18 SERDES lanes to board slots. - * A value of '0' here means that the mapping must be determined - * dynamically, Lane 8/9/16/17 map to Slot1 or Aurora debug - */ -static u8 lane_to_slot[] = { - 4, 4, 4, 4, 3, 3, 3, 3, 0, 0, 2, 2, 2, 2, 1, 1, 0, 0 -}; - -static char *p3060qds_mdio_name_for_muxval(u32 muxval) -{ - return mdio_names[muxval]; -} - -struct mii_dev *mii_dev_for_muxval(u32 muxval) -{ - struct mii_dev *bus; - char *name = p3060qds_mdio_name_for_muxval(muxval); - - if (!name) { - printf("No bus for muxval %x\n", muxval); - return NULL; - } - - bus = miiphy_get_dev_by_name(name); - - if (!bus) { - printf("No bus by name %s\n", name); - return NULL; - } - - return bus; -} - -struct p3060qds_mdio { - u32 muxval; - struct mii_dev *realbus; -}; - -static void p3060qds_mux_mdio(u32 muxval) -{ - u8 brdcfg4; - - brdcfg4 = QIXIS_READ(brdcfg[4]); - brdcfg4 &= ~BRDCFG4_EMISEL_MASK; - brdcfg4 |= (muxval << 4); - QIXIS_WRITE(brdcfg[4], brdcfg4); -} - -static int p3060qds_mdio_read(struct mii_dev *bus, int addr, int devad, - int regnum) -{ - struct p3060qds_mdio *priv = bus->priv; - - p3060qds_mux_mdio(priv->muxval); - - return priv->realbus->read(priv->realbus, addr, devad, regnum); -} - -static int p3060qds_mdio_write(struct mii_dev *bus, int addr, int devad, - int regnum, u16 value) -{ - struct p3060qds_mdio *priv = bus->priv; - - p3060qds_mux_mdio(priv->muxval); - - return priv->realbus->write(priv->realbus, addr, devad, regnum, value); -} - -static int p3060qds_mdio_reset(struct mii_dev *bus) -{ - struct p3060qds_mdio *priv = bus->priv; - - return priv->realbus->reset(priv->realbus); -} - -static int p3060qds_mdio_init(char *realbusname, u32 muxval) -{ - struct p3060qds_mdio *pmdio; - struct mii_dev *bus = mdio_alloc(); - - if (!bus) { - printf("Failed to allocate P3060QDS MDIO bus\n"); - return -1; - } - - pmdio = malloc(sizeof(*pmdio)); - if (!pmdio) { - printf("Failed to allocate P3060QDS private data\n"); - free(bus); - return -1; - } - - bus->read = p3060qds_mdio_read; - bus->write = p3060qds_mdio_write; - bus->reset = p3060qds_mdio_reset; - sprintf(bus->name, p3060qds_mdio_name_for_muxval(muxval)); - - pmdio->realbus = miiphy_get_dev_by_name(realbusname); - - if (!pmdio->realbus) { - printf("No bus with name %s\n", realbusname); - free(bus); - free(pmdio); - return -1; - } - - pmdio->muxval = muxval; - bus->priv = pmdio; - - return mdio_register(bus); -} - -void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, - enum fm_port port, int offset) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - int srds_prtcl = (in_be32(&gur->rcwsr[4]) & - FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; - - if (mdio_mux[port] == EMI1_RGMII1) - fdt_set_phy_handle(blob, prop, pa, "phy_rgmii1"); - - if (mdio_mux[port] == EMI1_RGMII2) - fdt_set_phy_handle(blob, prop, pa, "phy_rgmii2"); - - if ((mdio_mux[port] == EMI1_SLOT1) && ((srds_prtcl == 0x3) - || (srds_prtcl == 0x6))) { - switch (port) { - case FM2_DTSEC4: - fdt_set_phy_handle(blob, prop, pa, "phy2_slot1"); - break; - case FM1_DTSEC4: - fdt_set_phy_handle(blob, prop, pa, "phy3_slot1"); - break; - default: - break; - } - } - - if (mdio_mux[port] == EMI1_SLOT3) { - switch (port) { - case FM2_DTSEC3: - fdt_set_phy_handle(blob, prop, pa, "phy0_slot3"); - break; - case FM1_DTSEC3: - fdt_set_phy_handle(blob, prop, pa, "phy1_slot3"); - break; - default: - break; - } - } -} - -void fdt_fixup_board_enet(void *fdt) -{ - int i, lane, idx; - - for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { - idx = i - FM1_DTSEC1; - switch (fm_info_get_enet_if(i)) { - case PHY_INTERFACE_MODE_SGMII: - lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx); - if (lane < 0) - break; - - switch (mdio_mux[i]) { - case EMI1_SLOT1: - if (lane >= 14) { - fdt_status_okay_by_alias(fdt, - "emi1_slot1"); - fdt_status_disabled_by_alias(fdt, - "emi1_slot1_bk1"); - } else { - fdt_status_disabled_by_alias(fdt, - "emi1_slot1"); - fdt_status_okay_by_alias(fdt, - "emi1_slot1_bk1"); - } - break; - case EMI1_SLOT2: - fdt_status_okay_by_alias(fdt, "emi1_slot2"); - break; - case EMI1_SLOT3: - fdt_status_okay_by_alias(fdt, "emi1_slot3"); - break; - } - break; - case PHY_INTERFACE_MODE_RGMII: - if (i == FM1_DTSEC1) - fdt_status_okay_by_alias(fdt, "emi1_rgmii1"); - - if (i == FM1_DTSEC2) - fdt_status_okay_by_alias(fdt, "emi1_rgmii2"); - break; - default: - break; - } - } -#if (CONFIG_SYS_NUM_FMAN == 2) - for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) { - idx = i - FM2_DTSEC1; - switch (fm_info_get_enet_if(i)) { - case PHY_INTERFACE_MODE_SGMII: - lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx); - if (lane >= 0) { - switch (mdio_mux[i]) { - case EMI1_SLOT1: - if (lane >= 14) - fdt_status_okay_by_alias(fdt, - "emi1_slot1"); - else - fdt_status_okay_by_alias(fdt, - "emi1_slot1_bk1"); - break; - case EMI1_SLOT2: - fdt_status_okay_by_alias(fdt, - "emi1_slot2"); - break; - case EMI1_SLOT3: - fdt_status_okay_by_alias(fdt, - "emi1_slot3"); - break; - } - } - break; - default: - break; - } - } -#endif -} - -static void initialize_lane_to_slot(void) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - int sdprtl = (in_be32(&gur->rcwsr[4]) & - FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; - - switch (sdprtl) { - case 0x03: - case 0x06: - lane_to_slot[8] = 1; - lane_to_slot[9] = lane_to_slot[8]; - lane_to_slot[16] = 5; - lane_to_slot[17] = lane_to_slot[16]; - break; - case 0x16: - case 0x19: - case 0x1C: - lane_to_slot[8] = 5; - lane_to_slot[9] = lane_to_slot[8]; - lane_to_slot[16] = 1; - lane_to_slot[17] = lane_to_slot[16]; - break; - default: - puts("Invalid SerDes protocol for P3060QDS\n"); - break; - } -} - -int board_eth_init(bd_t *bis) -{ -#ifdef CONFIG_FMAN_ENET - struct dtsec *tsec = (void *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR; - int i; - struct fsl_pq_mdio_info dtsec_mdio_info; - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - int srds_cfg = (in_be32(&gur->rcwsr[4]) & - FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; - - initialize_lane_to_slot(); - - /* - * Set TBIPA on FM1@DTSEC1. This is needed for configurations - * where FM1@DTSEC1 isn't used directly, since it provides - * MDIO for other ports. - */ - out_be32(&tsec->tbipa, CONFIG_SYS_TBIPA_VALUE); - - /* Initialize the mdio_mux array so we can recognize empty elements */ - for (i = 0; i < NUM_FM_PORTS; i++) - mdio_mux[i] = EMI_NONE; - - dtsec_mdio_info.regs = - (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR; - dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME; - - /* Register the 1G MDIO bus */ - fsl_pq_mdio_init(bis, &dtsec_mdio_info); - - /* Register the 5 muxing front-ends to the MDIO buses */ - if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_RGMII) - p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII1); - - if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_RGMII) - p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII2); - p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT1); - p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT2); - p3060qds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3); - - if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_RGMII) - fm_info_set_phy_address(FM1_DTSEC1, 1); /* RGMII1 */ - else if (fm_info_get_enet_if(FM1_DTSEC1) == PHY_INTERFACE_MODE_SGMII) - fm_info_set_phy_address(FM1_DTSEC1, SGMII_CARD_PORT2_PHY_ADDR); - - if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_RGMII) - fm_info_set_phy_address(FM1_DTSEC2, 2); /* RGMII2 */ - else if (fm_info_get_enet_if(FM1_DTSEC2) == PHY_INTERFACE_MODE_SGMII) - fm_info_set_phy_address(FM1_DTSEC2, SGMII_CARD_PORT4_PHY_ADDR); - - fm_info_set_phy_address(FM2_DTSEC1, SGMII_CARD_PORT1_PHY_ADDR); - fm_info_set_phy_address(FM2_DTSEC2, SGMII_CARD_PORT3_PHY_ADDR); - - switch (srds_cfg) { - case 0x03: - case 0x06: - fm_info_set_phy_address(FM2_DTSEC3, SGMII_CARD_PORT3_PHY_ADDR); - fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT4_PHY_ADDR); - fm_info_set_phy_address(FM2_DTSEC4, SGMII_CARD_PORT1_PHY_ADDR); - fm_info_set_phy_address(FM1_DTSEC4, SGMII_CARD_PORT2_PHY_ADDR); - break; - case 0x16: - case 0x19: - case 0x1C: - fm_info_set_phy_address(FM2_DTSEC3, SGMII_CARD_PORT1_PHY_ADDR); - fm_info_set_phy_address(FM1_DTSEC3, SGMII_CARD_PORT2_PHY_ADDR); - fm_info_set_phy_address(FM2_DTSEC4, SGMII_CARD_PORT3_PHY_ADDR); - fm_info_set_phy_address(FM1_DTSEC4, SGMII_CARD_PORT4_PHY_ADDR); - break; - default: - puts("Invalid SerDes protocol for P3060QDS\n"); - break; - } - - for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { - int idx = i - FM1_DTSEC1, lane, slot; - switch (fm_info_get_enet_if(i)) { - case PHY_INTERFACE_MODE_SGMII: - lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx); - if (lane < 0) - break; - slot = lane_to_slot[lane]; - if (QIXIS_READ(present) & (1 << (slot - 1))) - fm_disable_port(i); - switch (slot) { - case 1: - mdio_mux[i] = EMI1_SLOT1; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - case 2: - mdio_mux[i] = EMI1_SLOT2; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - case 3: - mdio_mux[i] = EMI1_SLOT3; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - }; - break; - case PHY_INTERFACE_MODE_RGMII: - if (i == FM1_DTSEC1) { - mdio_mux[i] = EMI1_RGMII1; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - } else if (i == FM1_DTSEC2) { - mdio_mux[i] = EMI1_RGMII2; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - } - break; - default: - break; - } - } - -#if (CONFIG_SYS_NUM_FMAN == 2) - for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) { - int idx = i - FM2_DTSEC1, lane, slot; - switch (fm_info_get_enet_if(i)) { - case PHY_INTERFACE_MODE_SGMII: - lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx); - if (lane < 0) - break; - slot = lane_to_slot[lane]; - if (QIXIS_READ(present) & (1 << (slot - 1))) - fm_disable_port(i); - switch (slot) { - case 1: - mdio_mux[i] = EMI1_SLOT1; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - case 2: - mdio_mux[i] = EMI1_SLOT2; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - case 3: - mdio_mux[i] = EMI1_SLOT3; - fm_info_set_mdio(i, - mii_dev_for_muxval(mdio_mux[i])); - break; - }; - break; - default: - break; - } - } -#endif /* CONFIG_SYS_NUM_FMAN */ - - cpu_eth_init(bis); -#endif /* CONFIG_FMAN_ENET */ - - return pci_eth_init(bis); -} diff --git a/board/freescale/p3060qds/fixed_ddr.c b/board/freescale/p3060qds/fixed_ddr.c deleted file mode 100644 index 125988d..0000000 --- a/board/freescale/p3060qds/fixed_ddr.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2009-2011 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * Version 2 as published by the Free Software Foundation. - */ - -#include -#include - -#define CONFIG_SYS_DDR_TIMING_3_1200 0x01030000 -#define CONFIG_SYS_DDR_TIMING_0_1200 0xCC550104 -#define CONFIG_SYS_DDR_TIMING_1_1200 0x868FAA45 -#define CONFIG_SYS_DDR_TIMING_2_1200 0x0FB8A912 -#define CONFIG_SYS_DDR_MODE_1_1200 0x00441A40 -#define CONFIG_SYS_DDR_MODE_2_1200 0x00100000 -#define CONFIG_SYS_DDR_INTERVAL_1200 0x12480100 -#define CONFIG_SYS_DDR_CLK_CTRL_1200 0x02800000 - -#define CONFIG_SYS_DDR_TIMING_3_1000 0x00020000 -#define CONFIG_SYS_DDR_TIMING_0_1000 0xCC440104 -#define CONFIG_SYS_DDR_TIMING_1_1000 0x727DF944 -#define CONFIG_SYS_DDR_TIMING_2_1000 0x0FB088CF -#define CONFIG_SYS_DDR_MODE_1_1000 0x00441830 -#define CONFIG_SYS_DDR_MODE_2_1000 0x00080000 -#define CONFIG_SYS_DDR_INTERVAL_1000 0x0F3C0100 -#define CONFIG_SYS_DDR_CLK_CTRL_1000 0x02800000 - -#define CONFIG_SYS_DDR_TIMING_3_900 0x00020000 -#define CONFIG_SYS_DDR_TIMING_0_900 0xCC440104 -#define CONFIG_SYS_DDR_TIMING_1_900 0x616ba844 -#define CONFIG_SYS_DDR_TIMING_2_900 0x0fb088ce -#define CONFIG_SYS_DDR_MODE_1_900 0x00441620 -#define CONFIG_SYS_DDR_MODE_2_900 0x00080000 -#define CONFIG_SYS_DDR_INTERVAL_900 0x0db60100 -#define CONFIG_SYS_DDR_CLK_CTRL_900 0x02800000 - -#define CONFIG_SYS_DDR_TIMING_3_800 0x00020000 -#define CONFIG_SYS_DDR_TIMING_0_800 0xcc330104 -#define CONFIG_SYS_DDR_TIMING_1_800 0x6f6b4744 -#define CONFIG_SYS_DDR_TIMING_2_800 0x0fa888cc -#define CONFIG_SYS_DDR_MODE_1_800 0x00441420 -#define CONFIG_SYS_DDR_MODE_2_800 0x00000000 -#define CONFIG_SYS_DDR_INTERVAL_800 0x0c300100 -#define CONFIG_SYS_DDR_CLK_CTRL_800 0x02800000 - -#define CONFIG_SYS_DDR_CS0_BNDS 0x000000FF -#define CONFIG_SYS_DDR_CS1_BNDS 0x00000000 -#define CONFIG_SYS_DDR_CS2_BNDS 0x000000FF -#define CONFIG_SYS_DDR_CS3_BNDS 0x000000FF -#define CONFIG_SYS_DDR2_CS0_BNDS 0x000000FF -#define CONFIG_SYS_DDR2_CS1_BNDS 0x00000000 -#define CONFIG_SYS_DDR2_CS2_BNDS 0x000000FF -#define CONFIG_SYS_DDR2_CS3_BNDS 0x000000FF -#define CONFIG_SYS_DDR_CS0_CONFIG 0xA0044202 -#define CONFIG_SYS_DDR_CS0_CONFIG_2 0x00000000 -#define CONFIG_SYS_DDR_CS1_CONFIG 0x80004202 -#define CONFIG_SYS_DDR_CS2_CONFIG 0x00000000 -#define CONFIG_SYS_DDR_CS3_CONFIG 0x00000000 -#define CONFIG_SYS_DDR2_CS0_CONFIG 0x80044202 -#define CONFIG_SYS_DDR2_CS1_CONFIG 0x80004202 -#define CONFIG_SYS_DDR2_CS2_CONFIG 0x00000000 -#define CONFIG_SYS_DDR2_CS3_CONFIG 0x00000000 -#define CONFIG_SYS_DDR_INIT_ADDR 0x00000000 -#define CONFIG_SYS_DDR_INIT_EXT_ADDR 0x00000000 -#define CONFIG_SYS_DDR_CS1_CONFIG 0x80004202 -#define CONFIG_SYS_DDR_DATA_INIT 0xdeadbeef -#define CONFIG_SYS_DDR_TIMING_4 0x00000001 -#define CONFIG_SYS_DDR_TIMING_5 0x02401400 -#define CONFIG_SYS_DDR_MODE_CONTROL 0x00000000 -#define CONFIG_SYS_DDR_ZQ_CNTL 0x89080600 -#define CONFIG_SYS_DDR_WRLVL_CNTL 0x8675F607 -#define CONFIG_SYS_DDR_SDRAM_CFG 0xE7044000 -#define CONFIG_SYS_DDR_SDRAM_CFG2 0x24401031 -#define CONFIG_SYS_DDR_RCW_1 0x00000000 -#define CONFIG_SYS_DDR_RCW_2 0x00000000 -#define CONFIG_MEM_INIT_VALUE 0xdeadbeef - -fsl_ddr_cfg_regs_t ddr_cfg_regs_800 = { - .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, - .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, - .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, - .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, - .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, - .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, - .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, - .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, - .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, - .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_800, - .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_800, - .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_800, - .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_800, - .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, - .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, - .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_800, - .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_800, - .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, - .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_800, - .ddr_data_init = CONFIG_MEM_INIT_VALUE, - .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_800, - .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, - .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, - .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, - .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, - .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, - .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, - .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, - .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 -}; - -fsl_ddr_cfg_regs_t ddr_cfg_regs_900 = { - .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, - .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, - .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, - .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, - .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, - .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, - .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, - .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, - .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, - .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_900, - .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_900, - .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_900, - .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_900, - .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, - .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, - .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_900, - .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_900, - .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, - .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_900, - .ddr_data_init = CONFIG_MEM_INIT_VALUE, - .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_900, - .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, - .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, - .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, - .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, - .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, - .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, - .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, - .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 -}; - -fsl_ddr_cfg_regs_t ddr_cfg_regs_1000 = { - .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, - .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, - .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, - .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, - .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, - .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, - .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, - .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, - .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, - .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_1000, - .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_1000, - .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_1000, - .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_1000, - .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, - .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, - .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_1000, - .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_1000, - .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, - .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_1000, - .ddr_data_init = CONFIG_MEM_INIT_VALUE, - .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_1000, - .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, - .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, - .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, - .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, - .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, - .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, - .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, - .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 -}; - -fsl_ddr_cfg_regs_t ddr_cfg_regs_1200 = { - .cs[0].bnds = CONFIG_SYS_DDR_CS0_BNDS, - .cs[1].bnds = CONFIG_SYS_DDR_CS1_BNDS, - .cs[2].bnds = CONFIG_SYS_DDR_CS2_BNDS, - .cs[3].bnds = CONFIG_SYS_DDR_CS3_BNDS, - .cs[0].config = CONFIG_SYS_DDR_CS0_CONFIG, - .cs[0].config_2 = CONFIG_SYS_DDR_CS0_CONFIG_2, - .cs[1].config = CONFIG_SYS_DDR_CS1_CONFIG, - .cs[2].config = CONFIG_SYS_DDR_CS2_CONFIG, - .cs[3].config = CONFIG_SYS_DDR_CS3_CONFIG, - .timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3_1200, - .timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0_1200, - .timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1_1200, - .timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2_1200, - .ddr_sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG, - .ddr_sdram_cfg_2 = CONFIG_SYS_DDR_SDRAM_CFG2, - .ddr_sdram_mode = CONFIG_SYS_DDR_MODE_1_1200, - .ddr_sdram_mode_2 = CONFIG_SYS_DDR_MODE_2_1200, - .ddr_sdram_md_cntl = CONFIG_SYS_DDR_MODE_CONTROL, - .ddr_sdram_interval = CONFIG_SYS_DDR_INTERVAL_1200, - .ddr_data_init = CONFIG_MEM_INIT_VALUE, - .ddr_sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL_1200, - .ddr_init_addr = CONFIG_SYS_DDR_INIT_ADDR, - .ddr_init_ext_addr = CONFIG_SYS_DDR_INIT_EXT_ADDR, - .timing_cfg_4 = CONFIG_SYS_DDR_TIMING_4, - .timing_cfg_5 = CONFIG_SYS_DDR_TIMING_5, - .ddr_zq_cntl = CONFIG_SYS_DDR_ZQ_CNTL, - .ddr_wrlvl_cntl = CONFIG_SYS_DDR_WRLVL_CNTL, - .ddr_sdram_rcw_1 = CONFIG_SYS_DDR_RCW_1, - .ddr_sdram_rcw_2 = CONFIG_SYS_DDR_RCW_2 -}; - -fixed_ddr_parm_t fixed_ddr_parm_0[] = { - {750, 850, &ddr_cfg_regs_800}, - {850, 950, &ddr_cfg_regs_900}, - {950, 1050, &ddr_cfg_regs_1000}, - {1050, 1250, &ddr_cfg_regs_1200}, - {0, 0, NULL} -}; diff --git a/board/freescale/p3060qds/p3060qds.c b/board/freescale/p3060qds/p3060qds.c deleted file mode 100644 index 43e7f28..0000000 --- a/board/freescale/p3060qds/p3060qds.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright 2011-2012 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../common/qixis.h" -#include "p3060qds.h" -#include "p3060qds_qixis.h" - -DECLARE_GLOBAL_DATA_PTR; - -int checkboard(void) -{ - u8 sw; - struct cpu_type *cpu = gd->cpu; - ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; - unsigned int i; - - printf("Board: %s", cpu->name); - puts("QDS, "); - - printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ", - QIXIS_READ(id), QIXIS_READ(arch), QIXIS_READ(scver)); - - sw = QIXIS_READ(brdcfg[0]); - sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT; - - if (sw < 0x8) - printf("vBank: %d\n", sw); - else if (sw == 0x8) - puts("Promjet\n"); - else if (sw == 0x9) - puts("NAND\n"); - else - printf("invalid setting of SW%u\n", PIXIS_LBMAP_SWITCH); - - puts("Reset Configuration Word (RCW):"); - for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) { - u32 rcw = in_be32(&gur->rcwsr[i]); - - if ((i % 4) == 0) - printf("\n %08x:", i * 4); - printf(" %08x", rcw); - } - puts("\n"); - - puts("SERDES Reference Clocks: "); - sw = QIXIS_READ(brdcfg[2]); - for (i = 0; i < 3; i++) { - static const char * const freq[] = {"100", "125", "Reserved", - "156.25"}; - unsigned int clock = (sw >> (2 * i)) & 3; - - printf("Bank%u=%sMhz ", i+1, freq[clock]); - } - puts("\n"); - - return 0; -} - -int board_early_init_f(void) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - /* only single DDR controller on QDS board, disable DDR1_MCK4/5 */ - setbits_be32(&gur->ddrclkdr, 0x00030000); - - return 0; -} - -void board_config_serdes_mux(void) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - int cfg = (in_be32(&gur->rcwsr[4]) & - FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26; - - switch (cfg) { - case 0x03: - case 0x06: - /* set Lane I,J as SGMII */ - QIXIS_WRITE(brdcfg[6], BRDCFG6_SD4MX_B | BRDCFG6_SD3MX_A | - BRDCFG6_SD2MX_B | BRDCFG6_SD1MX_A); - break; - case 0x16: - case 0x19: - case 0x1c: - /* set Lane I,J as Aurora Debug */ - QIXIS_WRITE(brdcfg[6], BRDCFG6_SD4MX_A | BRDCFG6_SD3MX_B | - BRDCFG6_SD2MX_A | BRDCFG6_SD1MX_B); - break; - default: - puts("Invalid SerDes protocol for P3060QDS\n"); - break; - } -} - -void board_config_usb_mux(void) -{ - u8 brdcfg4, brdcfg5, brdcfg7; - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 rcwsr11 = in_be32(&gur->rcwsr[11]); - u32 ec1 = rcwsr11 & FSL_CORENET_RCWSR11_EC1; - u32 ec2 = rcwsr11 & FSL_CORENET_RCWSR11_EC2; - - brdcfg4 = QIXIS_READ(brdcfg[4]); - brdcfg4 &= ~BRDCFG4_EC_MODE_MASK; - if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_USB1) && - (ec2 == FSL_CORENET_RCWSR11_EC2_USB2)) { - brdcfg4 |= BRDCFG4_EC2_USB_EC1_USB; - - } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_USB1) && - ((ec2 == FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) || - (ec2 == FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))) { - brdcfg4 |= BRDCFG4_EC2_RGMII_EC1_USB; - - } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1) && - (ec2 == FSL_CORENET_RCWSR11_EC2_USB2)) { - brdcfg4 |= BRDCFG4_EC2_USB_EC1_RGMII; - - } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1) && - ((ec2 == FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) || - (ec2 == FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))) { - brdcfg4 |= BRDCFG4_EC2_RGMII_EC1_RGMII; - } else { - brdcfg4 |= BRDCFG4_EC2_MII_EC1_MII; - } - QIXIS_WRITE(brdcfg[4], brdcfg4); - - brdcfg5 = QIXIS_READ(brdcfg[5]); - brdcfg5 &= ~(BRDCFG5_USB1ID_MASK | BRDCFG5_USB2ID_MASK); - brdcfg5 |= (BRDCFG5_USB1ID_CTRL | BRDCFG5_USB2ID_CTRL); - QIXIS_WRITE(brdcfg[5], brdcfg5); - - brdcfg7 = BRDCFG7_JTAGMX_COP_JTAG | BRDCFG7_IQ1MX_IRQ_EVT | - BRDCFG7_G1MX_USB1 | BRDCFG7_D1MX_TSEC3USB | BRDCFG7_I3MX_USB1; - QIXIS_WRITE(brdcfg[7], brdcfg7); -} - -int board_early_init_r(void) -{ - const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; - const u8 flash_esel = find_tlb_idx((void *)flashbase, 1); - - /* - * Remap Boot flash + PROMJET region to caching-inhibited - * so that flash can be erased properly. - */ - - /* Flush d-cache and invalidate i-cache of any FLASH data */ - flush_dcache(); - invalidate_icache(); - - /* invalidate existing TLB entry for flash + promjet */ - disable_tlb(flash_esel); - - set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, - 0, flash_esel, BOOKE_PAGESZ_256M, 1); - - set_liodns(); -#ifdef CONFIG_SYS_DPAA_QBMAN - setup_portals(); -#endif - board_config_serdes_mux(); - board_config_usb_mux(); - - return 0; -} - -static const char *serdes_clock_to_string(u32 clock) -{ - switch (clock) { - case SRDS_PLLCR0_RFCK_SEL_100: - return "100"; - case SRDS_PLLCR0_RFCK_SEL_125: - return "125"; - case SRDS_PLLCR0_RFCK_SEL_156_25: - return "156.25"; - default: - return "150"; - } -} - -#define NUM_SRDS_BANKS 3 - -int misc_init_r(void) -{ - serdes_corenet_t *srds_regs; - u32 actual[NUM_SRDS_BANKS]; - unsigned int i; - u8 sw; - - sw = QIXIS_READ(brdcfg[2]); - for (i = 0; i < 3; i++) { - unsigned int clock = (sw >> (2 * i)) & 3; - switch (clock) { - case 0: - actual[i] = SRDS_PLLCR0_RFCK_SEL_100; - break; - case 1: - actual[i] = SRDS_PLLCR0_RFCK_SEL_125; - break; - case 3: - actual[i] = SRDS_PLLCR0_RFCK_SEL_156_25; - break; - default: - printf("Warning: SDREFCLK%u switch setting of '10' is " - "unsupported\n", i + 1); - break; - } - } - - srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; - for (i = 0; i < NUM_SRDS_BANKS; i++) { - u32 pllcr0 = in_be32(&srds_regs->bank[i].pllcr0); - u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK; - if (expected != actual[i]) { - printf("Warning: SERDES bank %u expects reference clock" - " %sMHz, but actual is %sMHz\n", i + 1, - serdes_clock_to_string(expected), - serdes_clock_to_string(actual[i])); - } - } - - return 0; -} - -/* - * This is map of CVDD values. 33 means CVDD is 3.3v, 25 means CVDD is 2.5v, - * 18 means CVDD is 1.8v. - */ -static u8 IO_VSEL[] = { - 33, 33, 33, 25, 25, 25, 18, 18, 18, - 33, 33, 33, 25, 25, 25, 18, 18, 18, - 33, 33, 33, 25, 25, 25, 18, 18, 18, - 33, 33, 33, 33, 33 -}; - -#define IO_VSEL_MASK 0x1f - -/* - * different CVDD selects diffenert spi flashs, read dutcfg[3] to get CVDD, - * then set status of spi flash nodes to 'disabled' according to CVDD. - * CVDD '33' will select spi flash0 and flash1, CVDD '25' will select spi - * flash2, CVDD '18' will select spi flash3. - */ -void fdt_fixup_board_spi(void *blob) -{ - u8 sw5 = QIXIS_READ(dutcfg[3]); - - switch (IO_VSEL[sw5 & IO_VSEL_MASK]) { - /* 3.3v */ - case 33: - do_fixup_by_compat(blob, "atmel,at45db081d", "status", - "disabled", strlen("disabled") + 1, 1); - do_fixup_by_compat(blob, "spansion,sst25wf040", "status", - "disabled", strlen("disabled") + 1, 1); - break; - /* 2.5v */ - case 25: - do_fixup_by_compat(blob, "spansion,s25sl12801", "status", - "disabled", strlen("disabled") + 1, 1); - do_fixup_by_compat(blob, "spansion,en25q32", "status", - "disabled", strlen("disabled") + 1, 1); - do_fixup_by_compat(blob, "spansion,sst25wf040", "status", - "disabled", strlen("disabled") + 1, 1); - break; - /* 1.8v */ - case 18: - do_fixup_by_compat(blob, "spansion,s25sl12801", "status", - "disabled", strlen("disabled") + 1, 1); - do_fixup_by_compat(blob, "spansion,en25q32", "status", - "disabled", strlen("disabled") + 1, 1); - do_fixup_by_compat(blob, "atmel,at45db081d", "status", - "disabled", strlen("disabled") + 1, 1); - break; - } -} - -void ft_board_setup(void *blob, bd_t *bd) -{ - phys_addr_t base; - phys_size_t size; - - ft_cpu_setup(blob, bd); - - base = getenv_bootm_low(); - size = getenv_bootm_size(); - - fdt_fixup_memory(blob, (u64)base, (u64)size); - -#if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_MPH_USB) - fdt_fixup_dr_usb(blob, bd); -#endif - -#ifdef CONFIG_PCI - pci_of_setup(blob, bd); -#endif - - fdt_fixup_liodn(blob); - fdt_fixup_dr_usb(blob, bd); - fdt_fixup_board_spi(blob); - -#ifdef CONFIG_SYS_DPAA_FMAN - fdt_fixup_fman_ethernet(blob); - fdt_fixup_board_enet(blob); -#endif -} diff --git a/board/freescale/p3060qds/p3060qds.h b/board/freescale/p3060qds/p3060qds.h deleted file mode 100644 index 3da6815..0000000 --- a/board/freescale/p3060qds/p3060qds.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef __P3060QDS_H__ -#define __P3060QDS_H__ - -#include -#include - -void fdt_fixup_board_enet(void *blob); -void pci_of_setup(void *blob, bd_t *bd); -extern fixed_ddr_parm_t fixed_ddr_parm_0[]; - -#endif diff --git a/board/freescale/p3060qds/p3060qds_qixis.h b/board/freescale/p3060qds/p3060qds_qixis.h deleted file mode 100644 index 4d5d6a2..0000000 --- a/board/freescale/p3060qds/p3060qds_qixis.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef __P3060QDS_QIXIS_H__ -#define __P3060QDS_QIXIS_H__ - -/* Definitions of QIXIS Registers for P3060QDS */ - -/* BRDCFG4[4:7]] select EC1 and EC2 as a pair */ -#define BRDCFG4_EC_MODE_MASK 0x0F -#define BRDCFG4_EC2_MII_EC1_MII 0x00 -#define BRDCFG4_EC2_MII_EC1_USB 0x03 -#define BRDCFG4_EC2_USB_EC1_MII 0x0C -#define BRDCFG4_EC2_USB_EC1_USB 0x0F -#define BRDCFG4_EC2_USB_EC1_RGMII 0x0E -#define BRDCFG4_EC2_RGMII_EC1_USB 0x0B -#define BRDCFG4_EC2_RGMII_EC1_RGMII 0x0A -#define BRDCFG4_EMISEL_MASK 0xF0 - -#define BRDCFG5_ECLKS_MASK 0x80 -#define BRDCFG5_USB1ID_MASK 0x40 -#define BRDCFG5_USB2ID_MASK 0x20 -#define BRDCFG5_GC2MX_MASK 0x0C -#define BRDCFG5_T15MX_MASK 0x03 -#define BRDCFG5_ECLKS_IEEE1588_CM 0x80 -#define BRDCFG5_USB1ID_CTRL 0x40 -#define BRDCFG5_USB2ID_CTRL 0x20 - -#define BRDCFG6_SD1MX_A 0x01 -#define BRDCFG6_SD1MX_B 0x00 -#define BRDCFG6_SD2MX_A 0x02 -#define BRDCFG6_SD2MX_B 0x00 -#define BRDCFG6_SD3MX_A 0x04 -#define BRDCFG6_SD3MX_B 0x00 -#define BRDCFG6_SD4MX_A 0x08 -#define BRDCFG6_SD4MX_B 0x00 - -#define BRDCFG7_JTAGMX_MASK 0xC0 -#define BRDCFG7_IQ1MX_MASK 0x20 -#define BRDCFG7_G1MX_MASK 0x10 -#define BRDCFG7_D1MX_MASK 0x0C -#define BRDCFG7_I3MX_MASK 0x03 -#define BRDCFG7_JTAGMX_AURORA 0x00 -#define BRDCFG7_JTAGMX_FPGA 0x80 -#define BRDCFG7_JTAGMX_COP_JTAG 0xC0 -#define BRDCFG7_IQ1MX_IRQ_EVT 0x00 -#define BRDCFG7_IQ1MX_USB2 0x20 -#define BRDCFG7_G1MX_USB1 0x00 -#define BRDCFG7_G1MX_TSEC3 0x10 -#define BRDCFG7_D1MX_DMA 0x00 -#define BRDCFG7_D1MX_TSEC3USB 0x04 -#define BRDCFG7_D1MX_HDLC2 0x08 -#define BRDCFG7_I3MX_UART2_I2C34 0x00 -#define BRDCFG7_I3MX_GPIO_EVT 0x01 -#define BRDCFG7_I3MX_USB1 0x02 -#define BRDCFG7_I3MX_TSEC3 0x03 - -#endif diff --git a/boards.cfg b/boards.cfg index f102f7a..dce754f 100644 --- a/boards.cfg +++ b/boards.cfg @@ -794,9 +794,6 @@ P3041DS_SDCARD powerpc mpc85xx corenet_ds freescale P3041DS_SECURE_BOOT powerpc mpc85xx corenet_ds freescale - P3041DS:SECURE_BOOT P3041DS_SPIFLASH powerpc mpc85xx corenet_ds freescale - P3041DS:RAMBOOT_PBL,SPIFLASH,SYS_TEXT_BASE=0xFFF80000 P3041DS_SRIO_PCIE_BOOT powerpc mpc85xx corenet_ds freescale - P3041DS:SRIO_PCIE_BOOT_SLAVE,SYS_TEXT_BASE=0xFFF80000 -P3060QDS powerpc mpc85xx p3060qds freescale -P3060QDS_NAND powerpc mpc85xx p3060qds freescale - P3060QDS:RAMBOOT_PBL,NAND,SYS_TEXT_BASE=0xFFF80000 -P3060QDS_SECURE_BOOT powerpc mpc85xx p3060qds freescale - P3060QDS:SECURE_BOOT P4080DS powerpc mpc85xx corenet_ds freescale P4080DS_SDCARD powerpc mpc85xx corenet_ds freescale - P4080DS:RAMBOOT_PBL,SDCARD,SYS_TEXT_BASE=0xFFF80000 P4080DS_SECURE_BOOT powerpc mpc85xx corenet_ds freescale - P4080DS:SECURE_BOOT diff --git a/drivers/net/fm/Makefile b/drivers/net/fm/Makefile index 072b178..9692575 100644 --- a/drivers/net/fm/Makefile +++ b/drivers/net/fm/Makefile @@ -39,7 +39,6 @@ COBJS-$(CONFIG_P1023) += p1023.o COBJS-$(CONFIG_PPC_P2040) += p5020.o COBJS-$(CONFIG_PPC_P2041) += p5020.o COBJS-$(CONFIG_PPC_P3041) += p5020.o -COBJS-$(CONFIG_PPC_P3060) += p3060.o COBJS-$(CONFIG_PPC_P4080) += p4080.o COBJS-$(CONFIG_PPC_P5020) += p5020.o endif diff --git a/drivers/net/fm/p3060.c b/drivers/net/fm/p3060.c deleted file mode 100644 index c9748a9..0000000 --- a/drivers/net/fm/p3060.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include - -u32 port_to_devdisr[] = { - [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, - [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, - [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, - [FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4, - [FM2_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC2_1, - [FM2_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC2_2, - [FM2_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC2_3, - [FM2_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC2_4, -}; - -static int is_device_disabled(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 devdisr2 = in_be32(&gur->devdisr2); - - return port_to_devdisr[port] & devdisr2; -} - -void fman_disable_port(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - - /* don't allow disabling of DTSEC1 as its needed for MDIO */ - if (port == FM1_DTSEC1) - return; - - setbits_be32(&gur->devdisr2, port_to_devdisr[port]); -} - -phy_interface_t fman_port_enet_if(enum fm_port port) -{ - ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - u32 rcwsr11 = in_be32(&gur->rcwsr[11]); - - if (is_device_disabled(port)) - return PHY_INTERFACE_MODE_NONE; - - /* handle RGMII/MII first */ - if ((port == FM1_DTSEC1) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC1) == - FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM1_DTSEC2) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2)) - return PHY_INTERFACE_MODE_RGMII; - - if ((port == FM2_DTSEC1) && ((rcwsr11 & FSL_CORENET_RCWSR11_EC2) == - FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1)) - return PHY_INTERFACE_MODE_RGMII; - - switch (port) { - case FM1_DTSEC1: - case FM1_DTSEC2: - case FM1_DTSEC3: - case FM1_DTSEC4: - if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - case FM2_DTSEC1: - case FM2_DTSEC2: - case FM2_DTSEC3: - case FM2_DTSEC4: - if (is_serdes_configured(SGMII_FM2_DTSEC1 + port - FM2_DTSEC1)) - return PHY_INTERFACE_MODE_SGMII; - break; - default: - return PHY_INTERFACE_MODE_NONE; - } - - return PHY_INTERFACE_MODE_NONE; -} diff --git a/include/configs/P3060QDS.h b/include/configs/P3060QDS.h deleted file mode 100644 index 8006547..0000000 --- a/include/configs/P3060QDS.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * P3060 QDS board configuration file - */ -#define CONFIG_P3060QDS -#define CONFIG_PHYS_64BIT -#define CONFIG_PPC_P3060 -#define CONFIG_FSL_QIXIS - -#define CONFIG_NAND_FSL_ELBC - -#define CONFIG_ICS307_REFCLK_HZ 25000000 /* ICS307 ref clk freq */ - -#define CONFIG_SPI_FLASH_ATMEL -#define CONFIG_SPI_FLASH_EON -#define CONFIG_SPI_FLASH_SST - -#include "corenet_ds.h" - -#define SGMII_CARD_PORT1_PHY_ADDR 0x1C -#define SGMII_CARD_PORT2_PHY_ADDR 0x1D -#define SGMII_CARD_PORT3_PHY_ADDR 0x1E -#define SGMII_CARD_PORT4_PHY_ADDR 0x1F - -/* There is a PCA9547 8-channel I2C-bus multiplexer on P3060QDS board */ -#define CONFIG_I2C_MUX -#define CONFIG_I2C_MULTI_BUS diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index ad3622c..f4f9bd1 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -194,11 +194,7 @@ #define CONFIG_DDR_SPD #define CONFIG_FSL_DDR3 -#ifdef CONFIG_P3060QDS -#define CONFIG_SYS_SPD_BUS_NUM 0 -#else #define CONFIG_SYS_SPD_BUS_NUM 1 -#endif #define SPD_EEPROM_ADDRESS1 0x51 #define SPD_EEPROM_ADDRESS2 0x52 #define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1 /* for p3041/p5010 */ @@ -713,7 +709,7 @@ #define CONFIG_BAUDRATE 115200 -#if defined(CONFIG_P4080DS) || defined(CONFIG_P3060QDS) +#ifdef CONFIG_P4080DS #define __USB_PHY_TYPE ulpi #else #define __USB_PHY_TYPE utmi -- cgit v1.1 From 3e978f5dc85db40432f73380aa5be53096205f18 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 14 Aug 2012 10:14:51 +0000 Subject: powerpc/fsl-corenet: remove dead variant symbols These are not supported as individual build targets, but instead are supported by another target. The dead p4040 defines in particular had bitrotted significantly. Signed-off-by: Scott Wood Acked-by: Kumar Gala Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/Makefile | 3 -- arch/powerpc/include/asm/config_mpc85xx.h | 68 ++----------------------------- arch/powerpc/include/asm/immap_85xx.h | 2 +- drivers/net/fm/Makefile | 1 - include/configs/P2041RDB.h | 2 +- include/configs/P4080DS.h | 1 + include/configs/P5020DS.h | 2 +- 7 files changed, 7 insertions(+), 72 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/Makefile b/arch/powerpc/cpu/mpc85xx/Makefile index 71b8bb7..33e93c8 100644 --- a/arch/powerpc/cpu/mpc85xx/Makefile +++ b/arch/powerpc/cpu/mpc85xx/Makefile @@ -62,7 +62,6 @@ COBJS-$(CONFIG_P1024) += ddr-gen3.o COBJS-$(CONFIG_P1025) += ddr-gen3.o COBJS-$(CONFIG_P2010) += ddr-gen3.o COBJS-$(CONFIG_P2020) += ddr-gen3.o -COBJS-$(CONFIG_PPC_P2040) += ddr-gen3.o COBJS-$(CONFIG_PPC_P2041) += ddr-gen3.o COBJS-$(CONFIG_PPC_P3041) += ddr-gen3.o COBJS-$(CONFIG_PPC_P4080) += ddr-gen3.o @@ -77,7 +76,6 @@ COBJS-$(CONFIG_PCI) += pci.o COBJS-$(CONFIG_SYS_DPAA_QBMAN) += portals.o # various SoC specific assignments -COBJS-$(CONFIG_PPC_P2040) += p2041_ids.o COBJS-$(CONFIG_PPC_P2041) += p2041_ids.o COBJS-$(CONFIG_PPC_P3041) += p3041_ids.o COBJS-$(CONFIG_PPC_P4080) += p4080_ids.o @@ -108,7 +106,6 @@ COBJS-$(CONFIG_P1024) += p1021_serdes.o COBJS-$(CONFIG_P1025) += p1021_serdes.o COBJS-$(CONFIG_P2010) += p2020_serdes.o COBJS-$(CONFIG_P2020) += p2020_serdes.o -COBJS-$(CONFIG_PPC_P2040) += p2041_serdes.o COBJS-$(CONFIG_PPC_P2041) += p2041_serdes.o COBJS-$(CONFIG_PPC_P3041) += p3041_serdes.o COBJS-$(CONFIG_PPC_P4080) += p4080_serdes.o diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 7dd9395..950ec2f 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -306,30 +306,7 @@ #define CONFIG_SYS_FSL_RMU #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM 2 -#elif defined(CONFIG_PPC_P2040) -#define CONFIG_MAX_CPUS 4 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 2 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_SYS_NUM_FMAN 1 -#define CONFIG_SYS_NUM_FM1_DTSEC 5 -#define CONFIG_NUM_DDR_CONTROLLERS 1 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 32 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_USB1_PHY_ENABLE -#define CONFIG_SYS_FSL_USB2_PHY_ENABLE -#define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 -#define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 -#define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - -#elif defined(CONFIG_PPC_P2041) +#elif defined(CONFIG_PPC_P2041) /* also supports P2040 */ #define CONFIG_MAX_CPUS 4 #define CONFIG_SYS_FSL_NUM_CC_PLLS 2 #define CONFIG_SYS_FSL_NUM_LAWS 32 @@ -379,22 +356,7 @@ #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 -#elif defined(CONFIG_PPC_P4040) -#define CONFIG_MAX_CPUS 4 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 4 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 16 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,p4080-pcie" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - -#elif defined(CONFIG_PPC_P4080) +#elif defined(CONFIG_PPC_P4080) /* also supports P4040 */ #define CONFIG_MAX_CPUS 8 #define CONFIG_SYS_FSL_NUM_CC_PLLS 4 #define CONFIG_SYS_FSL_NUM_LAWS 32 @@ -430,31 +392,7 @@ #define CONFIG_SYS_FSL_RMU #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM 2 -/* P5010 is single core version of P5020 */ -#elif defined(CONFIG_PPC_P5010) -#define CONFIG_MAX_CPUS 1 -#define CONFIG_SYS_FSL_NUM_CC_PLLS 2 -#define CONFIG_SYS_FSL_NUM_LAWS 32 -#define CONFIG_SYS_FSL_SEC_COMPAT 4 -#define CONFIG_FSL_SATA_V2 -#define CONFIG_SYS_NUM_FMAN 1 -#define CONFIG_SYS_NUM_FM1_DTSEC 5 -#define CONFIG_SYS_NUM_FM1_10GEC 1 -#define CONFIG_NUM_DDR_CONTROLLERS 1 -#define CONFIG_SYS_FM_MURAM_SIZE 0x28000 -#define CONFIG_SYS_FSL_TBCLK_DIV 32 -#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2" -#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000 -#define CONFIG_SYS_FSL_USB1_PHY_ENABLE -#define CONFIG_SYS_FSL_USB2_PHY_ENABLE -#define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY -#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 -#define CONFIG_SYS_FSL_ERRATUM_DDR_A003474 -#define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 -#define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 -#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 - -#elif defined(CONFIG_PPC_P5020) +#elif defined(CONFIG_PPC_P5020) /* also supports P5010 */ #define CONFIG_MAX_CPUS 2 #define CONFIG_SYS_FSL_NUM_CC_PLLS 2 #define CONFIG_SYS_FSL_NUM_LAWS 32 diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 80101bb..c2d33b1 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -1774,7 +1774,7 @@ typedef struct ccsr_gur { #define FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2 0x00080000 #define FSL_CORENET_RCWSR11_EC2_USB2 0x00100000 #endif -#if defined(CONFIG_PPC_P2040) || defined(CONFIG_PPC_P2041) \ +#if defined(CONFIG_PPC_P2041) \ || defined(CONFIG_PPC_P3041) || defined(CONFIG_PPC_P5020) #define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC4_RGMII 0x00000000 #define FSL_CORENET_RCWSR11_EC1_FM1_DTSEC4_MII 0x00800000 diff --git a/drivers/net/fm/Makefile b/drivers/net/fm/Makefile index 9692575..cc57354 100644 --- a/drivers/net/fm/Makefile +++ b/drivers/net/fm/Makefile @@ -36,7 +36,6 @@ COBJS-y += tgec_phy.o COBJS-$(CONFIG_P1017) += p1023.o COBJS-$(CONFIG_P1023) += p1023.o # The P204x, P304x, and P5020 are the same -COBJS-$(CONFIG_PPC_P2040) += p5020.o COBJS-$(CONFIG_PPC_P2041) += p5020.o COBJS-$(CONFIG_PPC_P3041) += p5020.o COBJS-$(CONFIG_PPC_P4080) += p4080.o diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h index ce31fdc..3169665 100644 --- a/include/configs/P2041RDB.h +++ b/include/configs/P2041RDB.h @@ -22,7 +22,7 @@ /* * P2041 RDB board configuration file - * + * Also supports P2040 RDB */ #ifndef __CONFIG_H #define __CONFIG_H diff --git a/include/configs/P4080DS.h b/include/configs/P4080DS.h index 4a2e475..d6f2f5c 100644 --- a/include/configs/P4080DS.h +++ b/include/configs/P4080DS.h @@ -22,6 +22,7 @@ /* * P4080 DS board configuration file + * Also supports P4040 DS */ #define CONFIG_P4080DS #define CONFIG_PHYS_64BIT diff --git a/include/configs/P5020DS.h b/include/configs/P5020DS.h index 4afc4f1..8625f76 100644 --- a/include/configs/P5020DS.h +++ b/include/configs/P5020DS.h @@ -22,7 +22,7 @@ /* * P5020 DS board configuration file - * + * Also supports P5010 DS */ #define CONFIG_P5020DS #define CONFIG_PHYS_64BIT -- cgit v1.1 From 33eee330cc8a445ff05f39a58af3c87324798230 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 14 Aug 2012 10:14:53 +0000 Subject: powerpc/fsl-corenet: work around erratum A004510 Erratum A004510 says that under certain load conditions, modified cache lines can be discarded, causing data corruption. To work around this, several CCSR and DCSR register updates need to be made in a careful manner, so that there is no other transaction in corenet when the update is made. The update is made from a locked cacheline, with a delay before to flush any previous activity, and a delay after to flush the CCSR/DCSR update. We can't use a readback because that would be another corenet transaction, which is not allowed. We lock the subsequent cacheline to prevent it from being fetched while we're executing the previous cacheline. It is filled with nops so that a branch doesn't cause us to fetch another cacheline. Ordinarily we are running in a cache-inhibited mapping at this point, so we temporarily change that. We make it guarded so that we should never see a speculative load, and we never do an explicit load. Thus, only the I-cache should ever fill from this mapping, and we flush/unlock it afterward. Thus we should avoid problems from any potential cache aliasing between inhibited and non-inhibited mappings. NOTE that if PAMU is used with this patch, it will need to use a dedicated LAW as described in the erratum. This is the responsibility of the OS that sets up PAMU. Signed-off-by: Scott Wood Signed-off-by: Andy Fleming --- README | 25 +++ arch/powerpc/cpu/mpc85xx/cmd_errata.c | 3 + arch/powerpc/cpu/mpc85xx/release.S | 27 +++ arch/powerpc/cpu/mpc85xx/start.S | 284 ++++++++++++++++++++++++++++++ arch/powerpc/include/asm/config_mpc85xx.h | 14 ++ arch/powerpc/include/asm/processor.h | 2 + 6 files changed, 355 insertions(+) diff --git a/README b/README index 81ee7d4..8197235 100644 --- a/README +++ b/README @@ -383,6 +383,31 @@ The following options need to be configured: symbol should be set to the TLB1 entry to be used for this purpose. + CONFIG_SYS_FSL_ERRATUM_A004510 + + Enables a workaround for erratum A004510. If set, + then CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV and + CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY must be set. + + CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV + CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 (optional) + + Defines one or two SoC revisions (low 8 bits of SVR) + for which the A004510 workaround should be applied. + + The rest of SVR is either not relevant to the decision + of whether the erratum is present (e.g. p2040 versus + p2041) or is implied by the build target, which controls + whether CONFIG_SYS_FSL_ERRATUM_A004510 is set. + + See Freescale App Note 4493 for more information about + this erratum. + + CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY + + This is the value to write into CCSR offset 0x18600 + according to the A004510 workaround. + - Generic CPU options: CONFIG_SYS_BIG_ENDIAN, CONFIG_SYS_LITTLE_ENDIAN diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 858b3f8..e8989bd 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -124,6 +124,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) puts("Work-around for Erratum NMG ETSEC129 enabled\n"); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + puts("Work-around for Erratum A004510 enabled\n"); +#endif return 0; } diff --git a/arch/powerpc/cpu/mpc85xx/release.S b/arch/powerpc/cpu/mpc85xx/release.S index 1555a9b..043d0ff 100644 --- a/arch/powerpc/cpu/mpc85xx/release.S +++ b/arch/powerpc/cpu/mpc85xx/release.S @@ -74,6 +74,33 @@ __secondary_start_page: mtspr 977,r3 #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + mfspr r3,SPRN_SVR + rlwinm r3,r3,0,0xff + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV + cmpw r3,r4 + beq 1f + +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + cmpw r3,r4 + beq 1f +#endif + + /* Not a supported revision affected by erratum */ + b 2f + +1: /* Erratum says set bits 55:60 to 001001 */ + msync + isync + mfspr r3,976 + li r4,0x48 + rlwimi r3,r4,0,0x1f8 + mtspr 976,r3 + isync +2: +#endif + /* Enable branch prediction */ lis r3,BUCSR_ENABLE@h ori r3,r3,BUCSR_ENABLE@l diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index b1998b2..66e8eb8 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -86,6 +86,35 @@ _start_e500: li r1,MSR_DE mtmsr r1 +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + mfspr r3,SPRN_SVR + rlwinm r3,r3,0,0xff + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV + cmpw r3,r4 + beq 1f + +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 + cmpw r3,r4 + beq 1f +#endif + + /* Not a supported revision affected by erratum */ + li r27,0 + b 2f + +1: li r27,1 /* Remember for later that we have the erratum */ + /* Erratum says set bits 55:60 to 001001 */ + msync + isync + mfspr r3,976 + li r4,0x48 + rlwimi r3,r4,0,0x1f8 + mtspr 976,r3 + isync +2: +#endif + #if defined(CONFIG_SECURE_BOOT) && defined(CONFIG_E500MC) /* ISBC uses L2 as stack. * Disable L2 cache here so that u-boot can enable it later @@ -440,6 +469,14 @@ nexti: mflr r1 /* R1 = our PC */ mfspr r2, MAS2 andc r2, r2, r3 or r2, r2, r1 +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 + cmpwi r27,0 + beq 1f + andi. r15, r2, MAS2_I|MAS2_G /* save the old I/G for later */ + rlwinm r2, r2, 0, ~MAS2_I + ori r2, r2, MAS2_G +1: +#endif mtspr MAS2, r2 /* Set the EPN to our PC base address */ mfspr r2, MAS3 @@ -719,6 +756,253 @@ delete_temp_tlbs: tlbwe #endif /* #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) */ +#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 +#define DCSR_LAWBARH0 (CONFIG_SYS_CCSRBAR + 0x1000) +#define LAW_SIZE_1M 0x13 +#define DCSRBAR_LAWAR (LAW_EN | (0x1d << 20) | LAW_SIZE_1M) + + cmpwi r27,0 + beq 9f + + /* + * Create a TLB entry for CCSR + * + * We're executing out of TLB1 entry in r14, and that's the only + * TLB entry that exists. To allocate some TLB entries for our + * own use, flip a bit high enough that we won't flip it again + * via incrementing. + */ + + xori r8, r14, 32 + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r8, 16, MAS0_ESEL_MSK + lis r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@h + ori r1, r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@l + lis r7, CONFIG_SYS_CCSRBAR@h + ori r7, r7, CONFIG_SYS_CCSRBAR@l + ori r2, r7, MAS2_I|MAS2_G + lis r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@h + ori r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@l + lis r4, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h + ori r4, r4, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l + mtspr MAS0, r0 + mtspr MAS1, r1 + mtspr MAS2, r2 + mtspr MAS3, r3 + mtspr MAS7, r4 + isync + tlbwe + isync + msync + + /* Map DCSR temporarily to physical address zero */ + li r0, 0 + lis r3, DCSRBAR_LAWAR@h + ori r3, r3, DCSRBAR_LAWAR@l + + stw r0, 0xc00(r7) /* LAWBARH0 */ + stw r0, 0xc04(r7) /* LAWBARL0 */ + sync + stw r3, 0xc08(r7) /* LAWAR0 */ + + /* Read back from LAWAR to ensure the update is complete. */ + lwz r3, 0xc08(r7) /* LAWAR0 */ + isync + + /* Create a TLB entry for DCSR at zero */ + + addi r9, r8, 1 + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r9, 16, MAS0_ESEL_MSK + lis r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M)@h + ori r1, r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M)@l + li r6, 0 /* DCSR effective address */ + ori r2, r6, MAS2_I|MAS2_G + li r3, MAS3_SW|MAS3_SR + li r4, 0 + mtspr MAS0, r0 + mtspr MAS1, r1 + mtspr MAS2, r2 + mtspr MAS3, r3 + mtspr MAS7, r4 + isync + tlbwe + isync + msync + + /* enable the timebase */ +#define CTBENR 0xe2084 + li r3, 1 + addis r4, r7, CTBENR@ha + stw r3, CTBENR@l(r4) + lwz r3, CTBENR@l(r4) + twi 0,r3,0 + isync + + .macro erratum_set_ccsr offset value + addis r3, r7, \offset@ha + lis r4, \value@h + addi r3, r3, \offset@l + ori r4, r4, \value@l + bl erratum_set_value + .endm + + .macro erratum_set_dcsr offset value + addis r3, r6, \offset@ha + lis r4, \value@h + addi r3, r3, \offset@l + ori r4, r4, \value@l + bl erratum_set_value + .endm + + erratum_set_dcsr 0xb0e08 0xe0201800 + erratum_set_dcsr 0xb0e18 0xe0201800 + erratum_set_dcsr 0xb0e38 0xe0400000 + erratum_set_dcsr 0xb0008 0x00900000 + erratum_set_dcsr 0xb0e40 0xe00a0000 + erratum_set_ccsr 0x18600 CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY + erratum_set_ccsr 0x10f00 0x415e5000 + erratum_set_ccsr 0x11f00 0x415e5000 + + /* Make temp mapping uncacheable again, if it was initially */ + bl 2f +2: mflr r3 + tlbsx 0, r3 + mfspr r4, MAS2 + rlwimi r4, r15, 0, MAS2_I + rlwimi r4, r15, 0, MAS2_G + mtspr MAS2, r4 + isync + tlbwe + isync + msync + + /* Clear the cache */ + lis r3,(L1CSR1_ICFI|L1CSR1_ICLFR)@h + ori r3,r3,(L1CSR1_ICFI|L1CSR1_ICLFR)@l + sync + isync + mtspr SPRN_L1CSR1,r3 + isync +2: sync + mfspr r4,SPRN_L1CSR1 + and. r4,r4,r3 + bne 2b + + lis r3,(L1CSR1_CPE|L1CSR1_ICE)@h + ori r3,r3,(L1CSR1_CPE|L1CSR1_ICE)@l + sync + isync + mtspr SPRN_L1CSR1,r3 + isync +2: sync + mfspr r4,SPRN_L1CSR1 + and. r4,r4,r3 + beq 2b + + /* Remove temporary mappings */ + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r9, 16, MAS0_ESEL_MSK + li r3, 0 + mtspr MAS0, r0 + mtspr MAS1, r3 + isync + tlbwe + isync + msync + + li r3, 0 + stw r3, 0xc08(r7) /* LAWAR0 */ + lwz r3, 0xc08(r7) + isync + + lis r0, MAS0_TLBSEL(1)@h + rlwimi r0, r8, 16, MAS0_ESEL_MSK + li r3, 0 + mtspr MAS0, r0 + mtspr MAS1, r3 + isync + tlbwe + isync + msync + + b 9f + + /* r3 = addr, r4 = value, clobbers r5, r11, r12 */ +erratum_set_value: + /* Lock two cache lines into I-Cache */ + sync + mfspr r11, SPRN_L1CSR1 + rlwinm r11, r11, 0, ~L1CSR1_ICUL + sync + isync + mtspr SPRN_L1CSR1, r11 + isync + + mflr r12 + bl 5f +5: mflr r5 + addi r5, r5, 2f - 5b + icbtls 0, 0, r5 + addi r5, r5, 64 + + sync + mfspr r11, SPRN_L1CSR1 +3: andi. r11, r11, L1CSR1_ICUL + bne 3b + + icbtls 0, 0, r5 + addi r5, r5, 64 + + sync + mfspr r11, SPRN_L1CSR1 +3: andi. r11, r11, L1CSR1_ICUL + bne 3b + + b 2f + .align 6 + /* Inside a locked cacheline, wait a while, write, then wait a while */ +2: sync + + mfspr r5, SPRN_TBRL + addis r11, r5, 0x10000@h /* wait 65536 timebase ticks */ +4: mfspr r5, SPRN_TBRL + subf. r5, r5, r11 + bgt 4b + + stw r4, 0(r3) + + mfspr r5, SPRN_TBRL + addis r11, r5, 0x10000@h /* wait 65536 timebase ticks */ +4: mfspr r5, SPRN_TBRL + subf. r5, r5, r11 + bgt 4b + + sync + + /* + * Fill out the rest of this cache line and the next with nops, + * to ensure that nothing outside the locked area will be + * fetched due to a branch. + */ + .rept 19 + nop + .endr + + sync + mfspr r11, SPRN_L1CSR1 + rlwinm r11, r11, 0, ~L1CSR1_ICUL + sync + isync + mtspr SPRN_L1CSR1, r11 + isync + + mtlr r12 + blr + +9: +#endif + create_init_ram_area: lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 950ec2f..8c7489d 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -330,6 +330,10 @@ #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 0x11 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000 #elif defined(CONFIG_PPC_P3041) #define CONFIG_MAX_CPUS 4 @@ -355,6 +359,10 @@ #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 0x11 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000 #elif defined(CONFIG_PPC_P4080) /* also supports P4040 */ #define CONFIG_MAX_CPUS 8 @@ -391,6 +399,9 @@ #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 #define CONFIG_SYS_FSL_RMU #define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM 2 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x20 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xff000000 #elif defined(CONFIG_PPC_P5020) /* also supports P5010 */ #define CONFIG_MAX_CPUS 2 @@ -414,6 +425,9 @@ #define CONFIG_SYS_FSL_SRIO_MAX_PORTS 2 #define CONFIG_SYS_FSL_SRIO_OB_WIN_NUM 9 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5 +#define CONFIG_SYS_FSL_ERRATUM_A004510 +#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10 +#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xc0000000 #elif defined(CONFIG_BSC9131) #define CONFIG_MAX_CPUS 1 diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index c942bec..a8ffedb 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -486,11 +486,13 @@ #define SPRN_L2CFG0 0x207 /* L2 Cache Configuration Register 0 */ #define SPRN_L1CSR0 0x3f2 /* L1 Data Cache Control and Status Register 0 */ #define L1CSR0_CPE 0x00010000 /* Data Cache Parity Enable */ +#define L1CSR0_CUL 0x00000400 /* (D-)Cache Unable to Lock */ #define L1CSR0_DCLFR 0x00000100 /* D-Cache Lock Flash Reset */ #define L1CSR0_DCFI 0x00000002 /* Data Cache Flash Invalidate */ #define L1CSR0_DCE 0x00000001 /* Data Cache Enable */ #define SPRN_L1CSR1 0x3f3 /* L1 Instruction Cache Control and Status Register 1 */ #define L1CSR1_CPE 0x00010000 /* Instruction Cache Parity Enable */ +#define L1CSR1_ICUL 0x00000400 /* I-Cache Unable to Lock */ #define L1CSR1_ICLFR 0x00000100 /* I-Cache Lock Flash Reset */ #define L1CSR1_ICFI 0x00000002 /* Instruction Cache Flash Invalidate */ #define L1CSR1_ICE 0x00000001 /* Instruction Cache Enable */ -- cgit v1.1 From e4879afba376dc6dcc2085760c614d615a203f73 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Wed, 15 Aug 2012 04:12:43 +0000 Subject: powerpc/mpc85xx:Enable debugger support to missed e500v2 SoC Freescale's e500v1 and e500v2 cores (used in mpc85xx chips) have some restrictions on external debugging (JTAG). Need to define define CONFIG_SYS_PPC_E500_DEBUG_TLB to enable a temporary TLB entry to be used during boot to work around the limitations. Enable missed e500v2 SoC i.e. MPC8536, MPC8544, MPC8548 and MPC8572 for debug support. Signed-off-by: Radu Lazarescu Signed-off-by: Prabhakar Kushwaha Cc: Tang Yuantian Signed-off-by: Andy Fleming --- arch/powerpc/include/asm/config_mpc85xx.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 8c7489d..aa27741 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -37,6 +37,7 @@ #if defined(CONFIG_MPC8536) #define CONFIG_MAX_CPUS 1 #define CONFIG_SYS_FSL_NUM_LAWS 12 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 1 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 @@ -54,12 +55,14 @@ #elif defined(CONFIG_MPC8544) #define CONFIG_MAX_CPUS 1 #define CONFIG_SYS_FSL_NUM_LAWS 10 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 0 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #elif defined(CONFIG_MPC8548) #define CONFIG_MAX_CPUS 1 #define CONFIG_SYS_FSL_NUM_LAWS 10 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 0 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_SYS_FSL_ERRATUM_NMG_DDR120 @@ -113,6 +116,7 @@ #elif defined(CONFIG_MPC8572) #define CONFIG_MAX_CPUS 2 #define CONFIG_SYS_FSL_NUM_LAWS 12 +#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2 #define CONFIG_SYS_FSL_SEC_COMPAT 2 #define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000 #define CONFIG_SYS_FSL_ERRATUM_DDR_115 -- cgit v1.1 From 3854173aa87ff30df801d61aba2c58bb88572bbc Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Wed, 15 Aug 2012 06:24:15 +0000 Subject: powerpc/mpc85xx: Add IFC LAW target ID for FSL High-End SoC Freescale's High-End SoC are going to have Integrated Flash controller (IFC)'s support. So add IFC LAW target ID support for High-End SoC or corenet SoC. Signed-off-by: Prabhakar Kushwaha Signed-off-by: Andy Fleming --- arch/powerpc/include/asm/fsl_law.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/include/asm/fsl_law.h b/arch/powerpc/include/asm/fsl_law.h index 13caffd..dc3985e 100644 --- a/arch/powerpc/include/asm/fsl_law.h +++ b/arch/powerpc/include/asm/fsl_law.h @@ -68,6 +68,7 @@ enum law_trgt_if { LAW_TRGT_IF_QMAN = 0x3c, }; #define LAW_TRGT_IF_DDR LAW_TRGT_IF_DDR_1 +#define LAW_TRGT_IF_IFC LAW_TRGT_IF_LBC #else enum law_trgt_if { LAW_TRGT_IF_PCI = 0x00, -- cgit v1.1 From 1ca8690d27871b87b8ec4afe8621d1e003d25d7a Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:20:21 +0000 Subject: powerpc/mpc8xxx: Add immap for topology and rcpm registers Signed-off-by: Kumar Gala Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/include/asm/immap_85xx.h | 88 ++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index c2d33b1..e2f3ae9 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -1838,7 +1838,13 @@ typedef struct ccsr_gur { u8 res31[184]; u32 sriopstecr; /* SRIO prescaler timer enable control */ u32 dcsrcr; /* DCSR Control register */ - u8 res32[1784]; + u8 res31a[56]; + u32 tp_ityp[64]; /* Topology Initiator Type Register */ + struct { + u32 upper; + u32 lower; + } tp_cluster[16]; /* Core Cluster n Topology Register */ + u8 res32[1344]; u32 pmuxcr; /* Pin multiplexing control */ u8 res33[60]; u32 iovselsr; /* I/O voltage selection status */ @@ -1851,6 +1857,18 @@ typedef struct ccsr_gur { u8 res37[380]; } ccsr_gur_t; +#define TP_ITYP_AV 0x00000001 /* Initiator available */ +#define TP_ITYP_TYPE(x) (((x) & 0x6) >> 1) /* Initiator Type */ +#define TP_ITYP_TYPE_OTHER 0x0 +#define TP_ITYP_TYPE_PPC 0x1 /* PowerPC */ +#define TP_ITYP_TYPE_SC 0x2 /* StarCore DSP */ +#define TP_ITYP_TYPE_HA 0x3 /* HW Accelerator */ +#define TP_ITYP_THDS(x) (((x) & 0x18) >> 3) /* # threads */ +#define TP_ITYP_VER(x) (((x) & 0xe0) >> 5) /* Initiator Version */ + +#define TP_CLUSTER_EOC 0x80000000 /* end of clusters */ +#define TP_CLUSTER_INIT_MASK 0x0000003f /* initiator mask */ + #define FSL_CORENET_DCSR_SZ_MASK 0x00000003 #define FSL_CORENET_DCSR_SZ_4M 0x0 #define FSL_CORENET_DCSR_SZ_1G 0x3 @@ -1892,6 +1910,73 @@ typedef struct ccsr_clk { u8 res15[0x3dc]; } ccsr_clk_t; +#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 +typedef struct ccsr_rcpm { + u8 res_00[12]; + u32 tph10sr0; /* Thread PH10 Status Register */ + u8 res_10[12]; + u32 tph10setr0; /* Thread PH10 Set Control Register */ + u8 res_20[12]; + u32 tph10clrr0; /* Thread PH10 Clear Control Register */ + u8 res_30[12]; + u32 tph10psr0; /* Thread PH10 Previous Status Register */ + u8 res_40[12]; + u32 twaitsr0; /* Thread Wait Status Register */ + u8 res_50[96]; + u32 pcph15sr; /* Physical Core PH15 Status Register */ + u32 pcph15setr; /* Physical Core PH15 Set Control Register */ + u32 pcph15clrr; /* Physical Core PH15 Clear Control Register */ + u32 pcph15psr; /* Physical Core PH15 Prev Status Register */ + u8 res_c0[16]; + u32 pcph20sr; /* Physical Core PH20 Status Register */ + u32 pcph20setr; /* Physical Core PH20 Set Control Register */ + u32 pcph20clrr; /* Physical Core PH20 Clear Control Register */ + u32 pcph20psr; /* Physical Core PH20 Prev Status Register */ + u32 pcpw20sr; /* Physical Core PW20 Status Register */ + u8 res_e0[12]; + u32 pcph30sr; /* Physical Core PH30 Status Register */ + u32 pcph30setr; /* Physical Core PH30 Set Control Register */ + u32 pcph30clrr; /* Physical Core PH30 Clear Control Register */ + u32 pcph30psr; /* Physical Core PH30 Prev Status Register */ + u8 res_100[32]; + u32 ippwrgatecr; /* IP Power Gating Control Register */ + u8 res_124[12]; + u32 powmgtcsr; /* Power Management Control & Status Reg */ + u8 res_134[12]; + u32 ippdexpcr[4]; /* IP Powerdown Exception Control Reg */ + u8 res_150[12]; + u32 tpmimr0; /* Thread PM Interrupt Mask Reg */ + u8 res_160[12]; + u32 tpmcimr0; /* Thread PM Crit Interrupt Mask Reg */ + u8 res_170[12]; + u32 tpmmcmr0; /* Thread PM Machine Check Interrupt Mask Reg */ + u8 res_180[12]; + u32 tpmnmimr0; /* Thread PM NMI Mask Reg */ + u8 res_190[12]; + u32 tmcpmaskcr0; /* Thread Machine Check Mask Control Reg */ + u32 pctbenr; /* Physical Core Time Base Enable Reg */ + u32 pctbclkselr; /* Physical Core Time Base Clock Select */ + u32 tbclkdivr; /* Time Base Clock Divider Register */ + u8 res_1ac[4]; + u32 ttbhltcr[4]; /* Thread Time Base Halt Control Register */ + u32 clpcl10sr; /* Cluster PCL10 Status Register */ + u32 clpcl10setr; /* Cluster PCL30 Set Control Register */ + u32 clpcl10clrr; /* Cluster PCL30 Clear Control Register */ + u32 clpcl10psr; /* Cluster PCL30 Prev Status Register */ + u32 cddslpsetr; /* Core Domain Deep Sleep Set Register */ + u32 cddslpclrr; /* Core Domain Deep Sleep Clear Register */ + u32 cdpwroksetr; /* Core Domain Power OK Set Register */ + u32 cdpwrokclrr; /* Core Domain Power OK Clear Register */ + u32 cdpwrensr; /* Core Domain Power Enable Status Register */ + u32 cddslsr; /* Core Domain Deep Sleep Status Register */ + u8 res_1e8[8]; + u32 dslpcntcr[8]; /* Deep Sleep Counter Cfg Register */ + u8 res_300[3568]; +} ccsr_rcpm_t; + +#define ctbenrl pctbenr + +#else typedef struct ccsr_rcpm { u8 res1[4]; u32 cdozsrl; /* Core Doze Status */ @@ -1928,6 +2013,7 @@ typedef struct ccsr_rcpm { u32 ctbhltcrl; /* Core Time Base Halt Control */ u8 res18[0xf68]; } ccsr_rcpm_t; +#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ #else typedef struct ccsr_gur { -- cgit v1.1 From 123bd96d533190a207c9fcea84ae6328732a16cc Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:20:22 +0000 Subject: powerpc/mpc8xxx: use topology registers to calculate number of cores We have actual topology infomation to find out exactly which core is present. Calculate the number of cores if not specified. Signed-off-by: Kumar Gala Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc8xxx/cpu.c | 65 +++++++++++++++++++++++++++++++----- arch/powerpc/include/asm/processor.h | 1 + arch/powerpc/lib/board.c | 13 ++++++++ 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/cpu/mpc8xxx/cpu.c b/arch/powerpc/cpu/mpc8xxx/cpu.c index 6cc5c4b..78a8f92 100644 --- a/arch/powerpc/cpu/mpc8xxx/cpu.c +++ b/arch/powerpc/cpu/mpc8xxx/cpu.c @@ -82,7 +82,39 @@ struct cpu_type cpu_type_list [] = { #endif }; -struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 1); +#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 +u32 compute_ppc_cpumask(void) +{ + ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + int i = 0, count = 0; + u32 cluster, mask = 0; + + do { + int j; + cluster = in_be32(&gur->tp_cluster[i++].lower); + for (j = 0; j < 4; j++) { + u32 idx = (cluster >> (j*8)) & TP_CLUSTER_INIT_MASK; + u32 type = in_be32(&gur->tp_ityp[idx]); + + if (type & TP_ITYP_AV) { + if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_PPC) + mask |= 1 << count; + } + count++; + } + } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); + + return mask; +} +#else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ +/* + * Before chassis genenration 2, the cpumask should be hard-coded. + * In case of cpu type unknown or cpumask unset, use 1 as fail save. + */ +#define compute_ppc_cpumask() 1 +#endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ + +struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 0); struct cpu_type *identify_cpu(u32 ver) { @@ -110,6 +142,9 @@ u32 cpu_mask() return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> MPC8xxx_PICFRR_NCPU_SHIFT) + 1; + if (cpu->num_cores == 0) + return compute_ppc_cpumask(); + return cpu->mask; } @@ -117,13 +152,14 @@ u32 cpu_mask() * Return the number of cores on this SOC. */ int cpu_numcores() { - ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; struct cpu_type *cpu = gd->cpu; - /* better to query feature reporting register than just assume 1 */ - if (cpu == &cpu_type_unknown) - return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> - MPC8xxx_PICFRR_NCPU_SHIFT) + 1; + /* + * Report # of cores in terms of the cpu_mask if we haven't + * figured out how many there are yet + */ + if (cpu->num_cores == 0) + return hweight32(cpu_mask()); return cpu->num_cores; } @@ -135,9 +171,7 @@ int cpu_numcores() { */ int is_core_valid(unsigned int core) { - struct cpu_type *cpu = gd->cpu; - - return !!((1 << core) & cpu->mask); + return !!((1 << core) & cpu_mask()); } int probecpu (void) @@ -153,6 +187,19 @@ int probecpu (void) return 0; } +/* Once in memory, compute mask & # cores once and save them off */ +int fixup_cpu(void) +{ + struct cpu_type *cpu = gd->cpu; + + if (cpu->num_cores == 0) { + cpu->mask = cpu_mask(); + cpu->num_cores = cpu_numcores(); + } + + return 0; +} + /* * Initializes on-chip ethernet controllers. * to override, implement board_eth_init() diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index a8ffedb..3247c80 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -1157,6 +1157,7 @@ struct cpu_type { }; struct cpu_type *identify_cpu(u32 ver); +int fixup_cpu(void); #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) #define CPU_TYPE_ENTRY(n, v, nc) \ diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index 435ef10..07feaf5 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -345,6 +345,13 @@ ulong get_effective_memsize(void) #endif } +int __fixup_cpu(void) +{ + return 0; +} + +int fixup_cpu(void) __attribute__((weak, alias("__fixup_cpu"))); + /* * This is the first part of the initialization sequence that is * implemented in C, but still running from ROM. @@ -646,6 +653,12 @@ void board_init_r(gd_t *id, ulong dest_addr) * We need to update it to point to the same CPU entry in RAM. */ gd->cpu += dest_addr - CONFIG_SYS_MONITOR_BASE; + + /* + * If we didn't know the cpu mask & # cores, we can save them of + * now rather than 'computing' them constantly + */ + fixup_cpu(); #endif #ifdef CONFIG_SYS_EXTRA_ENV_RELOC -- cgit v1.1 From 5b6b85ae639e5c7e822970bdb29337d9e4b16e28 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 17 Aug 2012 08:20:23 +0000 Subject: Add e6500 processor detection Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/cpu.c | 3 +++ arch/powerpc/include/asm/processor.h | 1 + 2 files changed, 4 insertions(+) diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index c1815e8..8d2ef9f 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -117,6 +117,9 @@ int checkcpu (void) case PVR_VER_E5500: puts("E5500"); break; + case PVR_VER_E6500: + puts("E6500"); + break; default: puts("Unknown"); break; diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 3247c80..f3acd17 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -950,6 +950,7 @@ #define PVR_VER_E500_V2 0x8021 #define PVR_VER_E500MC 0x8023 #define PVR_VER_E5500 0x8024 +#define PVR_VER_E6500 0x8040 #define PVR_86xx 0x80040000 -- cgit v1.1 From 50d96e95b454202f96994dd588925379382866aa Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 17 Aug 2012 08:20:24 +0000 Subject: Add IFC offset for DPAA/Corenet platforms Signed-off-by: Kumar Gala Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/include/asm/immap_85xx.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index e2f3ae9..412244e 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -2631,6 +2631,7 @@ struct ccsr_rman { #define CONFIG_SYS_MPC85xx_ESPI_OFFSET 0x110000 #define CONFIG_SYS_MPC85xx_ESDHC_OFFSET 0x114000 #define CONFIG_SYS_MPC85xx_LBC_OFFSET 0x124000 +#define CONFIG_SYS_MPC85xx_IFC_OFFSET 0x124000 #define CONFIG_SYS_MPC85xx_GPIO_OFFSET 0x130000 #define CONFIG_SYS_FSL_CORENET_RMAN_OFFSET 0x1e0000 #define CONFIG_SYS_MPC85xx_PCIE1_OFFSET 0x200000 -- cgit v1.1 From ffdf8890ae2564e8b5af36b1b384ca7e9bcdd7c2 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 17 Aug 2012 08:20:25 +0000 Subject: Added new ext fields to IFC In case more than 32 bit address is used, the EXT bit should be set. Need to fix up address map for IFC #CS for 4, also need to move # of IFC banks into config_mpc85xx.h Signed-off-by: Kumar Gala Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc8xxx/fsl_ifc.c | 12 ++++++++++++ arch/powerpc/include/asm/fsl_ifc.h | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c index 6682496..56b319f 100644 --- a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c +++ b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c @@ -44,12 +44,18 @@ void init_early_memctl_regs(void) set_ifc_ftim(IFC_CS0, IFC_FTIM3, CONFIG_SYS_CS0_FTIM3); #if !defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) || defined(CONFIG_SYS_RAMBOOT) +#ifdef CONFIG_SYS_CSPR0_EXT + set_ifc_cspr_ext(IFC_CS0, CONFIG_SYS_CSPR0_EXT); +#endif set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0); set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0); set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0); #endif #endif +#ifdef CONFIG_SYS_CSPR1_EXT + set_ifc_cspr_ext(IFC_CS1, CONFIG_SYS_CSPR1_EXT); +#endif #if defined(CONFIG_SYS_CSPR1) && defined(CONFIG_SYS_CSOR1) set_ifc_ftim(IFC_CS1, IFC_FTIM0, CONFIG_SYS_CS1_FTIM0); set_ifc_ftim(IFC_CS1, IFC_FTIM1, CONFIG_SYS_CS1_FTIM1); @@ -61,6 +67,9 @@ void init_early_memctl_regs(void) set_ifc_cspr(IFC_CS1, CONFIG_SYS_CSPR1); #endif +#ifdef CONFIG_SYS_CSPR2_EXT + set_ifc_cspr_ext(IFC_CS2, CONFIG_SYS_CSPR2_EXT); +#endif #if defined(CONFIG_SYS_CSPR2) && defined(CONFIG_SYS_CSOR2) set_ifc_ftim(IFC_CS2, IFC_FTIM0, CONFIG_SYS_CS2_FTIM0); set_ifc_ftim(IFC_CS2, IFC_FTIM1, CONFIG_SYS_CS2_FTIM1); @@ -72,6 +81,9 @@ void init_early_memctl_regs(void) set_ifc_cspr(IFC_CS2, CONFIG_SYS_CSPR2); #endif +#ifdef CONFIG_SYS_CSPR3_EXT + set_ifc_cspr_ext(IFC_CS3, CONFIG_SYS_CSPR3_EXT); +#endif #if defined(CONFIG_SYS_CSPR3) && defined(CONFIG_SYS_CSOR3) set_ifc_ftim(IFC_CS3, IFC_FTIM0, CONFIG_SYS_CS3_FTIM0); set_ifc_ftim(IFC_CS3, IFC_FTIM1, CONFIG_SYS_CS3_FTIM1); diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/arch/powerpc/include/asm/fsl_ifc.h index 7d95eb4..ba41b73 100644 --- a/arch/powerpc/include/asm/fsl_ifc.h +++ b/arch/powerpc/include/asm/fsl_ifc.h @@ -783,12 +783,16 @@ extern void init_early_memctl_regs(void); #define IFC_BASE_ADDR ((struct fsl_ifc *)CONFIG_SYS_IFC_ADDR) +#define get_ifc_cspr_ext(i) (in_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext)) #define get_ifc_cspr(i) (in_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr)) +#define get_ifc_csor_ext(i) (in_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext)) #define get_ifc_csor(i) (in_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor)) #define get_ifc_amask(i) (in_be32(&(IFC_BASE_ADDR)->amask_cs[i].amask)) #define get_ifc_ftim(i, j) (in_be32(&(IFC_BASE_ADDR)->ftim_cs[i].ftim[j])) +#define set_ifc_cspr_ext(i, v) (out_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext, v)) #define set_ifc_cspr(i, v) (out_be32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr, v)) +#define set_ifc_csor_ext(i, v) (out_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext, v)) #define set_ifc_csor(i, v) (out_be32(&(IFC_BASE_ADDR)->csor_cs[i].csor, v)) #define set_ifc_amask(i, v) (out_be32(&(IFC_BASE_ADDR)->amask_cs[i].amask, v)) #define set_ifc_ftim(i, j, v) \ @@ -909,22 +913,24 @@ struct fsl_ifc_gpcm { */ struct fsl_ifc { u32 ifc_rev; - u32 res1[0x3]; + u32 res1[0x2]; struct { + u32 cspr_ext; u32 cspr; - u32 res2[0x2]; + u32 res2; } cspr_cs[FSL_IFC_BANK_COUNT]; - u32 res3[0x18]; + u32 res3[0x19]; struct { u32 amask; u32 res4[0x2]; } amask_cs[FSL_IFC_BANK_COUNT]; - u32 res5[0x18]; + u32 res5[0x17]; struct { + u32 csor_ext; u32 csor; - u32 res6[0x2]; + u32 res6; } csor_cs[FSL_IFC_BANK_COUNT]; - u32 res7[0x18]; + u32 res7[0x19]; struct { u32 ftim[4]; u32 res8[0x8]; -- cgit v1.1 From 709389b654de05fd6035656f5e082ba1757807b3 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:20:26 +0000 Subject: powerpc/mpc8xxx: fix core id for multicore booting For the cores with multiple threads, we need to figure out which physical core a thread belongs. To match the core ids, update PIR registers and spin tables. Signed-off-by: York Sun Signed-off-by: Kumar Gala Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/fdt.c | 5 +++-- arch/powerpc/cpu/mpc85xx/release.S | 45 +++++++++++++++++++++++++++++++++++--- arch/powerpc/cpu/mpc8xxx/fdt.c | 3 ++- arch/powerpc/include/asm/mp.h | 6 +++++ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 2ef2078..a0a9b4c 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -57,8 +57,9 @@ void ft_fixup_cpu(void *blob, u64 memory_limit) u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); if (reg) { - u64 val = *reg * SIZE_BOOT_ENTRY + spin_tbl_addr; - val = cpu_to_fdt32(val); + u32 phys_cpu_id = thread_to_core(*reg); + u64 val = phys_cpu_id * SIZE_BOOT_ENTRY + spin_tbl_addr; + val = cpu_to_fdt64(val); if (*reg == id) { fdt_setprop_string(blob, off, "status", "okay"); diff --git a/arch/powerpc/cpu/mpc85xx/release.S b/arch/powerpc/cpu/mpc85xx/release.S index 043d0ff..22e73e0 100644 --- a/arch/powerpc/cpu/mpc85xx/release.S +++ b/arch/powerpc/cpu/mpc85xx/release.S @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * Kumar Gala * * See file CREDITS for list of people who contributed to this @@ -155,7 +155,27 @@ __secondary_start_page: /* r10 has the base address for the entry */ mfspr r0,SPRN_PIR -#ifdef CONFIG_E500MC +#if defined(CONFIG_E6500) +/* + * PIR definition for E6500 + * 0-17 Reserved (logic 0s) + * 8-19 CHIP_ID, 2’b00 - SoC 1 + * all others - reserved + * 20-24 CLUSTER_ID 5’b00000 - CCM 1 + * all others - reserved + * 25-26 CORE_CLUSTER_ID 2’b00 - cluster 1 + * 2’b01 - cluster 2 + * 2’b10 - cluster 3 + * 2’b11 - cluster 4 + * 27-28 CORE_ID 2’b00 - core 0 + * 2’b01 - core 1 + * 2’b10 - core 2 + * 2’b11 - core 3 + * 29-31 THREAD_ID 3’b000 - thread 0 + * 3’b001 - thread 1 + */ + rlwinm r4,r0,29,25,31 +#elif defined(CONFIG_E500MC) rlwinm r4,r0,27,27,31 #else mr r4,r0 @@ -170,6 +190,25 @@ __secondary_start_page: mtspr L1CSR2,r8 #endif +#ifdef CONFIG_E6500 + mfspr r0,SPRN_PIR + /* + * core 0 thread 0: pir reset value 0x00, new pir 0 + * core 0 thread 1: pir reset value 0x01, new pir 1 + * core 1 thread 0: pir reset value 0x08, new pir 2 + * core 1 thread 1: pir reset value 0x09, new pir 3 + * core 2 thread 0: pir reset value 0x10, new pir 4 + * core 2 thread 1: pir reset value 0x11, new pir 5 + * etc. + * + * Only thread 0 of each core will be running, updating PIR doesn't + * need to deal with the thread bits. + */ + rlwinm r4,r0,30,24,30 +#endif + + mtspr SPRN_PIR,r4 /* write to PIR register */ + #if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \ defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011) /* @@ -253,7 +292,7 @@ __secondary_start_page: /* setup the entry */ li r3,0 li r8,1 - stw r0,ENTRY_PIR(r10) + stw r4,ENTRY_PIR(r10) stw r3,ENTRY_ADDR_UPPER(r10) stw r8,ENTRY_ADDR_LOWER(r10) stw r3,ENTRY_R3_UPPER(r10) diff --git a/arch/powerpc/cpu/mpc8xxx/fdt.c b/arch/powerpc/cpu/mpc8xxx/fdt.c index 09810be..32ab050 100644 --- a/arch/powerpc/cpu/mpc8xxx/fdt.c +++ b/arch/powerpc/cpu/mpc8xxx/fdt.c @@ -62,8 +62,9 @@ void ft_fixup_num_cores(void *blob) { off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); while (off != -FDT_ERR_NOTFOUND) { u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); + u32 phys_cpu_id = thread_to_core(*reg); - if (!is_core_valid(*reg) || is_core_disabled(*reg)) { + if (!is_core_valid(phys_cpu_id) || is_core_disabled(phys_cpu_id)) { int ph = fdt_get_phandle(blob, off); /* Delete the cpu node once there are no cpu handles */ diff --git a/arch/powerpc/include/asm/mp.h b/arch/powerpc/include/asm/mp.h index 3ffa30b..fe490ba 100644 --- a/arch/powerpc/include/asm/mp.h +++ b/arch/powerpc/include/asm/mp.h @@ -28,4 +28,10 @@ void cpu_mp_lmb_reserve(struct lmb *lmb); u32 determine_mp_bootpg(void); int is_core_disabled(int nr); +#ifdef CONFIG_E6500 +#define thread_to_core(x) (x >> 1) +#else +#define thread_to_core(x) (x) +#endif + #endif -- cgit v1.1 From 744713a6a3ca19c77585a9452829a2e2a55693ad Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:22:36 +0000 Subject: powerpc/mpc85xx: Skip zero values for DDR debug registers Some debug registers have non-zero default out of reset. If software is not setting debug registers, skip writing to them to avoid unnecessary overriding. Also add debug messages for workarounds and debug registers. Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/ddr-gen3.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c index 81961de..0761d70 100644 --- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c +++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -43,6 +43,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, out_be32(&ddr->eor, regs->ddr_eor); #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 + debug("Workaround for ERRATUM_DDR111_DDR134\n"); for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { cs_sa = (regs->cs[i].bnds >> 16) & 0xfff; cs_ea = regs->cs[i].bnds & 0xfff; @@ -115,8 +116,12 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, out_be32(&ddr->ddr_cdr2, regs->ddr_cdr2); out_be32(&ddr->err_disable, regs->err_disable); out_be32(&ddr->err_int_en, regs->err_int_en); - for (i = 0; i < 32; i++) - out_be32(&ddr->debug[i], regs->debug[i]); + for (i = 0; i < 32; i++) { + if (regs->debug[i]) { + debug("Write to debug_%d as %08x\n", i+1, regs->debug[i]); + out_be32(&ddr->debug[i], regs->debug[i]); + } + } #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003474 out_be32(&ddr->debug[12], 0x00000015); @@ -128,6 +133,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN); out_be32(&ddr->sdram_cfg, temp_sdram_cfg); #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003 + debug("Workaround for ERRATUM_DDR_A003\n"); if (regs->ddr_sdram_rcw_2 & 0x00f00000) { out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2 & 0xf07fffff); out_be32(&ddr->debug[2], 0x00000400); @@ -209,6 +215,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, * This erratum does not affect DDR3 mode, only for DDR2 mode. */ #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_115 + debug("Workaround for ERRATUM_DDR_115\n"); if ((((in_be32(&ddr->sdram_cfg) >> 24) & 0x7) == SDRAM_TYPE_DDR2) && in_be32(&ddr->sdram_cfg) & 0x80000) { /* set DEBUG_1[31] */ @@ -216,6 +223,7 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, } #endif #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 + debug("Workaround for ERRATUM_DDR111_DDR134\n"); /* * This is the combined workaround for DDR111 and DDR134 * following the published errata for MPC8572 -- cgit v1.1 From 73b5396b25c52463aa71c782316e2d77a4b8d5ed Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:22:37 +0000 Subject: powerpc/mpc8xxx: Add fine timing support for DDR3 When the DDR3 speed goes higher, we need to utilize fine offset from SPD. Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c | 25 +++++++++++++++++++------ arch/powerpc/cpu/mpc8xxx/ddr/interactive.c | 22 ++++++++++++++++------ arch/powerpc/include/asm/fsl_ddr_dimm_params.h | 1 + include/ddr_spd.h | 7 ++++++- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c index d0a5466..3e7c269 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2009 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * Dave Liu * * calculate the organization and timing parameter @@ -90,6 +90,7 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, { unsigned int retval; unsigned int mtb_ps; + int ftb_10th_ps; int i; if (spd->mem_type) { @@ -197,6 +198,14 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, pdimm->mtb_ps = mtb_ps; /* + * FTB - fine timebase + * use 1/10th of ps as our unit to avoid floating point + * eg, 10 for 1ps, 25 for 2.5ps, 50 for 5ps + */ + ftb_10th_ps = + ((spd->ftb_div & 0xf0) >> 4) * 10 / (spd->ftb_div & 0x0f); + pdimm->ftb_10th_ps = ftb_10th_ps; + /* * sdram minimum cycle time * we assume the MTB is 0.125ns * eg: @@ -204,7 +213,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * =12 MTB (1.5ns) ->DDR3-1333 * =10 MTB (1.25ns) ->DDR3-1600 */ - pdimm->tCKmin_X_ps = spd->tCK_min * mtb_ps; + pdimm->tCKmin_X_ps = spd->tCK_min * mtb_ps + + (spd->fine_tCK_min * ftb_10th_ps) / 10; /* * CAS latency supported @@ -222,7 +232,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25ns) */ - pdimm->tAA_ps = spd->tAA_min * mtb_ps; + pdimm->tAA_ps = spd->tAA_min * mtb_ps + + (spd->fine_tAA_min * ftb_10th_ps) / 10; /* * min write recovery time @@ -239,7 +250,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25) */ - pdimm->tRCD_ps = spd->tRCD_min * mtb_ps; + pdimm->tRCD_ps = spd->tRCD_min * mtb_ps + + (spd->fine_tRCD_min * ftb_10th_ps) / 10; /* * min row active to row active delay time @@ -257,7 +269,8 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1333H 108 MTB (13.5ns) * DDR3-1600H 90 MTB (11.25ns) */ - pdimm->tRP_ps = spd->tRP_min * mtb_ps; + pdimm->tRP_ps = spd->tRP_min * mtb_ps + + (spd->fine_tRP_min * ftb_10th_ps) / 10; /* min active to precharge delay time * eg: tRAS_min = @@ -277,7 +290,7 @@ ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd, * DDR3-1600H 370 MTB (46.25ns) */ pdimm->tRC_ps = (((spd->tRAS_tRC_ext & 0xf0) << 4) | spd->tRC_min_lsb) - * mtb_ps; + * mtb_ps + (spd->fine_tRC_min * ftb_10th_ps) / 10; /* * min refresh recovery delay time * eg: tRFC_min = diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c index 5b72437..738c808 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2010-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -1121,11 +1121,21 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) "therm_sensor SDRAM Thermal Sensor"); PRINT_NXS(33, spd->device_type, "device_type SDRAM Device Type"); - - printf("%-3d-%3d: ", 34, 59); /* Reserved, General Section */ - - for (i = 34; i <= 59; i++) - printf("%02x ", spd->res_34_59[i - 34]); + PRINT_NXS(34, spd->fine_tCK_min, + "fine_tCK_min Fine offset for tCKmin"); + PRINT_NXS(35, spd->fine_tAA_min, + "fine_tAA_min Fine offset for tAAmin"); + PRINT_NXS(36, spd->fine_tRCD_min, + "fine_tRCD_min Fine offset for tRCDmin"); + PRINT_NXS(37, spd->fine_tRP_min, + "fine_tRP_min Fine offset for tRPmin"); + PRINT_NXS(38, spd->fine_tRC_min, + "fine_tRC_min Fine offset for tRCmin"); + + printf("%-3d-%3d: ", 39, 59); /* Reserved, General Section */ + + for (i = 39; i <= 59; i++) + printf("%02x ", spd->res_39_59[i - 39]); puts("\n"); diff --git a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h index 982b809..ffe4db8 100644 --- a/arch/powerpc/include/asm/fsl_ddr_dimm_params.h +++ b/arch/powerpc/include/asm/fsl_ddr_dimm_params.h @@ -43,6 +43,7 @@ typedef struct dimm_params_s { /* DIMM timing parameters */ unsigned int mtb_ps; /* medium timebase ps, only for ddr3 */ + unsigned int ftb_10th_ps; /* fine timebase, in 1/10 ps, only for ddr3 */ unsigned int tAA_ps; /* minimum CAS latency time, only for ddr3 */ unsigned int tFAW_ps; /* four active window delay, only for ddr3 */ diff --git a/include/ddr_spd.h b/include/ddr_spd.h index a9230b9..9e74d87 100644 --- a/include/ddr_spd.h +++ b/include/ddr_spd.h @@ -221,7 +221,12 @@ typedef struct ddr3_spd_eeprom_s { unsigned char therm_ref_opt; /* 31 SDRAM Thermal and Refresh Opts */ unsigned char therm_sensor; /* 32 Module Thermal Sensor */ unsigned char device_type; /* 33 SDRAM device type */ - unsigned char res_34_59[26]; /* 34-59 Reserved, General Section */ + int8_t fine_tCK_min; /* 34 Fine offset for tCKmin */ + int8_t fine_tAA_min; /* 35 Fine offset for tAAmin */ + int8_t fine_tRCD_min; /* 36 Fine offset for tRCDmin */ + int8_t fine_tRP_min; /* 37 Fine offset for tRPmin */ + int8_t fine_tRC_min; /* 38 Fine offset for tRCmin */ + unsigned char res_39_59[21]; /* 39-59 Reserved, General Section */ /* Module-Specific Section: Bytes 60-116 */ union { -- cgit v1.1 From fcea30688fd8c47d54473ffd0f551a5e6efc74a0 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:22:38 +0000 Subject: powerpc/mpc8xxx: Add support for cas latency 12 and above Required by JEDEC 79-3E for high speed DDR3. Also change "CSn disabled" message to debug. Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c index 2067d53..a8b2132 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -825,7 +825,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, /* Mode Register - MR0 */ unsigned int dll_on; /* DLL control for precharge PD, 0=off, 1=on */ - unsigned int wr; /* Write Recovery */ + unsigned int wr = 0; /* Write Recovery */ unsigned int dll_rst; /* DLL Reset */ unsigned int mode; /* Normal=0 or Test=1 */ unsigned int caslat = 4;/* CAS# latency, default set as 6 cycles */ @@ -885,24 +885,37 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, dll_on = 1; wr_mclk = (common_dimm->tWR_ps + mclk_ps - 1) / mclk_ps; - wr = wr_table[wr_mclk - 5]; + if (wr_mclk <= 16) { + wr = wr_table[wr_mclk - 5]; + } else { + printf("Error: unsupported write recovery for mode register " + "wr_mclk = %d\n", wr_mclk); + } dll_rst = 0; /* dll no reset */ mode = 0; /* normal mode */ /* look up table to get the cas latency bits */ - if (cas_latency >= 5 && cas_latency <= 11) { - unsigned char cas_latency_table[7] = { + if (cas_latency >= 5 && cas_latency <= 16) { + unsigned char cas_latency_table[] = { 0x2, /* 5 clocks */ 0x4, /* 6 clocks */ 0x6, /* 7 clocks */ 0x8, /* 8 clocks */ 0xa, /* 9 clocks */ 0xc, /* 10 clocks */ - 0xe /* 11 clocks */ + 0xe, /* 11 clocks */ + 0x1, /* 12 clocks */ + 0x3, /* 13 clocks */ + 0x5, /* 14 clocks */ + 0x7, /* 15 clocks */ + 0x9, /* 16 clocks */ }; caslat = cas_latency_table[cas_latency - 5]; + } else { + printf("Error: unsupported cas latency for mode register\n"); } + bt = 0; /* Nibble sequential */ switch (popts->burst_length) { @@ -930,6 +943,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr, | ((mode & 0x1) << 7) | (((caslat >> 1) & 0x7) << 4) | ((bt & 0x1) << 3) + | ((caslat & 1) << 2) | ((bl & 0x3) << 0) ); @@ -1574,7 +1588,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, set_csn_config(dimm_number, i, ddr, popts, dimm_params); set_csn_config_2(i, ddr); } else - printf("CS%d is disabled.\n", i); + debug("CS%d is disabled.\n", i); } /* -- cgit v1.1 From a4c66509f1b95884e5753d5a30cf2cf884adb821 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:22:39 +0000 Subject: powerpc/mpc8xxx: Enable 3-way and 4-way DDR interleaving Restructure DDR interleaving option to support 3 and 4 DDR controllers for 2-, 3- and 4-way interleaving. Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/cpu.c | 12 +- arch/powerpc/cpu/mpc85xx/ddr-gen3.c | 12 ++ arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 144 +++++---------- arch/powerpc/cpu/mpc8xxx/ddr/main.c | 305 +++++++++++++++++-------------- arch/powerpc/cpu/mpc8xxx/ddr/options.c | 211 +++++++++++++++------ arch/powerpc/cpu/mpc8xxx/ddr/util.c | 67 ++++--- arch/powerpc/include/asm/fsl_ddr_sdram.h | 7 + arch/powerpc/include/asm/fsl_law.h | 12 +- arch/powerpc/include/asm/immap_85xx.h | 3 + doc/README.fsl-ddr | 36 +++- 10 files changed, 489 insertions(+), 320 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 8d2ef9f..5ddb294 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -430,11 +430,21 @@ static void dump_spd_ddr_reg(void) case 0: ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR; break; -#ifdef CONFIG_SYS_MPC85xx_DDR2_ADDR +#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) case 1: ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR; break; #endif +#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) + case 2: + ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR; + break; +#endif +#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) + case 3: + ddr[i] = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR; + break; +#endif default: printf("%s unexpected controller number = %u\n", __func__, i); diff --git a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c index 0761d70..ca4ed62 100644 --- a/arch/powerpc/cpu/mpc85xx/ddr-gen3.c +++ b/arch/powerpc/cpu/mpc85xx/ddr-gen3.c @@ -32,9 +32,21 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, case 0: ddr = (void *)CONFIG_SYS_MPC85xx_DDR_ADDR; break; +#if defined(CONFIG_SYS_MPC85xx_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) case 1: ddr = (void *)CONFIG_SYS_MPC85xx_DDR2_ADDR; break; +#endif +#if defined(CONFIG_SYS_MPC85xx_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) + case 2: + ddr = (void *)CONFIG_SYS_MPC85xx_DDR3_ADDR; + break; +#endif +#if defined(CONFIG_SYS_MPC85xx_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) + case 3: + ddr = (void *)CONFIG_SYS_MPC85xx_DDR4_ADDR; + break; +#endif default: printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num); return; diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c index a8b2132..5938c44 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c @@ -151,8 +151,19 @@ static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr, if (dimm_params[dimm_number].n_ranks > 0) { go_config = 1; /* These fields only available in CS0_CONFIG */ - intlv_en = popts->memctl_interleaving; - intlv_ctl = popts->memctl_interleaving_mode; + if (!popts->memctl_interleaving) + break; + switch (popts->memctl_interleaving_mode) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + intlv_en = popts->memctl_interleaving; + intlv_ctl = popts->memctl_interleaving_mode; + break; + default: + break; + } } break; case 1: @@ -1413,73 +1424,37 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, /* Chip Select Memory Bounds (CSn_BNDS) */ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { - unsigned long long ea = 0, sa = 0; + unsigned long long ea, sa; unsigned int cs_per_dimm = CONFIG_CHIP_SELECTS_PER_CTRL / CONFIG_DIMM_SLOTS_PER_CTLR; unsigned int dimm_number = i / cs_per_dimm; unsigned long long rank_density - = dimm_params[dimm_number].rank_density; + = dimm_params[dimm_number].rank_density >> dbw_cap_adj; - if (((i == 1) && (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1)) || - ((i == 2) && (popts->ba_intlv_ctl & 0x04)) || - ((i == 3) && (popts->ba_intlv_ctl & FSL_DDR_CS2_CS3))) { - /* - * Don't set up boundaries for unused CS - * cs1 for cs0_cs1, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3 - * cs2 for cs0_cs1_cs2_cs3 - * cs3 for cs2_cs3, cs0_cs1_and_cs2_cs3, cs0_cs1_cs2_cs3 - * But we need to set the ODT_RD_CFG and - * ODT_WR_CFG for CS1_CONFIG here. - */ - set_csn_config(dimm_number, i, ddr, popts, dimm_params); - continue; - } if (dimm_params[dimm_number].n_ranks == 0) { debug("Skipping setup of CS%u " "because n_ranks on DIMM %u is 0\n", i, dimm_number); continue; } - if (popts->memctl_interleaving && popts->ba_intlv_ctl) { - /* - * This works superbank 2CS - * There are 2 or more memory controllers configured - * identically, memory is interleaved between them, - * and each controller uses rank interleaving within - * itself. Therefore the starting and ending address - * on each controller is twice the amount present on - * each controller. If any CS is not included in the - * interleaving, the memory on that CS is not accssible - * and the total memory size is reduced. The CS is also - * disabled. - */ - unsigned long long ctlr_density = 0; + if (popts->memctl_interleaving) { switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { + case FSL_DDR_CS0_CS1_CS2_CS3: + break; case FSL_DDR_CS0_CS1: case FSL_DDR_CS0_CS1_AND_CS2_CS3: - ctlr_density = dimm_params[0].rank_density * 2; if (i > 1) cs_en = 0; break; case FSL_DDR_CS2_CS3: - ctlr_density = dimm_params[0].rank_density; + default: if (i > 0) cs_en = 0; break; - case FSL_DDR_CS0_CS1_CS2_CS3: - /* - * The four CS interleaving should have been verified by - * populate_memctl_options() - */ - ctlr_density = dimm_params[0].rank_density * 4; - break; - default: - break; } - ea = (CONFIG_NUM_DDR_CONTROLLERS * - (ctlr_density >> dbw_cap_adj)) - 1; - } - else if (!popts->memctl_interleaving && popts->ba_intlv_ctl) { + sa = common_dimm->base_address; + ea = common_dimm->total_mem - 1; + } else if (!popts->memctl_interleaving) { /* * If memory interleaving between controllers is NOT * enabled, the starting address for each memory @@ -1491,49 +1466,40 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, */ switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) { case FSL_DDR_CS0_CS1_CS2_CS3: - /* CS0+CS1+CS2+CS3 interleaving, only CS0_CNDS - * needs to be set. - */ sa = common_dimm->base_address; - ea = sa + (4 * (rank_density >> dbw_cap_adj))-1; + ea = common_dimm->total_mem - 1; break; case FSL_DDR_CS0_CS1_AND_CS2_CS3: - /* CS0+CS1 and CS2+CS3 interleaving, CS0_CNDS - * and CS2_CNDS need to be set. - */ - if ((i == 2) && (dimm_number == 0)) { + if ((i >= 2) && (dimm_number == 0)) { sa = dimm_params[dimm_number].base_address + - 2 * (rank_density >> dbw_cap_adj); - ea = sa + 2 * (rank_density >> dbw_cap_adj) - 1; + 2 * rank_density; + ea = sa + 2 * rank_density - 1; } else { sa = dimm_params[dimm_number].base_address; - ea = sa + (2 * (rank_density >> - dbw_cap_adj)) - 1; + ea = sa + 2 * rank_density - 1; } break; case FSL_DDR_CS0_CS1: - /* CS0+CS1 interleaving, CS0_CNDS needs - * to be set - */ if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); + ea = sa + rank_density - 1; + if (i != 1) + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; } else { sa = 0; ea = 0; } if (i == 0) - ea += (rank_density >> dbw_cap_adj); + ea += rank_density; break; case FSL_DDR_CS2_CS3: - /* CS2+CS3 interleaving*/ if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); + ea = sa + rank_density - 1; + if (i != 3) + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; } else { sa = 0; ea = 0; @@ -1542,38 +1508,18 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, ea += (rank_density >> dbw_cap_adj); break; default: /* No bank(chip-select) interleaving */ + sa = dimm_params[dimm_number].base_address; + ea = sa + rank_density - 1; + if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { + sa += (i % cs_per_dimm) * rank_density; + ea += (i % cs_per_dimm) * rank_density; + } else { + sa = 0; + ea = 0; + } break; } } - else if (popts->memctl_interleaving && !popts->ba_intlv_ctl) { - /* - * Only the rank on CS0 of each memory controller may - * be used if memory controller interleaving is used - * without rank interleaving within each memory - * controller. However, the ending address programmed - * into each CS0 must be the sum of the amount of - * memory in the two CS0 ranks. - */ - if (i == 0) { - ea = (2 * (rank_density >> dbw_cap_adj)) - 1; - } - - } - else if (!popts->memctl_interleaving && !popts->ba_intlv_ctl) { - /* - * No rank interleaving and no memory controller - * interleaving. - */ - sa = dimm_params[dimm_number].base_address; - ea = sa + (rank_density >> dbw_cap_adj) - 1; - if (dimm_params[dimm_number].n_ranks > (i % cs_per_dimm)) { - sa += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - ea += (i % cs_per_dimm) * (rank_density >> dbw_cap_adj); - } else { - sa = 0; - ea = 0; - } - } sa >>= 24; ea >>= 24; diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c index c2a03e3..4fd4f8f 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -15,13 +15,15 @@ #include #include #include +#include #include "ddr.h" -extern void fsl_ddr_set_lawbar( +void fsl_ddr_set_lawbar( const common_timing_params_t *memctl_common_params, unsigned int memctl_interleaved, unsigned int ctrl_num); +void fsl_ddr_set_intl3r(const unsigned int granule_size); /* processor specific function */ extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, @@ -51,6 +53,22 @@ u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ }; +#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) +u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { + [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ + [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ + [2][0] = SPD_EEPROM_ADDRESS3, /* controller 3 */ +}; +#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { + [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ + [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ + [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ + [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ + [2][0] = SPD_EEPROM_ADDRESS5, /* controller 3 */ + [2][1] = SPD_EEPROM_ADDRESS6, /* controller 3 */ +}; + #endif static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address) @@ -156,12 +174,12 @@ const char * step_to_string(unsigned int step) { return step_string_tbl[s]; } -int step_assign_addresses(fsl_ddr_info_t *pinfo, - unsigned int dbw_cap_adj[], - unsigned int *all_memctl_interleaving, - unsigned int *all_ctlr_rank_interleaving) +unsigned long long step_assign_addresses(fsl_ddr_info_t *pinfo, + unsigned int dbw_cap_adj[]) { int i, j; + unsigned long long total_mem, current_mem_base, total_ctlr_mem; + unsigned long long rank_density, ctlr_density = 0; /* * If a reduced data width is requested, but the SPD @@ -220,86 +238,108 @@ int step_assign_addresses(fsl_ddr_info_t *pinfo, "specified controller %u\n", i); return 1; } + debug("dbw_cap_adj[%d]=%d\n", i, dbw_cap_adj[i]); } - j = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - if (pinfo->memctl_opts[i].memctl_interleaving) - j++; - /* - * Not support less than all memory controllers interleaving - * if more than two controllers - */ - if (j == CONFIG_NUM_DDR_CONTROLLERS) - *all_memctl_interleaving = 1; - - /* Check that all controllers are rank interleaving. */ - j = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - if (pinfo->memctl_opts[i].ba_intlv_ctl) - j++; - /* - * All memory controllers must be populated to qualify for - * all controller rank interleaving - */ - if (j == CONFIG_NUM_DDR_CONTROLLERS) - *all_ctlr_rank_interleaving = 1; - - if (*all_memctl_interleaving) { - unsigned long long addr, total_mem_per_ctlr = 0; - /* - * If interleaving between memory controllers, - * make each controller start at a base address - * of 0. - * - * Also, if bank interleaving (chip select - * interleaving) is enabled on each memory - * controller, CS0 needs to be programmed to - * cover the entire memory range on that memory - * controller - * - * Bank interleaving also implies that each - * addressed chip select is identical in size. - */ - + current_mem_base = 0ull; + total_mem = 0; + if (pinfo->memctl_opts[0].memctl_interleaving) { + rank_density = pinfo->dimm_params[0][0].rank_density >> + dbw_cap_adj[0]; + switch (pinfo->memctl_opts[0].ba_intlv_ctl & + FSL_DDR_CS0_CS1_CS2_CS3) { + case FSL_DDR_CS0_CS1_CS2_CS3: + ctlr_density = 4 * rank_density; + break; + case FSL_DDR_CS0_CS1: + case FSL_DDR_CS0_CS1_AND_CS2_CS3: + ctlr_density = 2 * rank_density; + break; + case FSL_DDR_CS2_CS3: + default: + ctlr_density = rank_density; + break; + } + debug("rank density is 0x%llx, ctlr density is 0x%llx\n", + rank_density, ctlr_density); for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - addr = 0; - pinfo->common_timing_params[i].base_address = 0ull; - for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { - unsigned long long cap - = pinfo->dimm_params[i][j].capacity; - - pinfo->dimm_params[i][j].base_address = addr; - addr += cap >> dbw_cap_adj[i]; - total_mem_per_ctlr += cap >> dbw_cap_adj[i]; + if (pinfo->memctl_opts[i].memctl_interleaving) { + switch (pinfo->memctl_opts[i].memctl_interleaving_mode) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + total_ctlr_mem = 2 * ctlr_density; + break; + case FSL_DDR_3WAY_1KB_INTERLEAVING: + case FSL_DDR_3WAY_4KB_INTERLEAVING: + case FSL_DDR_3WAY_8KB_INTERLEAVING: + total_ctlr_mem = 3 * ctlr_density; + break; + case FSL_DDR_4WAY_1KB_INTERLEAVING: + case FSL_DDR_4WAY_4KB_INTERLEAVING: + case FSL_DDR_4WAY_8KB_INTERLEAVING: + total_ctlr_mem = 4 * ctlr_density; + break; + default: + panic("Unknown interleaving mode"); + } + pinfo->common_timing_params[i].base_address = + current_mem_base; + pinfo->common_timing_params[i].total_mem = + total_ctlr_mem; + total_mem = current_mem_base + total_ctlr_mem; + debug("ctrl %d base 0x%llx\n", i, current_mem_base); + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); + } else { + /* when 3rd controller not interleaved */ + current_mem_base = total_mem; + total_ctlr_mem = 0; + pinfo->common_timing_params[i].base_address = + current_mem_base; + for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { + unsigned long long cap = + pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; + pinfo->dimm_params[i][j].base_address = + current_mem_base; + debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); + current_mem_base += cap; + total_ctlr_mem += cap; + } + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); + pinfo->common_timing_params[i].total_mem = + total_ctlr_mem; + total_mem += total_ctlr_mem; } } - pinfo->common_timing_params[0].total_mem = total_mem_per_ctlr; } else { /* * Simple linear assignment if memory * controllers are not interleaved. */ - unsigned long long cur_memsize = 0; for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - u64 total_mem_per_ctlr = 0; + total_ctlr_mem = 0; pinfo->common_timing_params[i].base_address = - cur_memsize; + current_mem_base; for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { /* Compute DIMM base addresses. */ unsigned long long cap = - pinfo->dimm_params[i][j].capacity; + pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i]; pinfo->dimm_params[i][j].base_address = - cur_memsize; - cur_memsize += cap >> dbw_cap_adj[i]; - total_mem_per_ctlr += cap >> dbw_cap_adj[i]; + current_mem_base; + debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base); + current_mem_base += cap; + total_ctlr_mem += cap; } + debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem); pinfo->common_timing_params[i].total_mem = - total_mem_per_ctlr; + total_ctlr_mem; + total_mem += total_ctlr_mem; } } + debug("Total mem by %s is 0x%llx\n", __func__, total_mem); - return 0; + return total_mem; } unsigned long long @@ -307,8 +347,6 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, unsigned int size_only) { unsigned int i, j; - unsigned int all_controllers_memctl_interleaving = 0; - unsigned int all_controllers_rank_interleaving = 0; unsigned long long total_mem = 0; fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg; @@ -346,8 +384,9 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, retval = compute_dimm_parameters(spd, pdimm, i); #ifdef CONFIG_SYS_DDR_RAW_TIMING if (retval != 0) { - printf("SPD error! Trying fallback to " - "raw timing calculation\n"); + printf("SPD error on controller %d! " + "Trying fallback to raw timing " + "calculation\n", i); fsl_ddr_get_dimm_params(pdimm, i, j); } #else @@ -407,17 +446,14 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, &pinfo->memctl_opts[i], pinfo->dimm_params[i], i); } - check_interleaving_options(pinfo); case STEP_ASSIGN_ADDRESSES: /* STEP 5: Assign addresses to chip selects */ - step_assign_addresses(pinfo, - dbw_capacity_adjust, - &all_controllers_memctl_interleaving, - &all_controllers_rank_interleaving); + check_interleaving_options(pinfo); + total_mem = step_assign_addresses(pinfo, dbw_capacity_adjust); case STEP_COMPUTE_REGS: /* STEP 6: compute controller register values */ - debug("FSL Memory ctrl cg register computation\n"); + debug("FSL Memory ctrl register computation\n"); for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { if (timing_params[i].ndimms_present == 0) { memset(&ddr_reg[i], 0, @@ -437,21 +473,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, break; } - /* Compute the total amount of memory. */ - - /* - * If bank interleaving but NOT memory controller interleaving - * CS_BNDS describe the quantity of memory on each memory - * controller, so the total is the sum across. - */ - if (!all_controllers_memctl_interleaving - && all_controllers_rank_interleaving) { - total_mem = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - total_mem += timing_params[i].total_mem; - } - - } else { + { /* * Compute the amount of memory available just by * looking for the highest valid CSn_BNDS value. @@ -489,7 +511,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, phys_size_t fsl_ddr_sdram(void) { unsigned int i; - unsigned int memctl_interleaved; + unsigned int law_memctl = LAW_TRGT_IF_DDR_1; unsigned long long total_memory; fsl_ddr_info_t info; @@ -504,34 +526,6 @@ phys_size_t fsl_ddr_sdram(void) #endif total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 0); - /* Check for memory controller interleaving. */ - memctl_interleaved = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - memctl_interleaved += - info.memctl_opts[i].memctl_interleaving; - } - - if (memctl_interleaved) { - if (memctl_interleaved == CONFIG_NUM_DDR_CONTROLLERS) { - debug("memctl interleaving\n"); - /* - * Change the meaning of memctl_interleaved - * to be "boolean". - */ - memctl_interleaved = 1; - } else { - printf("Warning: memctl interleaving not " - "properly configured on all controllers\n"); - memctl_interleaved = 0; - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - info.memctl_opts[i].memctl_interleaving = 0; - debug("Recomputing with memctl_interleaving off.\n"); - total_memory = fsl_ddr_compute(&info, - STEP_ASSIGN_ADDRESSES, - 0); - } - } - /* Program configuration registers. */ for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { debug("Programming controller %u\n", i); @@ -544,24 +538,69 @@ phys_size_t fsl_ddr_sdram(void) fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i); } - if (memctl_interleaved) { - const unsigned int ctrl_num = 0; - - /* Only set LAWBAR1 if memory controller interleaving is on. */ - fsl_ddr_set_lawbar(&info.common_timing_params[0], - memctl_interleaved, ctrl_num); - } else { - /* - * Memory controller interleaving is NOT on; - * set each lawbar individually. - */ - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + /* program LAWs */ + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + if (info.memctl_opts[i].memctl_interleaving) { + switch (info.memctl_opts[i].memctl_interleaving_mode) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + if (i == 0) { + law_memctl = LAW_TRGT_IF_DDR_INTRLV; + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + } else if (i == 2) { + law_memctl = LAW_TRGT_IF_DDR_INTLV_34; + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + } + break; + case FSL_DDR_3WAY_1KB_INTERLEAVING: + case FSL_DDR_3WAY_4KB_INTERLEAVING: + case FSL_DDR_3WAY_8KB_INTERLEAVING: + law_memctl = LAW_TRGT_IF_DDR_INTLV_123; + if (i == 0) { + fsl_ddr_set_intl3r(info.memctl_opts[i].memctl_interleaving_mode); + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + } + break; + case FSL_DDR_4WAY_1KB_INTERLEAVING: + case FSL_DDR_4WAY_4KB_INTERLEAVING: + case FSL_DDR_4WAY_8KB_INTERLEAVING: + law_memctl = LAW_TRGT_IF_DDR_INTLV_1234; + if (i == 0) + fsl_ddr_set_lawbar(&info.common_timing_params[i], + law_memctl, i); + /* place holder for future 4-way interleaving */ + break; + default: + break; + } + } else { + switch (i) { + case 0: + law_memctl = LAW_TRGT_IF_DDR_1; + break; + case 1: + law_memctl = LAW_TRGT_IF_DDR_2; + break; + case 2: + law_memctl = LAW_TRGT_IF_DDR_3; + break; + case 3: + law_memctl = LAW_TRGT_IF_DDR_4; + break; + default: + break; + } fsl_ddr_set_lawbar(&info.common_timing_params[i], - 0, i); + law_memctl, i); } } - debug("total_memory = %llu\n", total_memory); + debug("total_memory by %s = %llu\n", __func__, total_memory); #if !defined(CONFIG_PHYS_64BIT) /* Check for 4G or more. Bad. */ diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c index 00ec57b..2923456 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c @@ -1,5 +1,5 @@ /* - * Copyright 2008, 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2008, 2010-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -790,46 +790,97 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, * should be a subset of the requested configuration. */ #if (CONFIG_NUM_DDR_CONTROLLERS > 1) - if (hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) { - if (pdimm[0].n_ranks == 0) { - printf("There is no rank on CS0 for controller %d. Because only" - " rank on CS0 and ranks chip-select interleaved with CS0" - " are controller interleaved, force non memory " - "controller interleaving\n", ctrl_num); - popts->memctl_interleaving = 0; - } else { - popts->memctl_interleaving = 1; - /* - * test null first. if CONFIG_HWCONFIG is not defined - * hwconfig_arg_cmp returns non-zero - */ - if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "null", buf)) { - popts->memctl_interleaving = 0; - debug("memory controller interleaving disabled.\n"); - } else if (hwconfig_subarg_cmp_f("fsl_ddr", - "ctlr_intlv", - "cacheline", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_CACHE_LINE_INTERLEAVING; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "page", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_PAGE_INTERLEAVING; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "bank", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_BANK_INTERLEAVING; - else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", - "superbank", buf)) - popts->memctl_interleaving_mode = - FSL_DDR_SUPERBANK_INTERLEAVING; - else { - popts->memctl_interleaving = 0; - printf("hwconfig has unrecognized parameter for ctlr_intlv.\n"); - } - } + if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) + goto done; + + if (pdimm[0].n_ranks == 0) { + printf("There is no rank on CS0 for controller %d.\n", ctrl_num); + popts->memctl_interleaving = 0; + goto done; + } + popts->memctl_interleaving = 1; + /* + * test null first. if CONFIG_HWCONFIG is not defined + * hwconfig_arg_cmp returns non-zero + */ + if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", + "null", buf)) { + popts->memctl_interleaving = 0; + debug("memory controller interleaving disabled.\n"); + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "cacheline", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_CACHE_LINE_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "page", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_PAGE_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "bank", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_BANK_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "superbank", buf)) { + popts->memctl_interleaving_mode = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : FSL_DDR_SUPERBANK_INTERLEAVING; + popts->memctl_interleaving = + ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + 0 : 1; +#if (CONFIG_NUM_DDR_CONTROLLERS == 3) + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "3way_1KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_3WAY_1KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "3way_4KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_3WAY_4KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "3way_8KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_3WAY_8KB_INTERLEAVING; +#elif (CONFIG_NUM_DDR_CONTROLLERS == 4) + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "4way_1KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_4WAY_1KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "4way_4KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_4WAY_4KB_INTERLEAVING; + } else if (hwconfig_subarg_cmp_f("fsl_ddr", + "ctlr_intlv", + "4way_8KB", buf)) { + popts->memctl_interleaving_mode = + FSL_DDR_4WAY_8KB_INTERLEAVING; +#endif + } else { + popts->memctl_interleaving = 0; + printf("hwconfig has unrecognized parameter for ctlr_intlv.\n"); } +done: #endif if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) && (CONFIG_CHIP_SELECTS_PER_CTRL > 1)) { @@ -859,20 +910,20 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for " "CS0+CS1+CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) { popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for " "CS0+CS1+CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } if (pdimm[0].capacity != pdimm[1].capacity) { popts->ba_intlv_ctl = 0; printf("Not identical DIMM size for " "CS0+CS1+CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #endif break; @@ -881,7 +932,7 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for " "CS0+CS1 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } break; case FSL_DDR_CS2_CS3: @@ -889,13 +940,13 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, if (pdimm[0].n_ranks < 4) { popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for CS2+CS3 " - "on controller %d, force non-interleaving!\n", ctrl_num); + "on controller %d, interleaving disabled!\n", ctrl_num); } #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) if (pdimm[1].n_ranks < 2) { popts->ba_intlv_ctl = 0; printf("Not enough bank(chip-select) for CS2+CS3 " - "on controller %d, force non-interleaving!\n", ctrl_num); + "on controller %d, interleaving disabled!\n", ctrl_num); } #endif break; @@ -905,14 +956,14 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, popts->ba_intlv_ctl = 0; printf("Not enough bank(CS) for CS0+CS1 and " "CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2) if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) { popts->ba_intlv_ctl = 0; printf("Not enough bank(CS) for CS0+CS1 and " "CS2+CS3 on controller %d, " - "force non-interleaving!\n", ctrl_num); + "interleaving disabled!\n", ctrl_num); } #endif break; @@ -954,33 +1005,73 @@ unsigned int populate_memctl_options(int all_DIMMs_registered, void check_interleaving_options(fsl_ddr_info_t *pinfo) { - int i, j, check_n_ranks, intlv_fixed = 0; + int i, j, k, check_n_ranks, intlv_invalid = 0; + unsigned int check_intlv, check_n_row_addr, check_n_col_addr; unsigned long long check_rank_density; + struct dimm_params_s *dimm; /* * Check if all controllers are configured for memory * controller interleaving. Identical dimms are recommended. At least - * the size should be checked. + * the size, row and col address should be checked. */ j = 0; check_n_ranks = pinfo->dimm_params[0][0].n_ranks; check_rank_density = pinfo->dimm_params[0][0].rank_density; + check_n_row_addr = pinfo->dimm_params[0][0].n_row_addr; + check_n_col_addr = pinfo->dimm_params[0][0].n_col_addr; + check_intlv = pinfo->memctl_opts[0].memctl_interleaving_mode; for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { - if ((pinfo->memctl_opts[i].memctl_interleaving) && \ - (check_rank_density == pinfo->dimm_params[i][0].rank_density) && \ - (check_n_ranks == pinfo->dimm_params[i][0].n_ranks)) { + dimm = &pinfo->dimm_params[i][0]; + if (!pinfo->memctl_opts[i].memctl_interleaving) { + continue; + } else if (((check_rank_density != dimm->rank_density) || + (check_n_ranks != dimm->n_ranks) || + (check_n_row_addr != dimm->n_row_addr) || + (check_n_col_addr != dimm->n_col_addr) || + (check_intlv != + pinfo->memctl_opts[i].memctl_interleaving_mode))){ + intlv_invalid = 1; + break; + } else { j++; } + } - if (j != CONFIG_NUM_DDR_CONTROLLERS) { + if (intlv_invalid) { for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) - if (pinfo->memctl_opts[i].memctl_interleaving) { + pinfo->memctl_opts[i].memctl_interleaving = 0; + printf("Not all DIMMs are identical. " + "Memory controller interleaving disabled.\n"); + } else { + switch (check_intlv) { + case FSL_DDR_CACHE_LINE_INTERLEAVING: + case FSL_DDR_PAGE_INTERLEAVING: + case FSL_DDR_BANK_INTERLEAVING: + case FSL_DDR_SUPERBANK_INTERLEAVING: + if (3 == CONFIG_NUM_DDR_CONTROLLERS) + k = 2; + else + k = CONFIG_NUM_DDR_CONTROLLERS; + break; + case FSL_DDR_3WAY_1KB_INTERLEAVING: + case FSL_DDR_3WAY_4KB_INTERLEAVING: + case FSL_DDR_3WAY_8KB_INTERLEAVING: + case FSL_DDR_4WAY_1KB_INTERLEAVING: + case FSL_DDR_4WAY_4KB_INTERLEAVING: + case FSL_DDR_4WAY_8KB_INTERLEAVING: + default: + k = CONFIG_NUM_DDR_CONTROLLERS; + break; + } + debug("%d of %d controllers are interleaving.\n", j, k); + if (j != k) { + for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) pinfo->memctl_opts[i].memctl_interleaving = 0; - intlv_fixed = 1; - } - if (intlv_fixed) - printf("Not all DIMMs are identical in size. " - "Memory controller interleaving disabled.\n"); + printf("Not all controllers have compatible " + "interleaving mode. All disabled.\n"); + } } + debug("Checking interleaving options completed\n"); } int fsl_use_spd(void) diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/util.c b/arch/powerpc/cpu/mpc8xxx/ddr/util.c index eb6a17a..664ad09 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/util.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/util.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -79,7 +79,7 @@ unsigned int mclk_to_picos(unsigned int mclk) void __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, - unsigned int memctl_interleaved, + unsigned int law_memctl, unsigned int ctrl_num) { unsigned long long base = memctl_common_params->base_address; @@ -98,28 +98,13 @@ __fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, if ((base + size) >= CONFIG_MAX_MEM_MAPPED) size = CONFIG_MAX_MEM_MAPPED - base; #endif - - if (ctrl_num == 0) { - /* - * Set up LAW for DDR controller 1 space. - */ - unsigned int lawbar1_target_id = memctl_interleaved - ? LAW_TRGT_IF_DDR_INTRLV : LAW_TRGT_IF_DDR_1; - - if (set_ddr_laws(base, size, lawbar1_target_id) < 0) { - printf("%s: ERROR (ctrl #0, intrlv=%d)\n", __func__, - memctl_interleaved); - return ; - } - } else if (ctrl_num == 1) { - if (set_ddr_laws(base, size, LAW_TRGT_IF_DDR_2) < 0) { - printf("%s: ERROR (ctrl #1)\n", __func__); - return ; - } - } else { - printf("%s: unexpected DDR controller number (%u)\n", __func__, - ctrl_num); + if (set_ddr_laws(base, size, law_memctl) < 0) { + printf("%s: ERROR (ctrl #%d, TRGT ID=%x)\n", __func__, ctrl_num, + law_memctl); + return ; } + debug("setup ddr law base = 0x%llx, size 0x%llx, TRGT_ID 0x%x\n", + base, size, law_memctl); } __attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void @@ -127,6 +112,15 @@ fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params, unsigned int memctl_interleaved, unsigned int ctrl_num); +void fsl_ddr_set_intl3r(const unsigned int granule_size) +{ +#ifdef CONFIG_E6500 + u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); + *mcintl3r = 0x80000000 | (granule_size & 0x1f); + debug("Enable MCINTL3R with granule size 0x%x\n", granule_size); +#endif +} + void board_add_ram_info(int use_default) { #if defined(CONFIG_MPC83xx) @@ -137,6 +131,9 @@ void board_add_ram_info(int use_default) #elif defined(CONFIG_MPC86xx) ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC86xx_DDR_ADDR); #endif +#if defined(CONFIG_E6500) && (CONFIG_NUM_DDR_CONTROLLERS == 3) + u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); +#endif #if (CONFIG_NUM_DDR_CONTROLLERS > 1) uint32_t cs0_config = in_be32(&ddr->cs0_config); #endif @@ -180,7 +177,29 @@ void board_add_ram_info(int use_default) else puts(", ECC off)"); -#if (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if (CONFIG_NUM_DDR_CONTROLLERS == 3) +#ifdef CONFIG_E6500 + if (*mcintl3r & 0x80000000) { + puts("\n"); + puts(" DDR Controller Interleaving Mode: "); + switch (*mcintl3r & 0x1f) { + case FSL_DDR_3WAY_1KB_INTERLEAVING: + puts("3-way 1KB"); + break; + case FSL_DDR_3WAY_4KB_INTERLEAVING: + puts("3-way 4KB"); + break; + case FSL_DDR_3WAY_8KB_INTERLEAVING: + puts("3-way 8KB"); + break; + default: + puts("3-way UNKNOWN"); + break; + } + } +#endif +#endif +#if (CONFIG_NUM_DDR_CONTROLLERS >= 2) if (cs0_config & 0x20000000) { puts("\n"); puts(" DDR Controller Interleaving Mode: "); diff --git a/arch/powerpc/include/asm/fsl_ddr_sdram.h b/arch/powerpc/include/asm/fsl_ddr_sdram.h index 157ae24..e271342 100644 --- a/arch/powerpc/include/asm/fsl_ddr_sdram.h +++ b/arch/powerpc/include/asm/fsl_ddr_sdram.h @@ -76,6 +76,13 @@ typedef ddr3_spd_eeprom_t generic_spd_eeprom_t; #define FSL_DDR_PAGE_INTERLEAVING 0x1 #define FSL_DDR_BANK_INTERLEAVING 0x2 #define FSL_DDR_SUPERBANK_INTERLEAVING 0x3 +#define FSL_DDR_3WAY_1KB_INTERLEAVING 0xA +#define FSL_DDR_3WAY_4KB_INTERLEAVING 0xC +#define FSL_DDR_3WAY_8KB_INTERLEAVING 0xD +/* placeholder for 4-way interleaving */ +#define FSL_DDR_4WAY_1KB_INTERLEAVING 0x1A +#define FSL_DDR_4WAY_4KB_INTERLEAVING 0x1C +#define FSL_DDR_4WAY_8KB_INTERLEAVING 0x1D /* DDR_SDRAM_CFG - DDR SDRAM Control Configuration */ diff --git a/arch/powerpc/include/asm/fsl_law.h b/arch/powerpc/include/asm/fsl_law.h index dc3985e..f9cec8e 100644 --- a/arch/powerpc/include/asm/fsl_law.h +++ b/arch/powerpc/include/asm/fsl_law.h @@ -60,8 +60,12 @@ enum law_trgt_if { LAW_TRGT_IF_DDR_1 = 0x10, LAW_TRGT_IF_DDR_2 = 0x11, /* 2nd controller */ + LAW_TRGT_IF_DDR_3 = 0x12, + LAW_TRGT_IF_DDR_4 = 0x13, LAW_TRGT_IF_DDR_INTRLV = 0x14, - + LAW_TRGT_IF_DDR_INTLV_34 = 0x15, + LAW_TRGT_IF_DDR_INTLV_123 = 0x17, + LAW_TRGT_IF_DDR_INTLV_1234 = 0x16, LAW_TRGT_IF_BMAN = 0x18, LAW_TRGT_IF_DCSR = 0x1d, LAW_TRGT_IF_LBC = 0x1f, @@ -87,6 +91,12 @@ enum law_trgt_if { LAW_TRGT_IF_DPAA_SWP_SRAM = 0x0e, LAW_TRGT_IF_DDR = 0x0f, LAW_TRGT_IF_DDR_2 = 0x16, /* 2nd controller */ + /* place holder for 3-way and 4-way interleaving */ + LAW_TRGT_IF_DDR_3, + LAW_TRGT_IF_DDR_4, + LAW_TRGT_IF_DDR_INTLV_34, + LAW_TRGT_IF_DDR_INTLV_123, + LAW_TRGT_IF_DDR_INTLV_1234, }; #define LAW_TRGT_IF_DDR_1 LAW_TRGT_IF_DDR #define LAW_TRGT_IF_PCI_1 LAW_TRGT_IF_PCI diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 412244e..7de33a7 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -2621,6 +2621,7 @@ struct ccsr_rman { #define CONFIG_SYS_FSL_CORENET_CCM_OFFSET 0x0000 #define CONFIG_SYS_MPC85xx_DDR_OFFSET 0x8000 #define CONFIG_SYS_MPC85xx_DDR2_OFFSET 0x9000 +#define CONFIG_SYS_MPC85xx_DDR3_OFFSET 0xA000 #define CONFIG_SYS_FSL_CORENET_CLK_OFFSET 0xE1000 #define CONFIG_SYS_FSL_CORENET_RCPM_OFFSET 0xE2000 #define CONFIG_SYS_FSL_CORENET_SERDES_OFFSET 0xEA000 @@ -2740,6 +2741,8 @@ struct ccsr_rman { (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR_OFFSET) #define CONFIG_SYS_MPC85xx_DDR2_ADDR \ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR2_OFFSET) +#define CONFIG_SYS_MPC85xx_DDR3_ADDR \ + (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR3_OFFSET) #define CONFIG_SYS_LBC_ADDR \ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_LBC_OFFSET) #define CONFIG_SYS_IFC_ADDR \ diff --git a/doc/README.fsl-ddr b/doc/README.fsl-ddr index 5e21658..f94b56f 100644 --- a/doc/README.fsl-ddr +++ b/doc/README.fsl-ddr @@ -1,5 +1,28 @@ - -Table of interleaving modes supported in cpu/8xxx/ddr/ +Table of interleaving 2-4 controllers +===================================== + +--------------+-----------------------------------------------------------+ + |Configuration | Memory Controller | + | | 1 2 3 4 | + |--------------+--------------+--------------+-----------------------------+ + | Two memory | Not Intlv'ed | Not Intlv'ed | | + | complexes +--------------+--------------+ | + | | 2-way Intlv'ed | | + |--------------+--------------+--------------+--------------+ | + | | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed | | + | Three memory +--------------+--------------+--------------+ | + | complexes | 2-way Intlv'ed | Not Intlv'ed | | + | +-----------------------------+--------------+ | + | | 3-way Intlv'ed | | + +--------------+--------------+--------------+--------------+--------------+ + | | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed | Not Intlv'ed | + | Four memory +--------------+--------------+--------------+--------------+ + | complexes | 2-way Intlv'ed | 2-way Intlv'ed | + | +-----------------------------+-----------------------------+ + | | 4-way Intlv'ed | + +--------------+-----------------------------------------------------------+ + + +Table of 2-way interleaving modes supported in cpu/8xxx/ddr/ ====================================================== +-------------+---------------------------------------------------------+ | | Rank Interleaving | @@ -56,6 +79,15 @@ The ways to configure the ddr interleaving mode # superbank setenv hwconfig "fsl_ddr:ctlr_intlv=superbank" + # 1KB 3-way interleaving + setenv hwconfig "fsl_ddr:ctlr_intlv=3way_1KB" + + # 4KB 3-way interleaving + setenv hwconfig "fsl_ddr:ctlr_intlv=3way_4KB" + + # 8KB 3-way interleaving + setenv hwconfig "fsl_ddr:ctlr_intlv=3way_8KB" + # disable bank (chip-select) interleaving setenv hwconfig "fsl_ddr:bank_intlv=null" -- cgit v1.1 From 45064adcae724bd5162f64f186fdb17bfef8ab42 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:22:40 +0000 Subject: powerpc/mpc8xxx: Fix bug for extended DDR timing Faster DDR3 timing requires parameters exceeding previously defined range. Extended parameters are fixed. Added some debug messages. Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c | 51 ++++++++++++++-------- .../cpu/mpc8xxx/ddr/lc_common_dimm_params.c | 12 ++++- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c index 5938c44..2592873 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c @@ -313,29 +313,41 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr, /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr, + const memctl_options_t *popts, const common_timing_params_t *common_dimm, unsigned int cas_latency) { + /* Extended precharge to activate interval (tRP) */ + unsigned int ext_pretoact = 0; /* Extended Activate to precharge interval (tRAS) */ unsigned int ext_acttopre = 0; - unsigned int ext_refrec; /* Extended refresh recovery time (tRFC) */ - unsigned int ext_caslat = 0; /* Extended MCAS latency from READ cmd */ - unsigned int cntl_adj = 0; /* Control Adjust */ - - /* If the tRAS > 19 MCLK, we use the ext mode */ - if (picos_to_mclk(common_dimm->tRAS_ps) > 0x13) - ext_acttopre = 1; - + /* Extended activate to read/write interval (tRCD) */ + unsigned int ext_acttorw = 0; + /* Extended refresh recovery time (tRFC) */ + unsigned int ext_refrec; + /* Extended MCAS latency from READ cmd */ + unsigned int ext_caslat = 0; + /* Extended last data to precharge interval (tWR) */ + unsigned int ext_wrrec = 0; + /* Control Adjust */ + unsigned int cntl_adj = 0; + + ext_pretoact = picos_to_mclk(common_dimm->tRP_ps) >> 4; + ext_acttopre = picos_to_mclk(common_dimm->tRAS_ps) >> 4; + ext_acttorw = picos_to_mclk(common_dimm->tRCD_ps) >> 4; + ext_caslat = (2 * cas_latency - 1) >> 4; ext_refrec = (picos_to_mclk(common_dimm->tRFC_ps) - 8) >> 4; - - /* If the CAS latency more than 8, use the ext mode */ - if (cas_latency > 8) - ext_caslat = 1; + /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */ + ext_wrrec = (picos_to_mclk(common_dimm->tWR_ps) + + (popts->OTF_burst_chop_en ? 2 : 0)) >> 4; ddr->timing_cfg_3 = (0 - | ((ext_acttopre & 0x1) << 24) - | ((ext_refrec & 0xF) << 16) - | ((ext_caslat & 0x1) << 12) + | ((ext_pretoact & 0x1) << 28) + | ((ext_acttopre & 0x2) << 24) + | ((ext_acttorw & 0x1) << 22) + | ((ext_refrec & 0x1F) << 16) + | ((ext_caslat & 0x3) << 12) + | ((ext_wrrec & 0x1) << 8) | ((cntl_adj & 0x7) << 0) ); debug("FSLDDR: timing_cfg_3 = 0x%08x\n", ddr->timing_cfg_3); @@ -397,15 +409,16 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr, * we need set extend bit for it at * TIMING_CFG_3[EXT_CASLAT] */ - if (cas_latency > 8) - cas_latency -= 8; caslat_ctrl = 2 * cas_latency - 1; #endif refrec_ctrl = picos_to_mclk(common_dimm->tRFC_ps) - 8; wrrec_mclk = picos_to_mclk(common_dimm->tWR_ps); - wrrec_mclk = wrrec_table[wrrec_mclk - 1]; + if (wrrec_mclk > 16) + printf("Error: WRREC doesn't support more than 16 clocks\n"); + else + wrrec_mclk = wrrec_table[wrrec_mclk - 1]; if (popts->OTF_burst_chop_en) wrrec_mclk += 2; @@ -1550,7 +1563,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, set_timing_cfg_0(ddr, popts); #endif - set_timing_cfg_3(ddr, common_dimm, cas_latency); + set_timing_cfg_3(ddr, popts, common_dimm, cas_latency); set_timing_cfg_1(ddr, popts, common_dimm, cas_latency); set_timing_cfg_2(ddr, popts, common_dimm, cas_latency, additive_latency); diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c index 20c7db0..a474a65 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2011 Freescale Semiconductor, Inc. + * Copyright 2008-2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -491,5 +491,15 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params, */ outpdimm->additive_latency = additive_latency; + debug("tCKmin_ps = %u\n", outpdimm->tCKmin_X_ps); + debug("tRCD_ps = %u\n", outpdimm->tRCD_ps); + debug("tRP_ps = %u\n", outpdimm->tRP_ps); + debug("tRAS_ps = %u\n", outpdimm->tRAS_ps); + debug("tWR_ps = %u\n", outpdimm->tWR_ps); + debug("tWTR_ps = %u\n", outpdimm->tWTR_ps); + debug("tRFC_ps = %u\n", outpdimm->tRFC_ps); + debug("tRRD_ps = %u\n", outpdimm->tRRD_ps); + debug("tRC_ps = %u\n", outpdimm->tRC_ps); + return 0; } -- cgit v1.1 From 7e4db27ffd11f3eea7e4dfc33354fd087f9257d8 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:22:41 +0000 Subject: powerpc/mpc8xxx DDR: Fix CAS latency calculation Empty slot should be skipped when calculating CAS latency. Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c index a474a65..03a784c 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/lc_common_dimm_params.c @@ -27,8 +27,10 @@ compute_cas_latency_ddr3(const dimm_params_t *dimm_params, /* compute the common CAS latency supported between slots */ tmp = dimm_params[0].caslat_X; - for (i = 1; i < number_of_dimms; i++) - tmp &= dimm_params[i].caslat_X; + for (i = 1; i < number_of_dimms; i++) { + if (dimm_params[i].n_ranks) + tmp &= dimm_params[i].caslat_X; + } common_caslat = tmp; /* compute the max tAAmin tCKmin between slots */ -- cgit v1.1 From 62f739fe465c41a2c5be0a46b3330c12b213dc07 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:22:42 +0000 Subject: powerpc/mpc8xxx DDR: Fall back to raw timing for first controller only Only the first DIMM of first controller should fall back to raw timing parameters if SPD is missing or corrupted. Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc8xxx/ddr/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c index 4fd4f8f..b47268c 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c @@ -383,7 +383,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, retval = compute_dimm_parameters(spd, pdimm, i); #ifdef CONFIG_SYS_DDR_RAW_TIMING - if (retval != 0) { + if (!i && !j && retval) { printf("SPD error on controller %d! " "Trying fallback to raw timing " "calculation\n", i); -- cgit v1.1 From 1d083ff2c4be7864aacec30a82d01e90b78e680a Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 08:22:43 +0000 Subject: powerpc/mpc8xxx DDR: Fix interactive DDR debugging Add one more argument to call function readline_into_buffer(). Fix print SPD format for negative values. Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc8xxx/ddr/interactive.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c index 738c808..f59d105 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c @@ -1047,7 +1047,7 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) /* General Section: Bytes 0-59 */ -#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, y); +#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, (u8)y); #define PRINT_NNXXS(n0, n1, x0, x1, s) \ printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1); @@ -1398,7 +1398,7 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) * No need to worry for buffer overflow here in * this function; readline() maxes out at CFG_CBSIZE */ - readline_into_buffer(prompt, buffer); + readline_into_buffer(prompt, buffer, 0); argc = parse_line(buffer, argv); if (argc == 0) continue; -- cgit v1.1 From 7ac3cc20e09e10051fb42e4bb2325177c8b32e86 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 17 Aug 2012 09:00:54 +0000 Subject: powerpc/mpc8xxx: Move HWCONFIG_BUFFER_SIZE into config.h Before proper environment is setup, we extract hwconfig and put it into a buffer with size HWCONFIG_BUFFER_SIZE. We need to enlarge the buffer to accommodate longer string. Since this macro is used in multiple files, we move it into arch/powerpc/include/asm/config.h. Signed-off-by: York Sun Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/cpu_init.c | 2 -- arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c | 2 -- arch/powerpc/cpu/mpc8xxx/ddr/options.c | 1 - arch/powerpc/include/asm/config.h | 4 ++++ 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index f293265..afb5671 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -48,8 +48,6 @@ #include "../../../../drivers/block/fsl_sata.h" -#define HWCONFIG_BUFFER_SIZE 128 - DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_QE diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index 8aac1de..2a68060 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -46,8 +46,6 @@ static u32 serdes_prtcl_map; -#define HWCONFIG_BUFFER_SIZE 128 - #ifdef DEBUG static const char *serdes_prtcl_str[] = { [NONE] = "NA", diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c index 2923456..13e4825 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c @@ -19,7 +19,6 @@ * This is pretty fragile on both the use of stack and if the buffer is big * enough. However we will get a warning from getenv_f for the later. */ -#define HWCONFIG_BUFFER_SIZE 128 /* Board-specific functions defined in each board's ddr.c */ extern void fsl_ddr_board_options(memctl_options_t *popts, diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h index d138636..67cea01 100644 --- a/arch/powerpc/include/asm/config.h +++ b/arch/powerpc/include/asm/config.h @@ -29,6 +29,10 @@ #include #endif +#ifndef HWCONFIG_BUFFER_SIZE + #define HWCONFIG_BUFFER_SIZE 256 +#endif + /* CONFIG_HARD_SPI triggers SPI bus initialization in PowerPC */ #if defined(CONFIG_MPC8XXX_SPI) || defined(CONFIG_FSL_ESPI) # ifndef CONFIG_HARD_SPI -- cgit v1.1 From 3ea21536d773b3b03ffd4005c7e7c3281a542bea Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Mon, 20 Aug 2012 13:10:08 +0000 Subject: powerpc/85xx: clear out TLB on boot Instead of just shooting down the entry that covers CCSR, clear out every TLB entry that isn't the one that we're executing out of. Signed-off-by: Scott Wood Signed-off-by: Andy Fleming --- arch/powerpc/cpu/mpc85xx/start.S | 76 ++++++++++++++++++++---------------- arch/powerpc/include/asm/mmu.h | 4 ++ arch/powerpc/include/asm/processor.h | 1 + 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index 66e8eb8..9e04257 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -435,12 +435,11 @@ l2_disabled: * Search for the TLB that covers the code we're executing, and shrink it * so that it covers only this 4K page. That will ensure that any other * TLB we create won't interfere with it. We assume that the TLB exists, - * which is why we don't check the Valid bit of MAS1. + * which is why we don't check the Valid bit of MAS1. We also assume + * it is in TLB1. * * This is necessary, for example, when booting from the on-chip ROM, * which (oddly) creates a single 4GB TLB that covers CCSR and DDR. - * If we don't shrink this TLB now, then we'll accidentally delete it - * in "purge_old_ccsr_tlb" below. */ bl nexti /* Find our address */ nexti: mflr r1 /* R1 = our PC */ @@ -450,11 +449,15 @@ nexti: mflr r1 /* R1 = our PC */ msync tlbsx 0, r1 /* This must succeed */ + mfspr r14, MAS0 /* Save ESEL for later */ + rlwinm r14, r14, 16, 0xfff + /* Set the size of the TLB to 4KB */ mfspr r3, MAS1 li r2, 0xF00 andc r3, r3, r2 /* Clear the TSIZE bits */ ori r3, r3, MAS1_TSIZE(BOOKE_PAGESZ_4K)@l + oris r3, r3, MAS1_IPROT@h mtspr MAS1, r3 /* @@ -489,6 +492,39 @@ nexti: mflr r1 /* R1 = our PC */ tlbwe /* + * Clear out any other TLB entries that may exist, to avoid conflicts. + * Our TLB entry is in r14. + */ + li r0, TLBIVAX_ALL | TLBIVAX_TLB0 + tlbivax 0, r0 + tlbsync + + mfspr r4, SPRN_TLB1CFG + rlwinm r4, r4, 0, TLBnCFG_NENTRY_MASK + + li r3, 0 + mtspr MAS1, r3 +1: cmpw r3, r14 +#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(CONFIG_NAND_SPL) + cmpwi cr1, r3, CONFIG_SYS_PPC_E500_DEBUG_TLB + cror cr0*4+eq, cr0*4+eq, cr1*4+eq +#endif + rlwinm r5, r3, 16, MAS0_ESEL_MSK + addi r3, r3, 1 + beq 2f /* skip the entry we're executing from */ + + oris r5, r5, MAS0_TLBSEL(1)@h + mtspr MAS0, r5 + + isync + tlbwe + isync + msync + +2: cmpw r3, r4 + blt 1b + +/* * Relocate CCSR, if necessary. We relocate CCSR if (obviously) the default * location is not where we want it. This typically happens on a 36-bit * system, where we want to move CCSR to near the top of 36-bit address space. @@ -506,41 +542,15 @@ nexti: mflr r1 /* R1 = our PC */ #error "CONFIG_SYS_CCSRBAR_PHYS_HIGH and CONFIG_SYS_CCSRBAR_PHYS_LOW) must be defined." #endif -purge_old_ccsr_tlb: - lis r8, CONFIG_SYS_CCSRBAR@h - ori r8, r8, CONFIG_SYS_CCSRBAR@l - lis r9, (CONFIG_SYS_CCSRBAR + 0x1000)@h - ori r9, r9, (CONFIG_SYS_CCSRBAR + 0x1000)@l - - /* - * In a multi-stage boot (e.g. NAND boot), a previous stage may have - * created a TLB for CCSR, which will interfere with our relocation - * code. Since we're going to create a new TLB for CCSR anyway, - * it should be safe to delete this old TLB here. We have to search - * for it, though. - */ - - li r1, 0 - mtspr MAS6, r1 /* Search the current address space and PID */ - isync - msync - tlbsx 0, r8 - mfspr r1, MAS1 - andis. r2, r1, MAS1_VALID@h /* Check for the Valid bit */ - beq 1f /* Skip if no TLB found */ - - rlwinm r1, r1, 0, 1, 31 /* Clear Valid bit */ - mtspr MAS1, r1 - isync - msync - tlbwe -1: - create_ccsr_new_tlb: /* * Create a TLB for the new location of CCSR. Register R8 is reserved * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR). */ + lis r8, CONFIG_SYS_CCSRBAR@h + ori r8, r8, CONFIG_SYS_CCSRBAR@l + lis r9, (CONFIG_SYS_CCSRBAR + 0x1000)@h + ori r9, r9, (CONFIG_SYS_CCSRBAR + 0x1000)@l lis r0, FSL_BOOKE_MAS0(0, 0, 0)@h ori r0, r0, FSL_BOOKE_MAS0(0, 0, 0)@l lis r1, FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@h diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 209103e..2e0e292 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -475,6 +475,10 @@ extern void print_bats(void); #define BOOKE_PAGESZ_256GB 14 #define BOOKE_PAGESZ_1TB 15 +#define TLBIVAX_ALL 4 +#define TLBIVAX_TLB0 0 +#define TLBIVAX_TLB1 8 + #ifdef CONFIG_E500 #ifndef __ASSEMBLY__ extern void set_tlb(u8 tlb, u32 epn, u64 rpn, diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index f3acd17..36695e2 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -515,6 +515,7 @@ #define SPRN_TLB0CFG 0x2B0 /* TLB 0 Config Register */ #define SPRN_TLB1CFG 0x2B1 /* TLB 1 Config Register */ +#define TLBnCFG_NENTRY_MASK 0x00000fff #define SPRN_TLB0PS 0x158 /* TLB 0 Page Size Register */ #define SPRN_TLB1PS 0x159 /* TLB 1 Page Size Register */ #define SPRN_MMUCSR0 0x3f4 /* MMU control and status register 0 */ -- cgit v1.1 From e2c91b95e167de34cbf462a5b074aefdc18d8d27 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Mon, 20 Aug 2012 13:16:30 +0000 Subject: powerpc/p1_p2_rdb_pc: print -PC suffix in board name Currently the -PC variants of the P1/P2 RDB boards do not print it on boot -- e.g. a P2020RDB-PC will claim to be a plain P2020RDB. Besides being incorrect, this can confuse a user into building U-Boot for P2020RDB rather than P2020RDB-PC, resulting in a board that does not boot. P1024RDB and P1025RDB are not included, as these boards apparently do not have -PC as part of their name, even though they are supported by p1_p2_rdb_pc. The P2020RDB variant covered by this is apparently P2020RDB-PCA rather than P2020RDB-PC. Signed-off-by: Scott Wood Signed-off-by: Andy Fleming --- include/configs/p1_p2_rdb_pc.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/configs/p1_p2_rdb_pc.h b/include/configs/p1_p2_rdb_pc.h index a8882d4..b18f4a0 100644 --- a/include/configs/p1_p2_rdb_pc.h +++ b/include/configs/p1_p2_rdb_pc.h @@ -31,7 +31,7 @@ #endif #if defined(CONFIG_P1020MBG) -#define CONFIG_BOARDNAME "P1020MBG" +#define CONFIG_BOARDNAME "P1020MBG-PC" #define CONFIG_P1020 #define CONFIG_VSC7385_ENET #define CONFIG_SLIC @@ -41,7 +41,7 @@ #endif #if defined(CONFIG_P1020UTM) -#define CONFIG_BOARDNAME "P1020UTM" +#define CONFIG_BOARDNAME "P1020UTM-PC" #define CONFIG_P1020 #define __SW_BOOT_MASK 0x03 #define __SW_BOOT_NOR 0xe0 @@ -49,7 +49,7 @@ #endif #if defined(CONFIG_P1020RDB) -#define CONFIG_BOARDNAME "P1020RDB" +#define CONFIG_BOARDNAME "P1020RDB-PC" #define CONFIG_NAND_FSL_ELBC #define CONFIG_P1020 #define CONFIG_SPI_FLASH @@ -64,7 +64,7 @@ #endif #if defined(CONFIG_P1021RDB) -#define CONFIG_BOARDNAME "P1021RDB" +#define CONFIG_BOARDNAME "P1021RDB-PC" #define CONFIG_NAND_FSL_ELBC #define CONFIG_P1021 #define CONFIG_QE @@ -111,7 +111,7 @@ #endif #if defined(CONFIG_P2020RDB) -#define CONFIG_BOARDNAME "P2020RDB" +#define CONFIG_BOARDNAME "P2020RDB-PCA" #define CONFIG_NAND_FSL_ELBC #define CONFIG_P2020 #define CONFIG_SPI_FLASH -- cgit v1.1 From 98ae9ac434debd96a86ed8d4b6714d757860838c Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Thu, 23 Aug 2012 12:00:31 -0500 Subject: Revert "powerpc: Fix declaration type for I/O functions" This reverts commit 20959471b5d07fdeb8603b918d80385aa2954711. --- arch/powerpc/include/asm/io.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index ec0bfae..9e20861 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -162,7 +162,7 @@ static inline void __raw_writel(unsigned int v, volatile void __iomem *addr) * is actually performed (i.e. the data has come back) before we start * executing any following instructions. */ -static inline u8 in_8(const volatile unsigned char __iomem *addr) +extern inline u8 in_8(const volatile unsigned char __iomem *addr) { u8 ret; @@ -173,7 +173,7 @@ static inline u8 in_8(const volatile unsigned char __iomem *addr) return ret; } -static inline void out_8(volatile unsigned char __iomem *addr, u8 val) +extern inline void out_8(volatile unsigned char __iomem *addr, u8 val) { __asm__ __volatile__("sync;\n" "stb%U0%X0 %1,%0;\n" @@ -181,7 +181,7 @@ static inline void out_8(volatile unsigned char __iomem *addr, u8 val) : "r" (val)); } -static inline u16 in_le16(const volatile unsigned short __iomem *addr) +extern inline u16 in_le16(const volatile unsigned short __iomem *addr) { u16 ret; @@ -192,7 +192,7 @@ static inline u16 in_le16(const volatile unsigned short __iomem *addr) return ret; } -static inline u16 in_be16(const volatile unsigned short __iomem *addr) +extern inline u16 in_be16(const volatile unsigned short __iomem *addr) { u16 ret; @@ -202,18 +202,18 @@ static inline u16 in_be16(const volatile unsigned short __iomem *addr) return ret; } -static inline void out_le16(volatile unsigned short __iomem *addr, u16 val) +extern inline void out_le16(volatile unsigned short __iomem *addr, u16 val) { __asm__ __volatile__("sync; sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } -static inline void out_be16(volatile unsigned short __iomem *addr, u16 val) +extern inline void out_be16(volatile unsigned short __iomem *addr, u16 val) { __asm__ __volatile__("sync; sth%U0%X0 %1,%0" : "=m" (*addr) : "r" (val)); } -static inline u32 in_le32(const volatile unsigned __iomem *addr) +extern inline u32 in_le32(const volatile unsigned __iomem *addr) { u32 ret; @@ -224,7 +224,7 @@ static inline u32 in_le32(const volatile unsigned __iomem *addr) return ret; } -static inline u32 in_be32(const volatile unsigned __iomem *addr) +extern inline u32 in_be32(const volatile unsigned __iomem *addr) { u32 ret; @@ -234,13 +234,13 @@ static inline u32 in_be32(const volatile unsigned __iomem *addr) return ret; } -static inline void out_le32(volatile unsigned __iomem *addr, u32 val) +extern inline void out_le32(volatile unsigned __iomem *addr, u32 val) { __asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } -static inline void out_be32(volatile unsigned __iomem *addr, u32 val) +extern inline void out_be32(volatile unsigned __iomem *addr, u32 val) { __asm__ __volatile__("sync; stw%U0%X0 %1,%0" : "=m" (*addr) : "r" (val)); } -- cgit v1.1 From d69dba367aed051663d0ee1ece013c8232bfa9f5 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Wed, 8 Aug 2012 15:06:18 +0000 Subject: powerpc/mpc85xx/p1_p2_rdb: add all LAWs during SPL LAW init is skipped in the SPL payload because it's assumed that the SPL has taken care of it -- so make sure the SPL loads all the LAWs as is done on other boards. This bug was introduced by: commit 4589728e214958a4e6e011a081a68d360c49d7a5 Author: Kumar Gala Date: Fri Nov 11 08:14:53 2011 -0600 powerpc/85xx: Fix builds of P1020/P2020RDB-PC_36BIT_NAND Size grew a bit so nand-spl didn't fit in 4k, reduce done by removing LAW entries not needed during SPL phase. Signed-off-by: Scott Wood --- board/freescale/p1_p2_rdb_pc/law.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/board/freescale/p1_p2_rdb_pc/law.c b/board/freescale/p1_p2_rdb_pc/law.c index 7968919..0da8300 100644 --- a/board/freescale/p1_p2_rdb_pc/law.c +++ b/board/freescale/p1_p2_rdb_pc/law.c @@ -25,13 +25,11 @@ #include struct law_entry law_table[] = { -#ifndef CONFIG_NAND_SPL SET_LAW(CONFIG_SYS_CPLD_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC), SET_LAW(CONFIG_SYS_PMC_BASE_PHYS, LAW_SIZE_64K, LAW_TRGT_IF_LBC), #ifdef CONFIG_VSC7385_ENET SET_LAW(CONFIG_SYS_VSC7385_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC), #endif -#endif SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_64M, LAW_TRGT_IF_LBC), #ifdef CONFIG_SYS_NAND_BASE_PHYS SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_1M, LAW_TRGT_IF_LBC), -- cgit v1.1 From 2c0e3de384f6a3323a1ffbf5db390b3081c3e102 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Tue, 21 Aug 2012 23:27:37 +0200 Subject: MIPS: factor out endianess flag handling to arch config.mk This is CPU independent and should be configured architecture-wide. Signed-off-by: Daniel Schwierzeck --- arch/mips/config.mk | 20 ++++++++++++++++++-- arch/mips/cpu/mips32/config.mk | 19 +------------------ arch/mips/cpu/xburst/config.mk | 3 +-- include/configs/qi_lb60.h | 1 + 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/arch/mips/config.mk b/arch/mips/config.mk index 6ab8acd..b680256 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -23,6 +23,22 @@ CROSS_COMPILE ?= mips_4KC- +# Handle special prefix in ELDK 4.0 toolchain +ifneq (,$(findstring 4KCle,$(CROSS_COMPILE))) +ENDIANNESS := -EL +endif + +ifdef CONFIG_SYS_LITTLE_ENDIAN +ENDIANNESS := -EL +endif + +ifdef CONFIG_SYS_BIG_ENDIAN +ENDIANNESS := -EB +endif + +# Default to EB if no endianess is configured +ENDIANNESS ?= -EB + CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__ @@ -47,8 +63,8 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__ # On the other hand, we want PIC in the U-Boot code to relocate it from ROM # to RAM. $28 is always used as gp. # -PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic +PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS) PLATFORM_CPPFLAGS += -msoft-float -PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib +PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS) PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections LDFLAGS_FINAL += --gc-sections diff --git a/arch/mips/cpu/mips32/config.mk b/arch/mips/cpu/mips32/config.mk index a1cd590..a0e4de5 100644 --- a/arch/mips/cpu/mips32/config.mk +++ b/arch/mips/cpu/mips32/config.mk @@ -29,21 +29,4 @@ # MIPSFLAGS := -march=mips32r2 -# Handle special prefix in ELDK 4.0 toolchain -ifneq (,$(findstring 4KCle,$(CROSS_COMPILE))) -ENDIANNESS := -EL -endif - -ifdef CONFIG_SYS_LITTLE_ENDIAN -ENDIANNESS := -EL -endif - -ifdef CONFIG_SYS_BIG_ENDIAN -ENDIANNESS := -EB -endif - -# Default to EB if no endianess is configured -ENDIANNESS ?= -EB - -PLATFORM_CPPFLAGS += $(MIPSFLAGS) $(ENDIANNESS) -PLATFORM_LDFLAGS += $(ENDIANNESS) +PLATFORM_CPPFLAGS += $(MIPSFLAGS) diff --git a/arch/mips/cpu/xburst/config.mk b/arch/mips/cpu/xburst/config.mk index bce0c1b..18d49ab 100644 --- a/arch/mips/cpu/xburst/config.mk +++ b/arch/mips/cpu/xburst/config.mk @@ -20,5 +20,4 @@ # MA 02111-1307 USA # -PLATFORM_CPPFLAGS += -march=mips32 -EL -PLATFORM_LDFLAGS += -EL +PLATFORM_CPPFLAGS += -march=mips32 diff --git a/include/configs/qi_lb60.h b/include/configs/qi_lb60.h index a3fc465..4bb5bbc 100644 --- a/include/configs/qi_lb60.h +++ b/include/configs/qi_lb60.h @@ -11,6 +11,7 @@ #define __CONFIG_QI_LB60_H #define CONFIG_MIPS32 /* MIPS32 CPU core */ +#define CONFIG_SYS_LITTLE_ENDIAN #define CONFIG_JZSOC /* Jz SoC */ #define CONFIG_JZ4740 /* Jz4740 SoC */ #define CONFIG_NAND_JZ4740 -- cgit v1.1 From 0efcdb15f991386fea9e8de614b058bce759d557 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Tue, 21 Aug 2012 23:38:25 +0200 Subject: MIPS: move CONFIG_STANDALONE_LOAD_ADDR to CPU config makefiles Prepare for upcoming MIPS64 CPU support. Signed-off-by: Daniel Schwierzeck --- arch/mips/config.mk | 2 -- arch/mips/cpu/mips32/config.mk | 2 ++ arch/mips/cpu/xburst/config.mk | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/mips/config.mk b/arch/mips/config.mk index b680256..de9140b 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -39,8 +39,6 @@ endif # Default to EB if no endianess is configured ENDIANNESS ?= -EB -CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds - PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__ # diff --git a/arch/mips/cpu/mips32/config.mk b/arch/mips/cpu/mips32/config.mk index a0e4de5..481e984 100644 --- a/arch/mips/cpu/mips32/config.mk +++ b/arch/mips/cpu/mips32/config.mk @@ -30,3 +30,5 @@ MIPSFLAGS := -march=mips32r2 PLATFORM_CPPFLAGS += $(MIPSFLAGS) + +CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds diff --git a/arch/mips/cpu/xburst/config.mk b/arch/mips/cpu/xburst/config.mk index 18d49ab..1536746 100644 --- a/arch/mips/cpu/xburst/config.mk +++ b/arch/mips/cpu/xburst/config.mk @@ -21,3 +21,5 @@ # PLATFORM_CPPFLAGS += -march=mips32 + +CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds -- cgit v1.1 From 748fd4a621a870d378e4e4f54df76a38fd5d3cba Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Thu, 23 Aug 2012 23:47:02 +0200 Subject: MIPS: add support for qemu for little endian MIPS32 CPUs Tested with 'qemu-system-mipsel -machine mips -bios u-boot.bin -nographic' Signed-off-by: Daniel Schwierzeck --- boards.cfg | 3 ++- include/configs/qemu-mips.h | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/boards.cfg b/boards.cfg index fdb84ad..6b54941 100644 --- a/boards.cfg +++ b/boards.cfg @@ -378,7 +378,8 @@ M5485FFE m68k mcf547x_8x m548xevb freescale - M5485GFE m68k mcf547x_8x m548xevb freescale - M5485EVB:SYS_BUSCLK=100000000,SYS_BOOTSZ=4,SYS_DRAMSZ=64 M5485HFE m68k mcf547x_8x m548xevb freescale - M5485EVB:SYS_BUSCLK=100000000,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_NOR1SZ=16,SYS_VIDEO microblaze-generic microblaze microblaze microblaze-generic xilinx -qemu_mips mips mips32 qemu-mips - - qemu-mips +qemu_mips mips mips32 qemu-mips - - qemu-mips:SYS_BIG_ENDIAN +qemu_mipsel mips mips32 qemu-mips - - qemu-mips:SYS_LITTLE_ENDIAN vct_platinum mips mips32 vct micronas - vct:VCT_PLATINUM vct_platinumavc mips mips32 vct micronas - vct:VCT_PLATINUMAVC vct_platinumavc_onenand mips mips32 vct micronas - vct:VCT_PLATINUMAVC,VCT_ONENAND diff --git a/include/configs/qemu-mips.h b/include/configs/qemu-mips.h index 306c173..b8b9705 100644 --- a/include/configs/qemu-mips.h +++ b/include/configs/qemu-mips.h @@ -100,7 +100,12 @@ */ #define CONFIG_SYS_LONGHELP /* undef to save memory */ -#define CONFIG_SYS_PROMPT "qemu-mips # " /* Monitor Command Prompt */ +/* Monitor Command Prompt */ +#if defined(CONFIG_SYS_LITTLE_ENDIAN) +#define CONFIG_SYS_PROMPT "qemu-mipsel # " +#else +#define CONFIG_SYS_PROMPT "qemu-mips # " +#endif #define CONFIG_AUTO_COMPLETE #define CONFIG_CMDLINE_EDITING -- cgit v1.1 From cdeb916120a43c1bfe3de1a6d84ea403d43e59d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Thu, 19 Jul 2012 22:16:38 +0200 Subject: ehci: cosmetic: Define the number of qt_buffers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau Cc: Marek Vasut Cc: Ilya Yanok Cc: Stefan Herbrechtsmeier --- drivers/usb/host/ehci-hcd.c | 4 ++-- drivers/usb/host/ehci.h | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 2a82a29..5b3b906 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -183,7 +183,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz) flush_dcache_range(addr, ALIGN(addr + sz, ARCH_DMA_MINALIGN)); idx = 0; - while (idx < 5) { + while (idx < QT_BUFFER_CNT) { td->qt_buffer[idx] = cpu_to_hc32(addr); td->qt_buffer_hi[idx] = 0; next = (addr + 4096) & ~4095; @@ -195,7 +195,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz) idx++; } - if (idx == 5) { + if (idx == QT_BUFFER_CNT) { printf("out of buffer pointers (%u bytes left)\n", sz); return -1; } diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index cc00ce4..7992983 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -171,12 +171,13 @@ struct usb_linux_config_descriptor { /* Queue Element Transfer Descriptor (qTD). */ struct qTD { /* this part defined by EHCI spec */ - uint32_t qt_next; /* see EHCI 3.5.1 */ + uint32_t qt_next; /* see EHCI 3.5.1 */ #define QT_NEXT_TERMINATE 1 - uint32_t qt_altnext; /* see EHCI 3.5.2 */ - uint32_t qt_token; /* see EHCI 3.5.3 */ - uint32_t qt_buffer[5]; /* see EHCI 3.5.4 */ - uint32_t qt_buffer_hi[5]; /* Appendix B */ + uint32_t qt_altnext; /* see EHCI 3.5.2 */ + uint32_t qt_token; /* see EHCI 3.5.3 */ +#define QT_BUFFER_CNT 5 + uint32_t qt_buffer[QT_BUFFER_CNT]; /* see EHCI 3.5.4 */ + uint32_t qt_buffer_hi[QT_BUFFER_CNT]; /* Appendix B */ /* pad struct for 32 byte alignment */ uint32_t unused[3]; }; -- cgit v1.1 From 1d4a0b6c00cd1a5e4d230f81317aa3cc7a89c2f9 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 6 Aug 2012 14:41:05 +0200 Subject: dfu:usb: Support for g_dnl composite download gadget. Composite USB download gadget support (g_dnl) for download functions. This code works on top of composite gadget. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Cc: Marek Vasut --- drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/g_dnl.c | 202 ++++++++++++++++++++++++++++++++++++++++++++ include/g_dnl.h | 33 ++++++++ 3 files changed, 236 insertions(+) create mode 100644 drivers/usb/gadget/g_dnl.c create mode 100644 include/g_dnl.h diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 87d1918..2c067c8 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -29,6 +29,7 @@ LIB := $(obj)libusb_gadget.o ifdef CONFIG_USB_GADGET COBJS-y += epautoconf.o config.o usbstring.o COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o +COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o endif ifdef CONFIG_USB_ETHER COBJS-y += ether.o epautoconf.o config.o usbstring.o diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c new file mode 100644 index 0000000..7d87050 --- /dev/null +++ b/drivers/usb/gadget/g_dnl.c @@ -0,0 +1,202 @@ +/* + * g_dnl.c -- USB Downloader Gadget + * + * Copyright (C) 2012 Samsung Electronics + * Lukasz Majewski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#include +#include + +#include +#include "f_dfu.h" + +#include "gadget_chips.h" +#include "composite.c" + +/* + * One needs to define the following: + * CONFIG_G_DNL_VENDOR_NUM + * CONFIG_G_DNL_PRODUCT_NUM + * CONFIG_G_DNL_MANUFACTURER + * at e.g. ./include/configs/.h + */ + +#define STRING_MANUFACTURER 25 +#define STRING_PRODUCT 2 +#define STRING_USBDOWN 2 +#define CONFIG_USBDOWNLOADER 2 + +#define DRIVER_VERSION "usb_dnl 2.0" + +static const char shortname[] = "usb_dnl_"; +static const char product[] = "USB download gadget"; +static const char manufacturer[] = CONFIG_G_DNL_MANUFACTURER; + +static struct usb_device_descriptor device_desc = { + .bLength = sizeof device_desc, + .bDescriptorType = USB_DT_DEVICE, + + .bcdUSB = __constant_cpu_to_le16(0x0200), + .bDeviceClass = USB_CLASS_COMM, + .bDeviceSubClass = 0x02, /*0x02:CDC-modem , 0x00:CDC-serial*/ + + .idVendor = __constant_cpu_to_le16(CONFIG_G_DNL_VENDOR_NUM), + .idProduct = __constant_cpu_to_le16(CONFIG_G_DNL_PRODUCT_NUM), + .iProduct = STRING_PRODUCT, + .bNumConfigurations = 1, +}; + +/* static strings, in UTF-8 */ +static struct usb_string g_dnl_string_defs[] = { + { 0, manufacturer, }, + { 1, product, }, +}; + +static struct usb_gadget_strings g_dnl_string_tab = { + .language = 0x0409, /* en-us */ + .strings = g_dnl_string_defs, +}; + +static struct usb_gadget_strings *g_dnl_composite_strings[] = { + &g_dnl_string_tab, + NULL, +}; + +static int g_dnl_unbind(struct usb_composite_dev *cdev) +{ + debug("%s\n", __func__); + return 0; +} + +static int g_dnl_do_config(struct usb_configuration *c) +{ + const char *s = c->cdev->driver->name; + int ret = -1; + + debug("%s: configuration: 0x%p composite dev: 0x%p\n", + __func__, c, c->cdev); + + printf("GADGET DRIVER: %s\n", s); + if (!strcmp(s, "usb_dnl_dfu")) + ret = dfu_add(c); + + return ret; +} + +static int g_dnl_config_register(struct usb_composite_dev *cdev) +{ + static struct usb_configuration config = { + .label = "usb_dnload", + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, + .bConfigurationValue = CONFIG_USBDOWNLOADER, + .iConfiguration = STRING_USBDOWN, + + .bind = g_dnl_do_config, + }; + + return usb_add_config(cdev, &config); +} + +static int g_dnl_bind(struct usb_composite_dev *cdev) +{ + struct usb_gadget *gadget = cdev->gadget; + int id, ret; + int gcnum; + + debug("%s: gadget: 0x%p cdev: 0x%p\n", __func__, gadget, cdev); + + id = usb_string_id(cdev); + + if (id < 0) + return id; + g_dnl_string_defs[0].id = id; + device_desc.iManufacturer = id; + + id = usb_string_id(cdev); + if (id < 0) + return id; + + g_dnl_string_defs[1].id = id; + device_desc.iProduct = id; + + ret = g_dnl_config_register(cdev); + if (ret) + goto error; + + gcnum = usb_gadget_controller_number(gadget); + + debug("gcnum: %d\n", gcnum); + if (gcnum >= 0) + device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum); + else { + debug("%s: controller '%s' not recognized\n", + shortname, gadget->name); + device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); + } + + return 0; + + error: + g_dnl_unbind(cdev); + return -ENOMEM; +} + +static struct usb_composite_driver g_dnl_driver = { + .name = NULL, + .dev = &device_desc, + .strings = g_dnl_composite_strings, + + .bind = g_dnl_bind, + .unbind = g_dnl_unbind, +}; + +int g_dnl_register(const char *type) +{ + /* We only allow "dfu" atm, so 3 should be enough */ + static char name[sizeof(shortname) + 3]; + int ret; + + if (!strcmp(type, "dfu")) { + strcpy(name, shortname); + strcat(name, type); + } else { + printf("%s: unknown command: %s\n", __func__, type); + return -EINVAL; + } + + g_dnl_driver.name = name; + + debug("%s: g_dnl_driver.name: %s\n", __func__, g_dnl_driver.name); + ret = usb_composite_register(&g_dnl_driver); + + if (ret) { + printf("%s: failed!, error: %d\n", __func__, ret); + return ret; + } + + return 0; +} + +void g_dnl_unregister(void) +{ + usb_composite_unregister(&g_dnl_driver); +} diff --git a/include/g_dnl.h b/include/g_dnl.h new file mode 100644 index 0000000..0ec7440 --- /dev/null +++ b/include/g_dnl.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Lukasz Majewski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __G_DOWNLOAD_H_ +#define __G_DOWNLOAD_H_ + +#include +#include +#include + +int g_dnl_register(const char *s); +void g_dnl_unregister(void); + +/* USB initialization declaration - board specific */ +void board_usb_init(void); +#endif /* __G_DOWNLOAD_H_ */ -- cgit v1.1 From b819ddbf56da304120b72643e97e00e12815e777 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 6 Aug 2012 14:41:06 +0200 Subject: dfu:usb: DFU USB function (f_dfu) support for g_dnl composite gadget Support for f_dfu USB function. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Cc: Marek Vasut --- drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/f_dfu.c | 749 ++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/f_dfu.h | 100 ++++++ 3 files changed, 850 insertions(+) create mode 100644 drivers/usb/gadget/f_dfu.c create mode 100644 drivers/usb/gadget/f_dfu.h diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 2c067c8..5bbdd36 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -30,6 +30,7 @@ ifdef CONFIG_USB_GADGET COBJS-y += epautoconf.o config.o usbstring.o COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o +COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o endif ifdef CONFIG_USB_ETHER COBJS-y += ether.o epautoconf.o config.o usbstring.o diff --git a/drivers/usb/gadget/f_dfu.c b/drivers/usb/gadget/f_dfu.c new file mode 100644 index 0000000..3ec4c65 --- /dev/null +++ b/drivers/usb/gadget/f_dfu.c @@ -0,0 +1,749 @@ +/* + * f_dfu.c -- Device Firmware Update USB function + * + * Copyright (C) 2012 Samsung Electronics + * authors: Andrzej Pietrasiewicz + * Lukasz Majewski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "f_dfu.h" + +struct f_dfu { + struct usb_function usb_function; + + struct usb_descriptor_header **function; + struct usb_string *strings; + + /* when configured, we have one config */ + u8 config; + u8 altsetting; + enum dfu_state dfu_state; + unsigned int dfu_status; + + /* Send/received block number is handy for data integrity check */ + int blk_seq_num; +}; + +typedef int (*dfu_state_fn) (struct f_dfu *, + const struct usb_ctrlrequest *, + struct usb_gadget *, + struct usb_request *); + +static inline struct f_dfu *func_to_dfu(struct usb_function *f) +{ + return container_of(f, struct f_dfu, usb_function); +} + +static const struct dfu_function_descriptor dfu_func = { + .bLength = sizeof dfu_func, + .bDescriptorType = DFU_DT_FUNC, + .bmAttributes = DFU_BIT_WILL_DETACH | + DFU_BIT_MANIFESTATION_TOLERANT | + DFU_BIT_CAN_UPLOAD | + DFU_BIT_CAN_DNLOAD, + .wDetachTimeOut = 0, + .wTransferSize = DFU_USB_BUFSIZ, + .bcdDFUVersion = __constant_cpu_to_le16(0x0110), +}; + +static struct usb_interface_descriptor dfu_intf_runtime = { + .bLength = sizeof dfu_intf_runtime, + .bDescriptorType = USB_DT_INTERFACE, + .bNumEndpoints = 0, + .bInterfaceClass = USB_CLASS_APP_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 1, + /* .iInterface = DYNAMIC */ +}; + +static struct usb_descriptor_header *dfu_runtime_descs[] = { + (struct usb_descriptor_header *) &dfu_intf_runtime, + NULL, +}; + +static const struct usb_qualifier_descriptor dev_qualifier = { + .bLength = sizeof dev_qualifier, + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = __constant_cpu_to_le16(0x0200), + .bDeviceClass = USB_CLASS_VENDOR_SPEC, + .bNumConfigurations = 1, +}; + +static const char dfu_name[] = "Device Firmware Upgrade"; + +/* + * static strings, in UTF-8 + * + * dfu_generic configuration + */ +static struct usb_string strings_dfu_generic[] = { + [0].s = dfu_name, + { } /* end of list */ +}; + +static struct usb_gadget_strings stringtab_dfu_generic = { + .language = 0x0409, /* en-us */ + .strings = strings_dfu_generic, +}; + +static struct usb_gadget_strings *dfu_generic_strings[] = { + &stringtab_dfu_generic, + NULL, +}; + +/* + * usb_function specific + */ +static struct usb_gadget_strings stringtab_dfu = { + .language = 0x0409, /* en-us */ + /* + * .strings + * + * assigned during initialization, + * depends on number of flash entities + * + */ +}; + +static struct usb_gadget_strings *dfu_strings[] = { + &stringtab_dfu, + NULL, +}; + +/*-------------------------------------------------------------------------*/ + +static void dnload_request_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct f_dfu *f_dfu = req->context; + + dfu_write(dfu_get_entity(f_dfu->altsetting), req->buf, + req->length, f_dfu->blk_seq_num); + + if (req->length == 0) + puts("DOWNLOAD ... OK\nCtrl+C to exit ...\n"); +} + +static void handle_getstatus(struct usb_request *req) +{ + struct dfu_status *dstat = (struct dfu_status *)req->buf; + struct f_dfu *f_dfu = req->context; + + switch (f_dfu->dfu_state) { + case DFU_STATE_dfuDNLOAD_SYNC: + case DFU_STATE_dfuDNBUSY: + f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_IDLE; + break; + case DFU_STATE_dfuMANIFEST_SYNC: + break; + default: + break; + } + + /* send status response */ + dstat->bStatus = f_dfu->dfu_status; + dstat->bState = f_dfu->dfu_state; + dstat->iString = 0; +} + +static void handle_getstate(struct usb_request *req) +{ + struct f_dfu *f_dfu = req->context; + + ((u8 *)req->buf)[0] = f_dfu->dfu_state; + req->actual = sizeof(u8); +} + +static inline void to_dfu_mode(struct f_dfu *f_dfu) +{ + f_dfu->usb_function.strings = dfu_strings; + f_dfu->usb_function.hs_descriptors = f_dfu->function; +} + +static inline void to_runtime_mode(struct f_dfu *f_dfu) +{ + f_dfu->usb_function.strings = NULL; + f_dfu->usb_function.hs_descriptors = dfu_runtime_descs; +} + +static int handle_upload(struct usb_request *req, u16 len) +{ + struct f_dfu *f_dfu = req->context; + + return dfu_read(dfu_get_entity(f_dfu->altsetting), req->buf, + req->length, f_dfu->blk_seq_num); +} + +static int handle_dnload(struct usb_gadget *gadget, u16 len) +{ + struct usb_composite_dev *cdev = get_gadget_data(gadget); + struct usb_request *req = cdev->req; + struct f_dfu *f_dfu = req->context; + + if (len == 0) + f_dfu->dfu_state = DFU_STATE_dfuMANIFEST_SYNC; + + req->complete = dnload_request_complete; + + return len; +} + +/*-------------------------------------------------------------------------*/ +/* DFU state machine */ +static int state_app_idle(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + case USB_REQ_DFU_DETACH: + f_dfu->dfu_state = DFU_STATE_appDETACH; + to_dfu_mode(f_dfu); + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + value = RET_ZLP; + break; + default: + value = RET_STALL; + break; + } + + return value; +} + +static int state_app_detach(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + default: + f_dfu->dfu_state = DFU_STATE_appIDLE; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_idle(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + u16 w_value = le16_to_cpu(ctrl->wValue); + u16 len = le16_to_cpu(ctrl->wLength); + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_DNLOAD: + if (len == 0) { + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC; + f_dfu->blk_seq_num = w_value; + value = handle_dnload(gadget, len); + break; + case USB_REQ_DFU_UPLOAD: + f_dfu->dfu_state = DFU_STATE_dfuUPLOAD_IDLE; + f_dfu->blk_seq_num = 0; + value = handle_upload(req, len); + break; + case USB_REQ_DFU_ABORT: + /* no zlp? */ + value = RET_ZLP; + break; + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + case USB_REQ_DFU_DETACH: + /* + * Proprietary extension: 'detach' from idle mode and + * get back to runtime mode in case of USB Reset. As + * much as I dislike this, we just can't use every USB + * bus reset to switch back to runtime mode, since at + * least the Linux USB stack likes to send a number of + * resets in a row :( + */ + f_dfu->dfu_state = + DFU_STATE_dfuMANIFEST_WAIT_RST; + to_runtime_mode(f_dfu); + f_dfu->dfu_state = DFU_STATE_appIDLE; + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_dnload_sync(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_dnbusy(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_dnload_idle(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + u16 w_value = le16_to_cpu(ctrl->wValue); + u16 len = le16_to_cpu(ctrl->wLength); + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_DNLOAD: + f_dfu->dfu_state = DFU_STATE_dfuDNLOAD_SYNC; + f_dfu->blk_seq_num = w_value; + value = handle_dnload(gadget, len); + break; + case USB_REQ_DFU_ABORT: + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + value = RET_ZLP; + break; + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_manifest_sync(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + /* We're MainfestationTolerant */ + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + handle_getstatus(req); + f_dfu->blk_seq_num = 0; + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_upload_idle(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + u16 w_value = le16_to_cpu(ctrl->wValue); + u16 len = le16_to_cpu(ctrl->wLength); + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_UPLOAD: + /* state transition if less data then requested */ + f_dfu->blk_seq_num = w_value; + value = handle_upload(req, len); + if (value >= 0 && value < len) + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + break; + case USB_REQ_DFU_ABORT: + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + /* no zlp? */ + value = RET_ZLP; + break; + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static int state_dfu_error(struct f_dfu *f_dfu, + const struct usb_ctrlrequest *ctrl, + struct usb_gadget *gadget, + struct usb_request *req) +{ + int value = 0; + + switch (ctrl->bRequest) { + case USB_REQ_DFU_GETSTATUS: + handle_getstatus(req); + value = RET_STAT_LEN; + break; + case USB_REQ_DFU_GETSTATE: + handle_getstate(req); + break; + case USB_REQ_DFU_CLRSTATUS: + f_dfu->dfu_state = DFU_STATE_dfuIDLE; + f_dfu->dfu_status = DFU_STATUS_OK; + /* no zlp? */ + value = RET_ZLP; + break; + default: + f_dfu->dfu_state = DFU_STATE_dfuERROR; + value = RET_STALL; + break; + } + + return value; +} + +static dfu_state_fn dfu_state[] = { + state_app_idle, /* DFU_STATE_appIDLE */ + state_app_detach, /* DFU_STATE_appDETACH */ + state_dfu_idle, /* DFU_STATE_dfuIDLE */ + state_dfu_dnload_sync, /* DFU_STATE_dfuDNLOAD_SYNC */ + state_dfu_dnbusy, /* DFU_STATE_dfuDNBUSY */ + state_dfu_dnload_idle, /* DFU_STATE_dfuDNLOAD_IDLE */ + state_dfu_manifest_sync, /* DFU_STATE_dfuMANIFEST_SYNC */ + NULL, /* DFU_STATE_dfuMANIFEST */ + NULL, /* DFU_STATE_dfuMANIFEST_WAIT_RST */ + state_dfu_upload_idle, /* DFU_STATE_dfuUPLOAD_IDLE */ + state_dfu_error /* DFU_STATE_dfuERROR */ +}; + +static int +dfu_handle(struct usb_function *f, const struct usb_ctrlrequest *ctrl) +{ + struct usb_gadget *gadget = f->config->cdev->gadget; + struct usb_request *req = f->config->cdev->req; + struct f_dfu *f_dfu = f->config->cdev->req->context; + u16 len = le16_to_cpu(ctrl->wLength); + u16 w_value = le16_to_cpu(ctrl->wValue); + int value = 0; + u8 req_type = ctrl->bRequestType & USB_TYPE_MASK; + + debug("w_value: 0x%x len: 0x%x\n", w_value, len); + debug("req_type: 0x%x ctrl->bRequest: 0x%x f_dfu->dfu_state: 0x%x\n", + req_type, ctrl->bRequest, f_dfu->dfu_state); + + if (req_type == USB_TYPE_STANDARD) { + if (ctrl->bRequest == USB_REQ_GET_DESCRIPTOR && + (w_value >> 8) == DFU_DT_FUNC) { + value = min(len, (u16) sizeof(dfu_func)); + memcpy(req->buf, &dfu_func, value); + } + } else /* DFU specific request */ + value = dfu_state[f_dfu->dfu_state] (f_dfu, ctrl, gadget, req); + + if (value >= 0) { + req->length = value; + req->zero = value < len; + value = usb_ep_queue(gadget->ep0, req, 0); + if (value < 0) { + debug("ep_queue --> %d\n", value); + req->status = 0; + } + } + + return value; +} + +/*-------------------------------------------------------------------------*/ + +static int +dfu_prepare_strings(struct f_dfu *f_dfu, int n) +{ + struct dfu_entity *de = NULL; + int i = 0; + + f_dfu->strings = calloc(sizeof(struct usb_string), n + 1); + if (!f_dfu->strings) + goto enomem; + + for (i = 0; i < n; ++i) { + de = dfu_get_entity(i); + f_dfu->strings[i].s = de->name; + } + + f_dfu->strings[i].id = 0; + f_dfu->strings[i].s = NULL; + + return 0; + +enomem: + while (i) + f_dfu->strings[--i].s = NULL; + + free(f_dfu->strings); + + return -ENOMEM; +} + +static int dfu_prepare_function(struct f_dfu *f_dfu, int n) +{ + struct usb_interface_descriptor *d; + int i = 0; + + f_dfu->function = calloc(sizeof(struct usb_descriptor_header *), n); + if (!f_dfu->function) + goto enomem; + + for (i = 0; i < n; ++i) { + d = calloc(sizeof(*d), 1); + if (!d) + goto enomem; + + d->bLength = sizeof(*d); + d->bDescriptorType = USB_DT_INTERFACE; + d->bAlternateSetting = i; + d->bNumEndpoints = 0; + d->bInterfaceClass = USB_CLASS_APP_SPEC; + d->bInterfaceSubClass = 1; + d->bInterfaceProtocol = 2; + + f_dfu->function[i] = (struct usb_descriptor_header *)d; + } + f_dfu->function[i] = NULL; + + return 0; + +enomem: + while (i) { + free(f_dfu->function[--i]); + f_dfu->function[i] = NULL; + } + free(f_dfu->function); + + return -ENOMEM; +} + +static int dfu_bind(struct usb_configuration *c, struct usb_function *f) +{ + struct usb_composite_dev *cdev = c->cdev; + struct f_dfu *f_dfu = func_to_dfu(f); + int alt_num = dfu_get_alt_number(); + int rv, id, i; + + id = usb_interface_id(c, f); + if (id < 0) + return id; + dfu_intf_runtime.bInterfaceNumber = id; + + f_dfu->dfu_state = DFU_STATE_appIDLE; + f_dfu->dfu_status = DFU_STATUS_OK; + + rv = dfu_prepare_function(f_dfu, alt_num); + if (rv) + goto error; + + rv = dfu_prepare_strings(f_dfu, alt_num); + if (rv) + goto error; + for (i = 0; i < alt_num; i++) { + id = usb_string_id(cdev); + if (id < 0) + return id; + f_dfu->strings[i].id = id; + ((struct usb_interface_descriptor *)f_dfu->function[i]) + ->iInterface = id; + } + + stringtab_dfu.strings = f_dfu->strings; + + cdev->req->context = f_dfu; + +error: + return rv; +} + +static void dfu_unbind(struct usb_configuration *c, struct usb_function *f) +{ + struct f_dfu *f_dfu = func_to_dfu(f); + int alt_num = dfu_get_alt_number(); + int i; + + if (f_dfu->strings) { + i = alt_num; + while (i) + f_dfu->strings[--i].s = NULL; + + free(f_dfu->strings); + } + + if (f_dfu->function) { + i = alt_num; + while (i) { + free(f_dfu->function[--i]); + f_dfu->function[i] = NULL; + } + free(f_dfu->function); + } + + free(f_dfu); +} + +static int dfu_set_alt(struct usb_function *f, unsigned intf, unsigned alt) +{ + struct f_dfu *f_dfu = func_to_dfu(f); + + debug("%s: intf:%d alt:%d\n", __func__, intf, alt); + + f_dfu->altsetting = alt; + + return 0; +} + +/* TODO: is this really what we need here? */ +static void dfu_disable(struct usb_function *f) +{ + struct f_dfu *f_dfu = func_to_dfu(f); + if (f_dfu->config == 0) + return; + + debug("%s: reset config\n", __func__); + + f_dfu->config = 0; +} + +static int dfu_bind_config(struct usb_configuration *c) +{ + struct f_dfu *f_dfu; + int status; + + f_dfu = calloc(sizeof(*f_dfu), 1); + if (!f_dfu) + return -ENOMEM; + f_dfu->usb_function.name = "dfu"; + f_dfu->usb_function.hs_descriptors = dfu_runtime_descs; + f_dfu->usb_function.bind = dfu_bind; + f_dfu->usb_function.unbind = dfu_unbind; + f_dfu->usb_function.set_alt = dfu_set_alt; + f_dfu->usb_function.disable = dfu_disable; + f_dfu->usb_function.strings = dfu_generic_strings, + f_dfu->usb_function.setup = dfu_handle, + + status = usb_add_function(c, &f_dfu->usb_function); + if (status) + free(f_dfu); + + return status; +} + +int dfu_add(struct usb_configuration *c) +{ + int id; + + id = usb_string_id(c->cdev); + if (id < 0) + return id; + strings_dfu_generic[0].id = id; + dfu_intf_runtime.iInterface = id; + + debug("%s: cdev: 0x%p gadget:0x%p gadget->ep0: 0x%p\n", __func__, + c->cdev, c->cdev->gadget, c->cdev->gadget->ep0); + + return dfu_bind_config(c); +} diff --git a/drivers/usb/gadget/f_dfu.h b/drivers/usb/gadget/f_dfu.h new file mode 100644 index 0000000..023e1ad --- /dev/null +++ b/drivers/usb/gadget/f_dfu.h @@ -0,0 +1,100 @@ +/* + * f_dfu.h -- Device Firmware Update gadget + * + * Copyright (C) 2011-2012 Samsung Electronics + * author: Andrzej Pietrasiewicz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __F_DFU_H_ +#define __F_DFU_H_ + +#include +#include + +#define DFU_CONFIG_VAL 1 +#define DFU_DT_FUNC 0x21 + +#define DFU_BIT_WILL_DETACH (0x1 << 3) +#define DFU_BIT_MANIFESTATION_TOLERANT (0x1 << 2) +#define DFU_BIT_CAN_UPLOAD (0x1 << 1) +#define DFU_BIT_CAN_DNLOAD 0x1 + +/* big enough to hold our biggest descriptor */ +#define DFU_USB_BUFSIZ 4096 + +#define USB_REQ_DFU_DETACH 0x00 +#define USB_REQ_DFU_DNLOAD 0x01 +#define USB_REQ_DFU_UPLOAD 0x02 +#define USB_REQ_DFU_GETSTATUS 0x03 +#define USB_REQ_DFU_CLRSTATUS 0x04 +#define USB_REQ_DFU_GETSTATE 0x05 +#define USB_REQ_DFU_ABORT 0x06 + +#define DFU_STATUS_OK 0x00 +#define DFU_STATUS_errTARGET 0x01 +#define DFU_STATUS_errFILE 0x02 +#define DFU_STATUS_errWRITE 0x03 +#define DFU_STATUS_errERASE 0x04 +#define DFU_STATUS_errCHECK_ERASED 0x05 +#define DFU_STATUS_errPROG 0x06 +#define DFU_STATUS_errVERIFY 0x07 +#define DFU_STATUS_errADDRESS 0x08 +#define DFU_STATUS_errNOTDONE 0x09 +#define DFU_STATUS_errFIRMWARE 0x0a +#define DFU_STATUS_errVENDOR 0x0b +#define DFU_STATUS_errUSBR 0x0c +#define DFU_STATUS_errPOR 0x0d +#define DFU_STATUS_errUNKNOWN 0x0e +#define DFU_STATUS_errSTALLEDPKT 0x0f + +#define RET_STALL -1 +#define RET_ZLP 0 +#define RET_STAT_LEN 6 + +enum dfu_state { + DFU_STATE_appIDLE = 0, + DFU_STATE_appDETACH = 1, + DFU_STATE_dfuIDLE = 2, + DFU_STATE_dfuDNLOAD_SYNC = 3, + DFU_STATE_dfuDNBUSY = 4, + DFU_STATE_dfuDNLOAD_IDLE = 5, + DFU_STATE_dfuMANIFEST_SYNC = 6, + DFU_STATE_dfuMANIFEST = 7, + DFU_STATE_dfuMANIFEST_WAIT_RST = 8, + DFU_STATE_dfuUPLOAD_IDLE = 9, + DFU_STATE_dfuERROR = 10, +}; + +struct dfu_status { + __u8 bStatus; + __u8 bwPollTimeout[3]; + __u8 bState; + __u8 iString; +} __packed; + +struct dfu_function_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bmAttributes; + __le16 wDetachTimeOut; + __le16 wTransferSize; + __le16 bcdDFUVersion; +} __packed; + +/* configuration-specific linkup */ +int dfu_add(struct usb_configuration *c); +#endif /* __F_DFU_H_ */ -- cgit v1.1 From f22b11c10d16d71b7f96fd19cd0062724428bf88 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 6 Aug 2012 14:41:07 +0200 Subject: dfu: DFU backend implementation New, separate driver at ./drivers/dfu has been added. It allows platform and storage independent operation of DFU. It has been extended to use new MMC level of command abstraction. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Cc: Marek Vasut --- Makefile | 1 + drivers/dfu/Makefile | 43 ++++++++++ drivers/dfu/dfu.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/dfu.h | 103 ++++++++++++++++++++++ 4 files changed, 385 insertions(+) create mode 100644 drivers/dfu/Makefile create mode 100644 drivers/dfu/dfu.c create mode 100644 include/dfu.h diff --git a/Makefile b/Makefile index a41b987..cc15bfd 100644 --- a/Makefile +++ b/Makefile @@ -269,6 +269,7 @@ LIBS-y += drivers/pci/libpci.o LIBS-y += drivers/pcmcia/libpcmcia.o LIBS-y += drivers/power/libpower.o LIBS-y += drivers/spi/libspi.o +LIBS-y += drivers/dfu/libdfu.o ifeq ($(CPU),mpc83xx) LIBS-y += drivers/qe/libqe.o LIBS-y += arch/powerpc/cpu/mpc8xxx/ddr/libddr.o diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile new file mode 100644 index 0000000..7736485 --- /dev/null +++ b/drivers/dfu/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (C) 2012 Samsung Electronics +# Lukasz Majewski +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)libdfu.o + +COBJS-$(CONFIG_DFU_FUNCTION) += dfu.o + +SRCS := $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c new file mode 100644 index 0000000..e8477fb --- /dev/null +++ b/drivers/dfu/dfu.c @@ -0,0 +1,238 @@ +/* + * dfu.c -- DFU back-end routines + * + * Copyright (C) 2012 Samsung Electronics + * author: Lukasz Majewski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +static LIST_HEAD(dfu_list); +static int dfu_alt_num; + +static int dfu_find_alt_num(const char *s) +{ + int i = 0; + + for (; *s; s++) + if (*s == ';') + i++; + + return ++i; +} + +static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE) + dfu_buf[DFU_DATA_BUF_SIZE]; + +int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) +{ + static unsigned char *i_buf; + static int i_blk_seq_num; + long w_size = 0; + int ret = 0; + + debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x i_buf: 0x%p\n", + __func__, dfu->name, buf, size, blk_seq_num, i_buf); + + if (blk_seq_num == 0) { + i_buf = dfu_buf; + i_blk_seq_num = 0; + } + + if (i_blk_seq_num++ != blk_seq_num) { + printf("%s: Wrong sequence number! [%d] [%d]\n", + __func__, i_blk_seq_num, blk_seq_num); + return -1; + } + + memcpy(i_buf, buf, size); + i_buf += size; + + if (size == 0) { + /* Integrity check (if needed) */ + debug("%s: %s %d [B] CRC32: 0x%x\n", __func__, dfu->name, + i_buf - dfu_buf, crc32(0, dfu_buf, i_buf - dfu_buf)); + + w_size = i_buf - dfu_buf; + ret = dfu->write_medium(dfu, dfu_buf, &w_size); + if (ret) + debug("%s: Write error!\n", __func__); + + i_blk_seq_num = 0; + i_buf = NULL; + return ret; + } + + return ret; +} + +int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) +{ + static unsigned char *i_buf; + static int i_blk_seq_num; + static long r_size; + static u32 crc; + int ret = 0; + + debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x i_buf: 0x%p\n", + __func__, dfu->name, buf, size, blk_seq_num, i_buf); + + if (blk_seq_num == 0) { + i_buf = dfu_buf; + ret = dfu->read_medium(dfu, i_buf, &r_size); + debug("%s: %s %ld [B]\n", __func__, dfu->name, r_size); + i_blk_seq_num = 0; + /* Integrity check (if needed) */ + crc = crc32(0, dfu_buf, r_size); + } + + if (i_blk_seq_num++ != blk_seq_num) { + printf("%s: Wrong sequence number! [%d] [%d]\n", + __func__, i_blk_seq_num, blk_seq_num); + return -1; + } + + if (r_size >= size) { + memcpy(buf, i_buf, size); + i_buf += size; + r_size -= size; + return size; + } else { + memcpy(buf, i_buf, r_size); + i_buf += r_size; + debug("%s: %s CRC32: 0x%x\n", __func__, dfu->name, crc); + puts("UPLOAD ... done\nCtrl+C to exit ...\n"); + + i_buf = NULL; + i_blk_seq_num = 0; + crc = 0; + return r_size; + } + return ret; +} + +static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt, + char *interface, int num) +{ + char *st; + + debug("%s: %s interface: %s num: %d\n", __func__, s, interface, num); + st = strsep(&s, " "); + strcpy(dfu->name, st); + + dfu->dev_num = num; + dfu->alt = alt; + + /* Specific for mmc device */ + if (strcmp(interface, "mmc") == 0) { + if (dfu_fill_entity_mmc(dfu, s)) + return -1; + } else { + printf("%s: Device %s not (yet) supported!\n", + __func__, interface); + return -1; + } + + return 0; +} + +void dfu_free_entities(void) +{ + struct dfu_entity *dfu, *p, *t = NULL; + + list_for_each_entry_safe_reverse(dfu, p, &dfu_list, list) { + list_del(&dfu->list); + t = dfu; + } + if (t) + free(t); + INIT_LIST_HEAD(&dfu_list); +} + +int dfu_config_entities(char *env, char *interface, int num) +{ + struct dfu_entity *dfu; + int i, ret; + char *s; + + dfu_alt_num = dfu_find_alt_num(env); + debug("%s: dfu_alt_num=%d\n", __func__, dfu_alt_num); + + dfu = calloc(sizeof(*dfu), dfu_alt_num); + if (!dfu) + return -1; + for (i = 0; i < dfu_alt_num; i++) { + + s = strsep(&env, ";"); + ret = dfu_fill_entity(&dfu[i], s, i, interface, num); + if (ret) + return -1; + + list_add_tail(&dfu[i].list, &dfu_list); + } + + return 0; +} + +const char *dfu_get_dev_type(enum dfu_device_type t) +{ + const char *dev_t[] = {NULL, "eMMC", "OneNAND", "NAND" }; + return dev_t[t]; +} + +const char *dfu_get_layout(enum dfu_layout l) +{ + const char *dfu_layout[] = {NULL, "RAW_ADDR", "FAT", "EXT2", + "EXT3", "EXT4" }; + return dfu_layout[l]; +} + +void dfu_show_entities(void) +{ + struct dfu_entity *dfu; + + puts("DFU alt settings list:\n"); + + list_for_each_entry(dfu, &dfu_list, list) { + printf("dev: %s alt: %d name: %s layout: %s\n", + dfu_get_dev_type(dfu->dev_type), dfu->alt, + dfu->name, dfu_get_layout(dfu->layout)); + } +} + +int dfu_get_alt_number(void) +{ + return dfu_alt_num; +} + +struct dfu_entity *dfu_get_entity(int alt) +{ + struct dfu_entity *dfu; + + list_for_each_entry(dfu, &dfu_list, list) { + if (dfu->alt == alt) + return dfu; + } + + return NULL; +} diff --git a/include/dfu.h b/include/dfu.h new file mode 100644 index 0000000..5350d79 --- /dev/null +++ b/include/dfu.h @@ -0,0 +1,103 @@ +/* + * dfu.h - DFU flashable area description + * + * Copyright (C) 2012 Samsung Electronics + * authors: Andrzej Pietrasiewicz + * Lukasz Majewski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __DFU_ENTITY_H_ +#define __DFU_ENTITY_H_ + +#include +#include +#include + +enum dfu_device_type { + DFU_DEV_MMC = 1, + DFU_DEV_ONENAND, + DFU_DEV_NAND, +}; + +enum dfu_layout { + DFU_RAW_ADDR = 1, + DFU_FS_FAT, + DFU_FS_EXT2, + DFU_FS_EXT3, + DFU_FS_EXT4, +}; + +struct mmc_internal_data { + /* RAW programming */ + unsigned int lba_start; + unsigned int lba_size; + unsigned int lba_blk_size; + + /* FAT/EXT */ + unsigned int dev; + unsigned int part; +}; + +static inline unsigned int get_mmc_blk_size(int dev) +{ + return find_mmc_device(dev)->read_bl_len; +} + +#define DFU_NAME_SIZE 32 +#define DFU_CMD_BUF_SIZE 128 +#define DFU_DATA_BUF_SIZE (1024*1024*4) /* 4 MiB */ + +struct dfu_entity { + char name[DFU_NAME_SIZE]; + int alt; + void *dev_private; + int dev_num; + enum dfu_device_type dev_type; + enum dfu_layout layout; + + union { + struct mmc_internal_data mmc; + } data; + + int (*read_medium)(struct dfu_entity *dfu, void *buf, long *len); + int (*write_medium)(struct dfu_entity *dfu, void *buf, long *len); + + struct list_head list; +}; + +int dfu_config_entities(char *s, char *interface, int num); +void dfu_free_entities(void); +void dfu_show_entities(void); +int dfu_get_alt_number(void); +const char *dfu_get_dev_type(enum dfu_device_type t); +const char *dfu_get_layout(enum dfu_layout l); +struct dfu_entity *dfu_get_entity(int alt); +char *dfu_extract_token(char** e, int *n); + +int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num); +int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num); +/* Device specific */ +#ifdef CONFIG_DFU_MMC +extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s); +#else +static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s) +{ + puts("MMC support not available!\n"); + return -1; +} +#endif +#endif /* __DFU_ENTITY_H_ */ -- cgit v1.1 From cb383cd21d5d6aa6de5cfc59f14e8e3a56e2931f Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 6 Aug 2012 14:41:08 +0200 Subject: dfu: MMC specific routines for DFU operation Support for MMC storage devices to work with DFU framework. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Cc: Marek Vasut --- drivers/dfu/Makefile | 1 + drivers/dfu/dfu_mmc.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 drivers/dfu/dfu_mmc.c diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile index 7736485..7b717bc 100644 --- a/drivers/dfu/Makefile +++ b/drivers/dfu/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)libdfu.o COBJS-$(CONFIG_DFU_FUNCTION) += dfu.o +COBJS-$(CONFIG_DFU_MMC) += dfu_mmc.o SRCS := $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(COBJS-y)) diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c new file mode 100644 index 0000000..060145b --- /dev/null +++ b/drivers/dfu/dfu_mmc.c @@ -0,0 +1,162 @@ +/* + * dfu.c -- DFU back-end routines + * + * Copyright (C) 2012 Samsung Electronics + * author: Lukasz Majewski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +enum dfu_mmc_op { + DFU_OP_READ = 1, + DFU_OP_WRITE, +}; + +static int mmc_block_op(enum dfu_mmc_op op, struct dfu_entity *dfu, + void *buf, long *len) +{ + char cmd_buf[DFU_CMD_BUF_SIZE]; + + sprintf(cmd_buf, "mmc %s 0x%x %x %x", + op == DFU_OP_READ ? "read" : "write", + (unsigned int) buf, + dfu->data.mmc.lba_start, + dfu->data.mmc.lba_size); + + if (op == DFU_OP_READ) + *len = dfu->data.mmc.lba_blk_size * dfu->data.mmc.lba_size; + + debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); + return run_command(cmd_buf, 0); +} + +static inline int mmc_block_write(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_block_op(DFU_OP_WRITE, dfu, buf, len); +} + +static inline int mmc_block_read(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_block_op(DFU_OP_READ, dfu, buf, len); +} + +static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu, + void *buf, long *len) +{ + char cmd_buf[DFU_CMD_BUF_SIZE]; + char *str_env; + int ret; + + sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s %lx", + op == DFU_OP_READ ? "load" : "write", + dfu->data.mmc.dev, dfu->data.mmc.part, + (unsigned int) buf, dfu->name, *len); + + debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); + + ret = run_command(cmd_buf, 0); + if (ret) { + puts("dfu: Read error!\n"); + return ret; + } + + if (dfu->layout != DFU_RAW_ADDR) { + str_env = getenv("filesize"); + if (str_env == NULL) { + puts("dfu: Wrong file size!\n"); + return -1; + } + *len = simple_strtoul(str_env, NULL, 16); + } + + return ret; +} + +static inline int mmc_file_write(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_file_op(DFU_OP_WRITE, dfu, buf, len); +} + +static inline int mmc_file_read(struct dfu_entity *dfu, void *buf, long *len) +{ + return mmc_file_op(DFU_OP_READ, dfu, buf, len); +} + +int dfu_write_medium_mmc(struct dfu_entity *dfu, void *buf, long *len) +{ + int ret = -1; + + switch (dfu->layout) { + case DFU_RAW_ADDR: + ret = mmc_block_write(dfu, buf, len); + break; + case DFU_FS_FAT: + ret = mmc_file_write(dfu, buf, len); + break; + default: + printf("%s: Layout (%s) not (yet) supported!\n", __func__, + dfu_get_layout(dfu->layout)); + } + + return ret; +} + +int dfu_read_medium_mmc(struct dfu_entity *dfu, void *buf, long *len) +{ + int ret = -1; + + switch (dfu->layout) { + case DFU_RAW_ADDR: + ret = mmc_block_read(dfu, buf, len); + break; + case DFU_FS_FAT: + ret = mmc_file_read(dfu, buf, len); + break; + default: + printf("%s: Layout (%s) not (yet) supported!\n", __func__, + dfu_get_layout(dfu->layout)); + } + + return ret; +} + +int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s) +{ + char *st; + + dfu->dev_type = DFU_DEV_MMC; + st = strsep(&s, " "); + if (!strcmp(st, "mmc")) { + dfu->layout = DFU_RAW_ADDR; + dfu->data.mmc.lba_start = simple_strtoul(s, &s, 16); + dfu->data.mmc.lba_size = simple_strtoul(++s, &s, 16); + dfu->data.mmc.lba_blk_size = get_mmc_blk_size(dfu->dev_num); + } else if (!strcmp(st, "fat")) { + dfu->layout = DFU_FS_FAT; + dfu->data.mmc.dev = simple_strtoul(s, &s, 10); + dfu->data.mmc.part = simple_strtoul(++s, &s, 10); + } else { + printf("%s: Memory layout (%s) not supported!\n", __func__, st); + } + + dfu->read_medium = dfu_read_medium_mmc; + dfu->write_medium = dfu_write_medium_mmc; + + return 0; +} -- cgit v1.1 From a006a5deaa3d65850a3250b2136f91d2f38c96c1 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 6 Aug 2012 14:41:09 +0200 Subject: dfu:cmd: Support for DFU u-boot command Support for u-boot's command line command "dfu [list]". Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Cc: Marek Vasut --- common/Makefile | 1 + common/cmd_dfu.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 common/cmd_dfu.c diff --git a/common/Makefile b/common/Makefile index 3d62775..57da76f 100644 --- a/common/Makefile +++ b/common/Makefile @@ -184,6 +184,7 @@ COBJS-$(CONFIG_MENU) += menu.o COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o COBJS-$(CONFIG_UPDATE_TFTP) += update.o COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o +COBJS-$(CONFIG_CMD_DFU) += cmd_dfu.o endif ifdef CONFIG_SPL_BUILD diff --git a/common/cmd_dfu.c b/common/cmd_dfu.c new file mode 100644 index 0000000..62fb890 --- /dev/null +++ b/common/cmd_dfu.c @@ -0,0 +1,81 @@ +/* + * cmd_dfu.c -- dfu command + * + * Copyright (C) 2012 Samsung Electronics + * authors: Andrzej Pietrasiewicz + * Lukasz Majewski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + const char *str_env; + char s[] = "dfu"; + char *env_bkp; + int ret; + + if (argc < 3) + return CMD_RET_USAGE; + + str_env = getenv("dfu_alt_info"); + if (str_env == NULL) { + printf("%s: \"dfu_alt_info\" env variable not defined!\n", + __func__); + return CMD_RET_FAILURE; + } + + env_bkp = strdup(str_env); + ret = dfu_config_entities(env_bkp, argv[1], + (int)simple_strtoul(argv[2], NULL, 10)); + if (ret) + return CMD_RET_FAILURE; + + if (strcmp(argv[3], "list") == 0) { + dfu_show_entities(); + goto done; + } + + board_usb_init(); + g_dnl_register(s); + while (1) { + if (ctrlc()) + goto exit; + + usb_gadget_handle_interrupts(); + } +exit: + g_dnl_unregister(); +done: + dfu_free_entities(); + free(env_bkp); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu, + "Device Firmware Upgrade", + " [list]\n" + " - device firmware upgrade on a device \n" + " attached to interface \n" + " [list] - list available alt settings" +); -- cgit v1.1 From a241d6ef43168ff80dfc28eed55f5f94266bda46 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 6 Aug 2012 14:41:10 +0200 Subject: arm:trats: Support for USB UDC driver at TRATS board. Support for USB UDC driver at trats board. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Cc: Marek Vasut Cc: Minkyu Kang --- board/samsung/trats/trats.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index a8b2b11..4f9cb5a 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -59,6 +59,8 @@ static int hwrevision(int rev) return (board_rev & 0xf) == rev; } +struct s3c_plat_otg_data s5pc210_otg_data; + int board_init(void) { gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; @@ -259,6 +261,12 @@ struct s3c_plat_otg_data s5pc210_otg_data = { .usb_phy_ctrl = EXYNOS4_USBPHY_CONTROL, .usb_flags = PHY0_SLEEP, }; + +void board_usb_init(void) +{ + debug("USB_udc_probe\n"); + s3c_udc_probe(&s5pc210_otg_data); +} #endif static void pmic_reset(void) -- cgit v1.1 From 93a1ab57f340b890e9e5b48b143869bc063d625f Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Mon, 6 Aug 2012 14:41:11 +0200 Subject: arm:trats: Enable g_dnl composite USB gadget with embedded DFU function on TRATS Enable the g_dnl composite USB gadget driver with embedded DFU function on it. It now uses the composite gadget framework to support download specific USB functions (like enabled DFU or USB Mass Storage). Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Cc: Marek Vasut Cc: Minkyu Kang --- include/configs/trats.h | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/include/configs/trats.h b/include/configs/trats.h index d2dfc9f..7664a79 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -95,6 +95,21 @@ #undef CONFIG_CMD_ONENAND #undef CONFIG_CMD_MTDPARTS #define CONFIG_CMD_MMC +#define CONFIG_CMD_DFU + +/* FAT */ +#define CONFIG_CMD_FAT +#define CONFIG_FAT_WRITE + +/* USB Composite download gadget - g_dnl */ +#define CONFIG_USBDOWNLOAD_GADGET +#define CONFIG_DFU_FUNCTION +#define CONFIG_DFU_MMC + +/* USB Samsung's IDs */ +#define CONFIG_G_DNL_VENDOR_NUM 0x04E8 +#define CONFIG_G_DNL_PRODUCT_NUM 0x6601 +#define CONFIG_G_DNL_MANUFACTURER "Samsung" #define CONFIG_BOOTDELAY 1 #define CONFIG_ZERO_BOOTDELAY_CHECK @@ -105,6 +120,11 @@ #define CONFIG_BOOTBLOCK "10" #define CONFIG_ENV_COMMON_BOOT "${console} ${meminfo}" +#define CONFIG_DFU_ALT \ + "dfu_alt_info=" \ + "u-boot mmc 80 400;" \ + "uImage fat 0 2\0" \ + #define CONFIG_ENV_OVERWRITE #define CONFIG_SYS_CONSOLE_INFO_QUIET #define CONFIG_SYS_CONSOLE_IS_IN_ENV @@ -147,7 +167,8 @@ "mmcdev=0\0" \ "mmcbootpart=2\0" \ "mmcrootpart=3\0" \ - "opts=always_resume=1" + "opts=always_resume=1\0" \ + CONFIG_DFU_ALT /* Miscellaneous configurable options */ #define CONFIG_SYS_LONGHELP /* undef to save memory */ @@ -210,6 +231,7 @@ #define CONFIG_USB_GADGET #define CONFIG_USB_GADGET_S3C_UDC_OTG #define CONFIG_USB_GADGET_DUALSPEED +#define CONFIG_USB_GADGET_VBUS_DRAW 2 /* LCD */ #define CONFIG_EXYNOS_FB -- cgit v1.1 From 44ae0be7461f0ac72fa53b1a5bcd03c26e1d4fb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Thu, 9 Aug 2012 23:50:44 +0200 Subject: ehci: Fail for multi-transaction interrupt transfers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Interrupt transfers requiring several transactions are not supported by submit_int_msg() because bInterval is ignored. This patch returns a failure code and prints an error message in this case. Signed-off-by: Benoît Thébaudeau Cc: Marek Vasut Cc: Ilya Yanok Cc: Stefan Herbrechtsmeier --- drivers/usb/host/ehci-hcd.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 5b3b906..2a00389 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -819,8 +819,17 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int length, int interval) { - debug("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d", dev, pipe, buffer, length, interval); + + /* + * Interrupt transfers requiring several transactions are not supported + * because bInterval is ignored. + */ + if (length > usb_maxpacket(dev, pipe)) { + printf("%s: Interrupt transfers requiring several transactions " + "are not supported.\n", __func__); + return -1; + } return ehci_submit_async(dev, pipe, buffer, length, NULL); } -- cgit v1.1 From 14eb79b7a0861b299c6811e779ece7acf1cf320b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 18:22:11 +0200 Subject: ehci: cosmetic: Define used constants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make some light cosmetic code cleanup by the way. Signed-off-by: Benoît Thébaudeau Cc: Marek Vasut Cc: Ilya Yanok Cc: Stefan Herbrechtsmeier --- drivers/usb/host/ehci-hcd.c | 138 ++++++++++++++++++++++---------------------- drivers/usb/host/ehci.h | 49 +++++++++++++++- 2 files changed, 118 insertions(+), 69 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 2a00389..00a155b 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -163,7 +163,7 @@ static int ehci_reset(void) #ifdef CONFIG_USB_EHCI_TXFIFO_THRESH cmd = ehci_readl(&hcor->or_txfilltuning); - cmd &= ~TXFIFO_THRESH(0x3f); + cmd &= ~TXFIFO_THRESH_MASK; cmd |= TXFIFO_THRESH(CONFIG_USB_EHCI_TXFIFO_THRESH); ehci_writel(&hcor->or_txfilltuning, cmd); #endif @@ -186,7 +186,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz) while (idx < QT_BUFFER_CNT) { td->qt_buffer[idx] = cpu_to_hc32(addr); td->qt_buffer_hi[idx] = 0; - next = (addr + 4096) & ~4095; + next = (addr + EHCI_PAGE_SIZE) & ~(EHCI_PAGE_SIZE - 1); delta = next - addr; if (delta >= sz) break; @@ -208,7 +208,8 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, int length, struct devrequest *req) { ALLOC_ALIGN_BUFFER(struct QH, qh, 1, USB_DMA_MINALIGN); - ALLOC_ALIGN_BUFFER(struct qTD, qtd, 3, USB_DMA_MINALIGN); +#define QTD_COUNT 3 + ALLOC_ALIGN_BUFFER(struct qTD, qtd, QTD_COUNT, USB_DMA_MINALIGN); int qtd_counter = 0; volatile struct qTD *vtd; @@ -230,7 +231,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, le16_to_cpu(req->index)); memset(qh, 0, sizeof(struct QH)); - memset(qtd, 0, 3 * sizeof(*qtd)); + memset(qtd, 0, QTD_COUNT * sizeof(*qtd)); toggle = usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); @@ -245,20 +246,17 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, * - qh_overlay.qt_altnext */ qh->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH); - c = (usb_pipespeed(pipe) != USB_SPEED_HIGH && - usb_pipeendpoint(pipe) == 0) ? 1 : 0; - endpt = (8 << 28) | - (c << 27) | - (usb_maxpacket(dev, pipe) << 16) | - (0 << 15) | - (1 << 14) | - (usb_pipespeed(pipe) << 12) | - (usb_pipeendpoint(pipe) << 8) | - (0 << 7) | (usb_pipedevice(pipe) << 0); + c = usb_pipespeed(pipe) != USB_SPEED_HIGH && !usb_pipeendpoint(pipe); + endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) | + QH_ENDPT1_MAXPKTLEN(usb_maxpacket(dev, pipe)) | QH_ENDPT1_H(0) | + QH_ENDPT1_DTC(QH_ENDPT1_DTC_DT_FROM_QTD) | + QH_ENDPT1_EPS(usb_pipespeed(pipe)) | + QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) | + QH_ENDPT1_DEVADDR(usb_pipedevice(pipe)); qh->qh_endpt1 = cpu_to_hc32(endpt); - endpt = (1 << 30) | - (dev->portnr << 23) | - (dev->parent->devnum << 16) | (0 << 8) | (0 << 0); + endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_PORTNUM(dev->portnr) | + QH_ENDPT2_HUBADDR(dev->parent->devnum) | + QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0); qh->qh_endpt2 = cpu_to_hc32(endpt); qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); @@ -276,12 +274,13 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, */ qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); - token = (0 << 31) | - (sizeof(*req) << 16) | - (0 << 15) | (0 << 12) | (3 << 10) | (2 << 8) | (0x80 << 0); + token = QT_TOKEN_DT(0) | QT_TOKEN_TOTALBYTES(sizeof(*req)) | + QT_TOKEN_IOC(0) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) | + QT_TOKEN_PID(QT_TOKEN_PID_SETUP) | + QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE); qtd[qtd_counter].qt_token = cpu_to_hc32(token); - if (ehci_td_buffer(&qtd[qtd_counter], req, sizeof(*req)) != 0) { - printf("unable construct SETUP td\n"); + if (ehci_td_buffer(&qtd[qtd_counter], req, sizeof(*req))) { + printf("unable to construct SETUP TD\n"); goto fail; } /* Update previous qTD! */ @@ -302,15 +301,14 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, */ qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); - token = (toggle << 31) | - (length << 16) | - ((req == NULL ? 1 : 0) << 15) | - (0 << 12) | - (3 << 10) | - ((usb_pipein(pipe) ? 1 : 0) << 8) | (0x80 << 0); + token = QT_TOKEN_DT(toggle) | QT_TOKEN_TOTALBYTES(length) | + QT_TOKEN_IOC(req == NULL) | QT_TOKEN_CPAGE(0) | + QT_TOKEN_CERR(3) | QT_TOKEN_PID(usb_pipein(pipe) ? + QT_TOKEN_PID_IN : QT_TOKEN_PID_OUT) | + QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE); qtd[qtd_counter].qt_token = cpu_to_hc32(token); - if (ehci_td_buffer(&qtd[qtd_counter], buffer, length) != 0) { - printf("unable construct DATA td\n"); + if (ehci_td_buffer(&qtd[qtd_counter], buffer, length)) { + printf("unable to construct DATA TD\n"); goto fail; } /* Update previous qTD! */ @@ -328,12 +326,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, */ qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); - token = (toggle << 31) | - (0 << 16) | - (1 << 15) | - (0 << 12) | - (3 << 10) | - ((usb_pipein(pipe) ? 0 : 1) << 8) | (0x80 << 0); + token = QT_TOKEN_DT(toggle) | QT_TOKEN_TOTALBYTES(0) | + QT_TOKEN_IOC(1) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) | + QT_TOKEN_PID(usb_pipein(pipe) ? + QT_TOKEN_PID_OUT : QT_TOKEN_PID_IN) | + QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE); qtd[qtd_counter].qt_token = cpu_to_hc32(token); /* Update previous qTD! */ *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]); @@ -346,7 +343,8 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, flush_dcache_range((uint32_t)qh_list, ALIGN_END_ADDR(struct QH, qh_list, 1)); flush_dcache_range((uint32_t)qh, ALIGN_END_ADDR(struct QH, qh, 1)); - flush_dcache_range((uint32_t)qtd, ALIGN_END_ADDR(struct qTD, qtd, 3)); + flush_dcache_range((uint32_t)qtd, + ALIGN_END_ADDR(struct qTD, qtd, QTD_COUNT)); /* Set async. queue head pointer. */ ehci_writel(&hcor->or_asynclistaddr, (uint32_t)qh_list); @@ -359,10 +357,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, cmd |= CMD_ASE; ehci_writel(&hcor->or_usbcmd, cmd); - ret = handshake((uint32_t *)&hcor->or_usbsts, STD_ASS, STD_ASS, + ret = handshake((uint32_t *)&hcor->or_usbsts, STS_ASS, STS_ASS, 100 * 1000); if (ret < 0) { - printf("EHCI fail timeout STD_ASS set\n"); + printf("EHCI fail timeout STS_ASS set\n"); goto fail; } @@ -377,10 +375,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, invalidate_dcache_range((uint32_t)qh, ALIGN_END_ADDR(struct QH, qh, 1)); invalidate_dcache_range((uint32_t)qtd, - ALIGN_END_ADDR(struct qTD, qtd, 3)); + ALIGN_END_ADDR(struct qTD, qtd, QTD_COUNT)); token = hc32_to_cpu(vtd->qt_token); - if (!(token & 0x80)) + if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)) break; WATCHDOG_RESET(); } while (get_timer(ts) < timeout); @@ -398,50 +396,50 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, ALIGN((uint32_t)buffer + length, ARCH_DMA_MINALIGN)); /* Check that the TD processing happened */ - if (token & 0x80) { + if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE) printf("EHCI timed out on TD - token=%#x\n", token); - } /* Disable async schedule. */ cmd = ehci_readl(&hcor->or_usbcmd); cmd &= ~CMD_ASE; ehci_writel(&hcor->or_usbcmd, cmd); - ret = handshake((uint32_t *)&hcor->or_usbsts, STD_ASS, 0, + ret = handshake((uint32_t *)&hcor->or_usbsts, STS_ASS, 0, 100 * 1000); if (ret < 0) { - printf("EHCI fail timeout STD_ASS reset\n"); + printf("EHCI fail timeout STS_ASS reset\n"); goto fail; } token = hc32_to_cpu(qh->qh_overlay.qt_token); - if (!(token & 0x80)) { + if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)) { debug("TOKEN=%#x\n", token); - switch (token & 0xfc) { + switch (QT_TOKEN_GET_STATUS(token) & + ~(QT_TOKEN_STATUS_SPLITXSTATE | QT_TOKEN_STATUS_PERR)) { case 0: - toggle = token >> 31; + toggle = QT_TOKEN_GET_DT(token); usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), toggle); dev->status = 0; break; - case 0x40: + case QT_TOKEN_STATUS_HALTED: dev->status = USB_ST_STALLED; break; - case 0xa0: - case 0x20: + case QT_TOKEN_STATUS_ACTIVE | QT_TOKEN_STATUS_DATBUFERR: + case QT_TOKEN_STATUS_DATBUFERR: dev->status = USB_ST_BUF_ERR; break; - case 0x50: - case 0x10: + case QT_TOKEN_STATUS_HALTED | QT_TOKEN_STATUS_BABBLEDET: + case QT_TOKEN_STATUS_BABBLEDET: dev->status = USB_ST_BABBLE_DET; break; default: dev->status = USB_ST_CRC_ERR; - if ((token & 0x40) == 0x40) + if (QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_HALTED) dev->status |= USB_ST_STALLED; break; } - dev->act_len = length - ((token >> 16) & 0x7fff); + dev->act_len = length - QT_TOKEN_GET_TOTALBYTES(token); } else { dev->act_len = 0; debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\n", @@ -499,12 +497,14 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, case USB_DT_DEVICE: debug("USB_DT_DEVICE request\n"); srcptr = &descriptor.device; - srclen = 0x12; + srclen = descriptor.device.bLength; break; case USB_DT_CONFIG: debug("USB_DT_CONFIG config\n"); srcptr = &descriptor.config; - srclen = 0x19; + srclen = descriptor.config.bLength + + descriptor.interface.bLength + + descriptor.endpoint.bLength; break; case USB_DT_STRING: debug("USB_DT_STRING config\n"); @@ -539,7 +539,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, case USB_DT_HUB: debug("USB_DT_HUB config\n"); srcptr = &descriptor.hub; - srclen = 0x8; + srclen = descriptor.hub.bLength; break; default: debug("unknown value %x\n", le16_to_cpu(req->value)); @@ -577,13 +577,13 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, tmpbuf[1] |= USB_PORT_STAT_POWER >> 8; if (ehci_is_TDI()) { - switch ((reg >> 26) & 3) { - case 0: + switch (PORTSC_PSPD(reg)) { + case PORTSC_PSPD_FS: break; - case 1: + case PORTSC_PSPD_LS: tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8; break; - case 2: + case PORTSC_PSPD_HS: default: tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8; break; @@ -729,26 +729,28 @@ int usb_lowlevel_init(void) uint32_t reg; uint32_t cmd; - if (ehci_hcd_init() != 0) + if (ehci_hcd_init()) return -1; /* EHCI spec section 4.1 */ - if (ehci_reset() != 0) + if (ehci_reset()) return -1; #if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET) - if (ehci_hcd_init() != 0) + if (ehci_hcd_init()) return -1; #endif /* Set head of reclaim list */ memset(qh_list, 0, sizeof(*qh_list)); qh_list->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH); - qh_list->qh_endpt1 = cpu_to_hc32((1 << 15) | (USB_SPEED_HIGH << 12)); + qh_list->qh_endpt1 = cpu_to_hc32(QH_ENDPT1_H(1) | + QH_ENDPT1_EPS(USB_SPEED_HIGH)); qh_list->qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE); qh_list->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qh_list->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); - qh_list->qh_overlay.qt_token = cpu_to_hc32(0x40); + qh_list->qh_overlay.qt_token = + cpu_to_hc32(QT_TOKEN_STATUS(QT_TOKEN_STATUS_HALTED)); reg = ehci_readl(&hccr->cr_hcsparams); descriptor.hub.bNbrPorts = HCS_N_PORTS(reg); @@ -808,7 +810,7 @@ submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, } if (usb_pipedevice(pipe) == rootdev) { - if (rootdev == 0) + if (!rootdev) dev->speed = USB_SPEED_HIGH; return ehci_submit_root(dev, pipe, buffer, length, setup); } diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 7992983..39acdf9 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -68,7 +68,7 @@ struct ehci_hcor { #define CMD_RESET (1 << 1) /* reset HC not bus */ #define CMD_RUN (1 << 0) /* start/stop HC */ uint32_t or_usbsts; -#define STD_ASS (1 << 15) +#define STS_ASS (1 << 15) #define STS_HALT (1 << 12) uint32_t or_usbintr; #define INTR_UE (1 << 0) /* USB interrupt enable */ @@ -83,11 +83,16 @@ struct ehci_hcor { uint32_t _reserved_0_; uint32_t or_burstsize; uint32_t or_txfilltuning; +#define TXFIFO_THRESH_MASK (0x3f << 16) #define TXFIFO_THRESH(p) ((p & 0x3f) << 16) uint32_t _reserved_1_[6]; uint32_t or_configflag; #define FLAG_CF (1 << 0) /* true: we'll support "high speed" */ uint32_t or_portsc[CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS]; +#define PORTSC_PSPD(x) (((x) >> 26) & 0x3) +#define PORTSC_PSPD_FS 0x0 +#define PORTSC_PSPD_LS 0x1 +#define PORTSC_PSPD_HS 0x2 uint32_t or_systune; } __attribute__ ((packed, aligned(4))); @@ -175,6 +180,27 @@ struct qTD { #define QT_NEXT_TERMINATE 1 uint32_t qt_altnext; /* see EHCI 3.5.2 */ uint32_t qt_token; /* see EHCI 3.5.3 */ +#define QT_TOKEN_DT(x) (((x) & 0x1) << 31) /* Data Toggle */ +#define QT_TOKEN_GET_DT(x) (((x) >> 31) & 0x1) +#define QT_TOKEN_TOTALBYTES(x) (((x) & 0x7fff) << 16) /* Total Bytes to Transfer */ +#define QT_TOKEN_GET_TOTALBYTES(x) (((x) >> 16) & 0x7fff) +#define QT_TOKEN_IOC(x) (((x) & 0x1) << 15) /* Interrupt On Complete */ +#define QT_TOKEN_CPAGE(x) (((x) & 0x7) << 12) /* Current Page */ +#define QT_TOKEN_CERR(x) (((x) & 0x3) << 10) /* Error Counter */ +#define QT_TOKEN_PID(x) (((x) & 0x3) << 8) /* PID Code */ +#define QT_TOKEN_PID_OUT 0x0 +#define QT_TOKEN_PID_IN 0x1 +#define QT_TOKEN_PID_SETUP 0x2 +#define QT_TOKEN_STATUS(x) (((x) & 0xff) << 0) /* Status */ +#define QT_TOKEN_GET_STATUS(x) (((x) >> 0) & 0xff) +#define QT_TOKEN_STATUS_ACTIVE 0x80 +#define QT_TOKEN_STATUS_HALTED 0x40 +#define QT_TOKEN_STATUS_DATBUFERR 0x20 +#define QT_TOKEN_STATUS_BABBLEDET 0x10 +#define QT_TOKEN_STATUS_XACTERR 0x08 +#define QT_TOKEN_STATUS_MISSEDUFRAME 0x04 +#define QT_TOKEN_STATUS_SPLITXSTATE 0x02 +#define QT_TOKEN_STATUS_PERR 0x01 #define QT_BUFFER_CNT 5 uint32_t qt_buffer[QT_BUFFER_CNT]; /* see EHCI 3.5.4 */ uint32_t qt_buffer_hi[QT_BUFFER_CNT]; /* Appendix B */ @@ -182,6 +208,8 @@ struct qTD { uint32_t unused[3]; }; +#define EHCI_PAGE_SIZE 4096 + /* Queue Head (QH). */ struct QH { uint32_t qh_link; @@ -191,7 +219,26 @@ struct QH { #define QH_LINK_TYPE_SITD 4 #define QH_LINK_TYPE_FSTN 6 uint32_t qh_endpt1; +#define QH_ENDPT1_RL(x) (((x) & 0xf) << 28) /* NAK Count Reload */ +#define QH_ENDPT1_C(x) (((x) & 0x1) << 27) /* Control Endpoint Flag */ +#define QH_ENDPT1_MAXPKTLEN(x) (((x) & 0x7ff) << 16) /* Maximum Packet Length */ +#define QH_ENDPT1_H(x) (((x) & 0x1) << 15) /* Head of Reclamation List Flag */ +#define QH_ENDPT1_DTC(x) (((x) & 0x1) << 14) /* Data Toggle Control */ +#define QH_ENDPT1_DTC_IGNORE_QTD_TD 0x0 +#define QH_ENDPT1_DTC_DT_FROM_QTD 0x1 +#define QH_ENDPT1_EPS(x) (((x) & 0x3) << 12) /* Endpoint Speed */ +#define QH_ENDPT1_EPS_FS 0x0 +#define QH_ENDPT1_EPS_LS 0x1 +#define QH_ENDPT1_EPS_HS 0x2 +#define QH_ENDPT1_ENDPT(x) (((x) & 0xf) << 8) /* Endpoint Number */ +#define QH_ENDPT1_I(x) (((x) & 0x1) << 7) /* Inactivate on Next Transaction */ +#define QH_ENDPT1_DEVADDR(x) (((x) & 0x7f) << 0) /* Device Address */ uint32_t qh_endpt2; +#define QH_ENDPT2_MULT(x) (((x) & 0x3) << 30) /* High-Bandwidth Pipe Multiplier */ +#define QH_ENDPT2_PORTNUM(x) (((x) & 0x7f) << 23) /* Port Number */ +#define QH_ENDPT2_HUBADDR(x) (((x) & 0x7f) << 16) /* Hub Address */ +#define QH_ENDPT2_UFCMASK(x) (((x) & 0xff) << 8) /* Split Completion Mask */ +#define QH_ENDPT2_UFSMASK(x) (((x) & 0xff) << 0) /* Interrupt Schedule Mask */ uint32_t qh_curtd; struct qTD qh_overlay; /* -- cgit v1.1 From 5cec214ecd7ddabc5480958c5355139c07ba8cee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 18:22:32 +0200 Subject: ehci-hcd: Boost transfer speed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch takes advantage of the hardware EHCI qTD queuing mechanism to avoid software and transfer splitting overhead so as to make transfers as fast as possible. The only drawback is a call to memalign. However, this is fast compared to the transfer timings, and the heap size to allocate is small, e.g. 128 kiB in the worst case for a transfer length of 65535 packets of 512 bytes. Tested on i.MX25, i.MX35 and i.MX51. In my test conditions, the speed gain was very significant (several times faster), which is really appreciable when accessing large files. Signed-off-by: Benoît Thébaudeau Cc: Marek Vasut Cc: Ilya Yanok Cc: Stefan Herbrechtsmeier --- drivers/usb/host/ehci-hcd.c | 167 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 138 insertions(+), 29 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 00a155b..a0ef5db 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -208,8 +208,8 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, int length, struct devrequest *req) { ALLOC_ALIGN_BUFFER(struct QH, qh, 1, USB_DMA_MINALIGN); -#define QTD_COUNT 3 - ALLOC_ALIGN_BUFFER(struct qTD, qtd, QTD_COUNT, USB_DMA_MINALIGN); + struct qTD *qtd; + int qtd_count = 0; int qtd_counter = 0; volatile struct qTD *vtd; @@ -230,8 +230,74 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, le16_to_cpu(req->value), le16_to_cpu(req->value), le16_to_cpu(req->index)); + /* + * The USB transfer is split into qTD transfers. Eeach qTD transfer is + * described by a transfer descriptor (the qTD). The qTDs form a linked + * list with a queue head (QH). + * + * Each qTD transfer starts with a new USB packet, i.e. a packet cannot + * have its beginning in a qTD transfer and its end in the following + * one, so the qTD transfer lengths have to be chosen accordingly. + * + * Each qTD transfer uses up to QT_BUFFER_CNT data buffers, mapped to + * single pages. The first data buffer can start at any offset within a + * page (not considering the cache-line alignment issues), while the + * following buffers must be page-aligned. There is no alignment + * constraint on the size of a qTD transfer. + */ + if (req != NULL) + /* 1 qTD will be needed for SETUP, and 1 for ACK. */ + qtd_count += 1 + 1; + if (length > 0 || req == NULL) { + /* + * Determine the qTD transfer size that will be used for the + * data payload (not considering the final qTD transfer, which + * may be shorter). + * + * In order to keep each packet within a qTD transfer, the qTD + * transfer size is aligned to EHCI_PAGE_SIZE, which is a + * multiple of wMaxPacketSize (except in some cases for + * interrupt transfers, see comment in submit_int_msg()). + * + * By default, i.e. if the input buffer is page-aligned, + * QT_BUFFER_CNT full pages will be used. + */ + int xfr_sz = QT_BUFFER_CNT; + /* + * However, if the input buffer is not page-aligned, the qTD + * transfer size will be one page shorter, and the first qTD + * data buffer of each transfer will be page-unaligned. + */ + if ((uint32_t)buffer & (EHCI_PAGE_SIZE - 1)) + xfr_sz--; + /* Convert the qTD transfer size to bytes. */ + xfr_sz *= EHCI_PAGE_SIZE; + /* + * Determine the number of qTDs that will be required for the + * data payload. This value has to be rounded up since the final + * qTD transfer may be shorter than the regular qTD transfer + * size that has just been computed. + */ + qtd_count += DIV_ROUND_UP(length, xfr_sz); + /* ZLPs also need a qTD. */ + if (!qtd_count) + qtd_count++; + } +/* + * Threshold value based on the worst-case total size of the qTDs to allocate + * for a mass-storage transfer of 65535 blocks of 512 bytes. + */ +#if CONFIG_SYS_MALLOC_LEN <= 128 * 1024 +#warning CONFIG_SYS_MALLOC_LEN may be too small for EHCI +#endif + qtd = memalign(USB_DMA_MINALIGN, qtd_count * sizeof(struct qTD)); + if (qtd == NULL) { + printf("unable to allocate TDs\n"); + return -1; + } + memset(qh, 0, sizeof(struct QH)); - memset(qtd, 0, QTD_COUNT * sizeof(*qtd)); + memset(qtd, 0, qtd_count * sizeof(*qtd)); toggle = usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); @@ -290,30 +356,64 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, } if (length > 0 || req == NULL) { - /* - * Setup request qTD (3.5 in ehci-r10.pdf) - * - * qt_next ................ 03-00 H - * qt_altnext ............. 07-04 H - * qt_token ............... 0B-08 H - * - * [ buffer, buffer_hi ] loaded with "buffer". - */ - qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); - qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); - token = QT_TOKEN_DT(toggle) | QT_TOKEN_TOTALBYTES(length) | - QT_TOKEN_IOC(req == NULL) | QT_TOKEN_CPAGE(0) | - QT_TOKEN_CERR(3) | QT_TOKEN_PID(usb_pipein(pipe) ? - QT_TOKEN_PID_IN : QT_TOKEN_PID_OUT) | - QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE); - qtd[qtd_counter].qt_token = cpu_to_hc32(token); - if (ehci_td_buffer(&qtd[qtd_counter], buffer, length)) { - printf("unable to construct DATA TD\n"); - goto fail; - } - /* Update previous qTD! */ - *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]); - tdp = &qtd[qtd_counter++].qt_next; + uint8_t *buf_ptr = buffer; + int left_length = length; + + do { + /* + * Determine the size of this qTD transfer. By default, + * QT_BUFFER_CNT full pages can be used. + */ + int xfr_bytes = QT_BUFFER_CNT * EHCI_PAGE_SIZE; + /* + * However, if the input buffer is not page-aligned, the + * portion of the first page before the buffer start + * offset within that page is unusable. + */ + xfr_bytes -= (uint32_t)buf_ptr & (EHCI_PAGE_SIZE - 1); + /* + * In order to keep each packet within a qTD transfer, + * align the qTD transfer size to EHCI_PAGE_SIZE. + */ + xfr_bytes &= ~(EHCI_PAGE_SIZE - 1); + /* + * This transfer may be shorter than the available qTD + * transfer size that has just been computed. + */ + xfr_bytes = min(xfr_bytes, left_length); + + /* + * Setup request qTD (3.5 in ehci-r10.pdf) + * + * qt_next ................ 03-00 H + * qt_altnext ............. 07-04 H + * qt_token ............... 0B-08 H + * + * [ buffer, buffer_hi ] loaded with "buffer". + */ + qtd[qtd_counter].qt_next = + cpu_to_hc32(QT_NEXT_TERMINATE); + qtd[qtd_counter].qt_altnext = + cpu_to_hc32(QT_NEXT_TERMINATE); + token = QT_TOKEN_DT(toggle) | + QT_TOKEN_TOTALBYTES(xfr_bytes) | + QT_TOKEN_IOC(req == NULL) | QT_TOKEN_CPAGE(0) | + QT_TOKEN_CERR(3) | + QT_TOKEN_PID(usb_pipein(pipe) ? + QT_TOKEN_PID_IN : QT_TOKEN_PID_OUT) | + QT_TOKEN_STATUS(QT_TOKEN_STATUS_ACTIVE); + qtd[qtd_counter].qt_token = cpu_to_hc32(token); + if (ehci_td_buffer(&qtd[qtd_counter], buf_ptr, + xfr_bytes)) { + printf("unable to construct DATA TD\n"); + goto fail; + } + /* Update previous qTD! */ + *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]); + tdp = &qtd[qtd_counter++].qt_next; + buf_ptr += xfr_bytes; + left_length -= xfr_bytes; + } while (left_length > 0); } if (req != NULL) { @@ -344,7 +444,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, ALIGN_END_ADDR(struct QH, qh_list, 1)); flush_dcache_range((uint32_t)qh, ALIGN_END_ADDR(struct QH, qh, 1)); flush_dcache_range((uint32_t)qtd, - ALIGN_END_ADDR(struct qTD, qtd, QTD_COUNT)); + ALIGN_END_ADDR(struct qTD, qtd, qtd_count)); /* Set async. queue head pointer. */ ehci_writel(&hcor->or_asynclistaddr, (uint32_t)qh_list); @@ -375,7 +475,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, invalidate_dcache_range((uint32_t)qh, ALIGN_END_ADDR(struct QH, qh, 1)); invalidate_dcache_range((uint32_t)qtd, - ALIGN_END_ADDR(struct qTD, qtd, QTD_COUNT)); + ALIGN_END_ADDR(struct qTD, qtd, qtd_count)); token = hc32_to_cpu(vtd->qt_token); if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)) @@ -448,9 +548,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, ehci_readl(&hcor->or_portsc[1])); } + free(qtd); return (dev->status != USB_ST_NOT_PROC) ? 0 : -1; fail: + free(qtd); return -1; } @@ -827,6 +929,13 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, /* * Interrupt transfers requiring several transactions are not supported * because bInterval is ignored. + * + * Also, ehci_submit_async() relies on wMaxPacketSize being a power of 2 + * if several qTDs are required, while the USB specification does not + * constrain this for interrupt transfers. That means that + * ehci_submit_async() would support interrupt transfers requiring + * several transactions only as long as the transfer size does not + * require more than a single qTD. */ if (length > usb_maxpacket(dev, pipe)) { printf("%s: Interrupt transfers requiring several transactions " -- cgit v1.1 From cffcc503580907d733e694d505e12ff6ec6c679a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 18:26:50 +0200 Subject: usb_storage: Restore non-EHCI support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commit 5dd95cf made the MSC driver EHCI-specific. This patch restores a basic support of non-EHCI HCDs, like before that commit. The fallback transfer size is certainly not optimal, but at least it should work like before. Signed-off-by: Benoît Thébaudeau Cc: Marek Vasut Cc: Ilya Yanok Cc: Stefan Herbrechtsmeier --- common/usb_storage.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/usb_storage.c b/common/usb_storage.c index bdc306f..0cd6399 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -155,11 +155,15 @@ struct us_data { trans_cmnd transport; /* transport routine */ }; +#ifdef CONFIG_USB_EHCI /* * The U-Boot EHCI driver cannot handle more than 5 page aligned buffers * of 4096 bytes in a transfer without running itself out of qt_buffers */ #define USB_MAX_XFER_BLK(start, blksz) (((4096 * 5) - (start % 4096)) / blksz) +#else +#define USB_MAX_XFER_BLK(start, blksz) 20 +#endif static struct us_data usb_stor[USB_MAX_STOR_DEV]; -- cgit v1.1 From 4bee5c83ea46b5c7a5670f7decd6ba2515483d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 18:23:25 +0200 Subject: usb_storage: Remove EHCI constraints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the EHCI driver allocates its qTDs from the heap, the MSC driver is only limited by the SCSI commands it uses. Signed-off-by: Benoît Thébaudeau Cc: Marek Vasut Cc: Ilya Yanok Cc: Stefan Herbrechtsmeier --- common/usb_storage.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/common/usb_storage.c b/common/usb_storage.c index 0cd6399..099edd3 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -157,12 +157,13 @@ struct us_data { #ifdef CONFIG_USB_EHCI /* - * The U-Boot EHCI driver cannot handle more than 5 page aligned buffers - * of 4096 bytes in a transfer without running itself out of qt_buffers + * The U-Boot EHCI driver can handle any transfer length as long as there is + * enough free heap space left, but the SCSI READ(10) and WRITE(10) commands are + * limited to 65535 blocks. */ -#define USB_MAX_XFER_BLK(start, blksz) (((4096 * 5) - (start % 4096)) / blksz) +#define USB_MAX_XFER_BLK 65535 #else -#define USB_MAX_XFER_BLK(start, blksz) 20 +#define USB_MAX_XFER_BLK 20 #endif static struct us_data usb_stor[USB_MAX_STOR_DEV]; @@ -1050,7 +1051,7 @@ static void usb_bin_fixup(struct usb_device_descriptor descriptor, unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, void *buffer) { - unsigned long start, blks, buf_addr, max_xfer_blk; + unsigned long start, blks, buf_addr; unsigned short smallblks; struct usb_device *dev; struct us_data *ss; @@ -1092,14 +1093,12 @@ unsigned long usb_stor_read(int device, unsigned long blknr, /* XXX need some comment here */ retry = 2; srb->pdata = (unsigned char *)buf_addr; - max_xfer_blk = USB_MAX_XFER_BLK(buf_addr, - usb_dev_desc[device].blksz); - if (blks > max_xfer_blk) - smallblks = (unsigned short) max_xfer_blk; + if (blks > USB_MAX_XFER_BLK) + smallblks = USB_MAX_XFER_BLK; else smallblks = (unsigned short) blks; retry_it: - if (smallblks == max_xfer_blk) + if (smallblks == USB_MAX_XFER_BLK) usb_show_progress(); srb->datalen = usb_dev_desc[device].blksz * smallblks; srb->pdata = (unsigned char *)buf_addr; @@ -1120,7 +1119,7 @@ retry_it: start, smallblks, buf_addr); usb_disable_asynch(0); /* asynch transfer allowed */ - if (blkcnt >= max_xfer_blk) + if (blkcnt >= USB_MAX_XFER_BLK) debug("\n"); return blkcnt; } @@ -1128,7 +1127,7 @@ retry_it: unsigned long usb_stor_write(int device, unsigned long blknr, unsigned long blkcnt, const void *buffer) { - unsigned long start, blks, buf_addr, max_xfer_blk; + unsigned long start, blks, buf_addr; unsigned short smallblks; struct usb_device *dev; struct us_data *ss; @@ -1173,14 +1172,12 @@ unsigned long usb_stor_write(int device, unsigned long blknr, */ retry = 2; srb->pdata = (unsigned char *)buf_addr; - max_xfer_blk = USB_MAX_XFER_BLK(buf_addr, - usb_dev_desc[device].blksz); - if (blks > max_xfer_blk) - smallblks = (unsigned short) max_xfer_blk; + if (blks > USB_MAX_XFER_BLK) + smallblks = USB_MAX_XFER_BLK; else smallblks = (unsigned short) blks; retry_it: - if (smallblks == max_xfer_blk) + if (smallblks == USB_MAX_XFER_BLK) usb_show_progress(); srb->datalen = usb_dev_desc[device].blksz * smallblks; srb->pdata = (unsigned char *)buf_addr; @@ -1201,7 +1198,7 @@ retry_it: start, smallblks, buf_addr); usb_disable_asynch(0); /* asynch transfer allowed */ - if (blkcnt >= max_xfer_blk) + if (blkcnt >= USB_MAX_XFER_BLK) debug("\n"); return blkcnt; -- cgit v1.1 From 3e8581bb95899e21b01d86e9fe5ad7358bbef142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 18:27:11 +0200 Subject: usb_stor_BBB_transport: Do not delay when not required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a 5-ms delay in usb_stor_BBB_transport, which occurs every 10 kiB of data for fragmented fatload usb, i.e. roughly 500 ms of delay per MiB. This adds up to quite a bit of delay if you're loading a large ramdisk. The purpose of this delay should be to debounce the 5-V/100-mA USB power up. This patch skips the delay if the device has already been queried as ready. Signed-off-by: Jim Shimer Rework following the review: - Rebase against the latest u-boot-usb master. - Replace typedef with #define. - Use the existing flags struct field instead of adding a new field. - Remove the setter function. - Remove the typecasts. Signed-off-by: Benoît Thébaudeau Cc: Marek Vasut Cc: Ilya Yanok Cc: Stefan Herbrechtsmeier Cc: Jim Shimer --- common/usb_storage.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/common/usb_storage.c b/common/usb_storage.c index 099edd3..ccfe811 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -136,6 +136,7 @@ struct us_data { struct usb_device *pusb_dev; /* this usb_device */ unsigned int flags; /* from filter initially */ +# define USB_READY (1 << 0) unsigned char ifnum; /* interface number */ unsigned char ep_in; /* in endpoint */ unsigned char ep_out; /* out ....... */ @@ -698,7 +699,8 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us) usb_stor_BBB_reset(us); return USB_STOR_TRANSPORT_FAILED; } - mdelay(5); + if (!(us->flags & USB_READY)) + mdelay(5); pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in); pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out); /* DATA phase + error handling */ @@ -963,8 +965,10 @@ static int usb_test_unit_ready(ccb *srb, struct us_data *ss) srb->cmd[1] = srb->lun << 5; srb->datalen = 0; srb->cmdlen = 12; - if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) + if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) { + ss->flags |= USB_READY; return 0; + } usb_request_sense(srb, ss); mdelay(100); } while (retries--); @@ -1114,6 +1118,7 @@ retry_it: blks -= smallblks; buf_addr += srb->datalen; } while (blks != 0); + ss->flags &= ~USB_READY; USB_STOR_PRINTF("usb_read: end startblk %lx, blccnt %x buffer %lx\n", start, smallblks, buf_addr); @@ -1193,6 +1198,7 @@ retry_it: blks -= smallblks; buf_addr += srb->datalen; } while (blks != 0); + ss->flags &= ~USB_READY; USB_STOR_PRINTF("usb_write: end startblk %lx, blccnt %x buffer %lx\n", start, smallblks, buf_addr); @@ -1404,6 +1410,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss, cap[0] = 2880; cap[1] = 0x200; } + ss->flags &= ~USB_READY; USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n", cap[0], cap[1]); #if 0 -- cgit v1.1 From db19134615dda7e4b0b511c65e92507ab0a530d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 18:27:23 +0200 Subject: ehci: Optimize qTD allocations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Relax the qTD transfer alignment constraints in order to need less qTDs for buffers that are aligned to 512 bytes but not to pages. Signed-off-by: Benoît Thébaudeau Cc: Marek Vasut Cc: Ilya Yanok Cc: Stefan Herbrechtsmeier --- drivers/usb/host/ehci-hcd.c | 67 +++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index a0ef5db..18b4bc6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -215,7 +215,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, volatile struct qTD *vtd; unsigned long ts; uint32_t *tdp; - uint32_t endpt, token, usbsts; + uint32_t endpt, maxpacket, token, usbsts; uint32_t c, toggle; uint32_t cmd; int timeout; @@ -230,6 +230,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, le16_to_cpu(req->value), le16_to_cpu(req->value), le16_to_cpu(req->index)); +#define PKT_ALIGN 512 /* * The USB transfer is split into qTD transfers. Eeach qTD transfer is * described by a transfer descriptor (the qTD). The qTDs form a linked @@ -251,43 +252,41 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, if (length > 0 || req == NULL) { /* * Determine the qTD transfer size that will be used for the - * data payload (not considering the final qTD transfer, which - * may be shorter). + * data payload (not considering the first qTD transfer, which + * may be longer or shorter, and the final one, which may be + * shorter). * * In order to keep each packet within a qTD transfer, the qTD - * transfer size is aligned to EHCI_PAGE_SIZE, which is a - * multiple of wMaxPacketSize (except in some cases for - * interrupt transfers, see comment in submit_int_msg()). + * transfer size is aligned to PKT_ALIGN, which is a multiple of + * wMaxPacketSize (except in some cases for interrupt transfers, + * see comment in submit_int_msg()). * - * By default, i.e. if the input buffer is page-aligned, + * By default, i.e. if the input buffer is aligned to PKT_ALIGN, * QT_BUFFER_CNT full pages will be used. */ int xfr_sz = QT_BUFFER_CNT; /* - * However, if the input buffer is not page-aligned, the qTD - * transfer size will be one page shorter, and the first qTD + * However, if the input buffer is not aligned to PKT_ALIGN, the + * qTD transfer size will be one page shorter, and the first qTD * data buffer of each transfer will be page-unaligned. */ - if ((uint32_t)buffer & (EHCI_PAGE_SIZE - 1)) + if ((uint32_t)buffer & (PKT_ALIGN - 1)) xfr_sz--; /* Convert the qTD transfer size to bytes. */ xfr_sz *= EHCI_PAGE_SIZE; /* - * Determine the number of qTDs that will be required for the - * data payload. This value has to be rounded up since the final - * qTD transfer may be shorter than the regular qTD transfer - * size that has just been computed. + * Approximate by excess the number of qTDs that will be + * required for the data payload. The exact formula is way more + * complicated and saves at most 2 qTDs, i.e. a total of 128 + * bytes. */ - qtd_count += DIV_ROUND_UP(length, xfr_sz); - /* ZLPs also need a qTD. */ - if (!qtd_count) - qtd_count++; + qtd_count += 2 + length / xfr_sz; } /* - * Threshold value based on the worst-case total size of the qTDs to allocate - * for a mass-storage transfer of 65535 blocks of 512 bytes. + * Threshold value based on the worst-case total size of the allocated qTDs for + * a mass-storage transfer of 65535 blocks of 512 bytes. */ -#if CONFIG_SYS_MALLOC_LEN <= 128 * 1024 +#if CONFIG_SYS_MALLOC_LEN <= 64 + 128 * 1024 #warning CONFIG_SYS_MALLOC_LEN may be too small for EHCI #endif qtd = memalign(USB_DMA_MINALIGN, qtd_count * sizeof(struct qTD)); @@ -313,8 +312,9 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, */ qh->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH); c = usb_pipespeed(pipe) != USB_SPEED_HIGH && !usb_pipeendpoint(pipe); + maxpacket = usb_maxpacket(dev, pipe); endpt = QH_ENDPT1_RL(8) | QH_ENDPT1_C(c) | - QH_ENDPT1_MAXPKTLEN(usb_maxpacket(dev, pipe)) | QH_ENDPT1_H(0) | + QH_ENDPT1_MAXPKTLEN(maxpacket) | QH_ENDPT1_H(0) | QH_ENDPT1_DTC(QH_ENDPT1_DTC_DT_FROM_QTD) | QH_ENDPT1_EPS(usb_pipespeed(pipe)) | QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) | @@ -373,9 +373,9 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, xfr_bytes -= (uint32_t)buf_ptr & (EHCI_PAGE_SIZE - 1); /* * In order to keep each packet within a qTD transfer, - * align the qTD transfer size to EHCI_PAGE_SIZE. + * align the qTD transfer size to PKT_ALIGN. */ - xfr_bytes &= ~(EHCI_PAGE_SIZE - 1); + xfr_bytes &= ~(PKT_ALIGN - 1); /* * This transfer may be shorter than the available qTD * transfer size that has just been computed. @@ -411,6 +411,13 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, /* Update previous qTD! */ *tdp = cpu_to_hc32((uint32_t)&qtd[qtd_counter]); tdp = &qtd[qtd_counter++].qt_next; + /* + * Data toggle has to be adjusted since the qTD transfer + * size is not always an even multiple of + * wMaxPacketSize. + */ + if ((xfr_bytes / maxpacket) & 1) + toggle ^= 1; buf_ptr += xfr_bytes; left_length -= xfr_bytes; } while (left_length > 0); @@ -426,7 +433,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, */ qtd[qtd_counter].qt_next = cpu_to_hc32(QT_NEXT_TERMINATE); qtd[qtd_counter].qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); - token = QT_TOKEN_DT(toggle) | QT_TOKEN_TOTALBYTES(0) | + token = QT_TOKEN_DT(1) | QT_TOKEN_TOTALBYTES(0) | QT_TOKEN_IOC(1) | QT_TOKEN_CPAGE(0) | QT_TOKEN_CERR(3) | QT_TOKEN_PID(usb_pipein(pipe) ? QT_TOKEN_PID_OUT : QT_TOKEN_PID_IN) | @@ -931,11 +938,11 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, * because bInterval is ignored. * * Also, ehci_submit_async() relies on wMaxPacketSize being a power of 2 - * if several qTDs are required, while the USB specification does not - * constrain this for interrupt transfers. That means that - * ehci_submit_async() would support interrupt transfers requiring - * several transactions only as long as the transfer size does not - * require more than a single qTD. + * <= PKT_ALIGN if several qTDs are required, while the USB + * specification does not constrain this for interrupt transfers. That + * means that ehci_submit_async() would support interrupt transfers + * requiring several transactions only as long as the transfer size does + * not require more than a single qTD. */ if (length > usb_maxpacket(dev, pipe)) { printf("%s: Interrupt transfers requiring several transactions " -- cgit v1.1 From b7006958ea367394e39e82532317a44491ed52ac Mon Sep 17 00:00:00 2001 From: Jim Shimer Date: Mon, 30 Jul 2012 22:11:28 -0400 Subject: usb: Optimize USB storage read/write Trim down the IO times by removing uneeded test unit reeady calls. Signed-off-by: Jim Shimer --- common/usb_storage.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/common/usb_storage.c b/common/usb_storage.c index ccfe811..4aeed82 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -1083,12 +1083,6 @@ unsigned long usb_stor_read(int device, unsigned long blknr, buf_addr = (unsigned long)buffer; start = blknr; blks = blkcnt; - if (usb_test_unit_ready(srb, ss)) { - printf("Device NOT ready\n Request Sense returned %02X %02X" - " %02X\n", srb->sense_buf[2], srb->sense_buf[12], - srb->sense_buf[13]); - return 0; - } USB_STOR_PRINTF("\nusb_read: dev %d startblk %lx, blccnt %lx" " buffer %lx\n", device, start, blks, buf_addr); @@ -1161,12 +1155,6 @@ unsigned long usb_stor_write(int device, unsigned long blknr, buf_addr = (unsigned long)buffer; start = blknr; blks = blkcnt; - if (usb_test_unit_ready(srb, ss)) { - printf("Device NOT ready\n Request Sense returned %02X %02X" - " %02X\n", srb->sense_buf[2], srb->sense_buf[12], - srb->sense_buf[13]); - return 0; - } USB_STOR_PRINTF("\nusb_write: dev %d startblk %lx, blccnt %lx" " buffer %lx\n", device, start, blks, buf_addr); -- cgit v1.1 From f1273f11433ef4803d5eb88f1ec26986c99094c7 Mon Sep 17 00:00:00 2001 From: Troy Kisky Date: Sat, 11 Aug 2012 14:49:09 -0700 Subject: USB: Fix strict aliasing in ohci-hcd commit 5f6aa03fda2a0a79940765865c1e4266be8a75f8 USB: Fix complaints about strict aliasing in OHCI-HCD tried to fix this, but gcc4.4 still complains. So, this patch basically reverts the above and does a simpler fix. also, the above commit incorrectly changed /* corresponds to data_buf[4-7] */ datab [1] = 0; to /* corresponds to databuf.u8[4-7] */ databuf.u8[1] = 0; This patch also fixes that. Signed-off-by: Troy Kisky --- drivers/usb/host/ohci-hcd.c | 70 ++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index d24f2f1..9f47351 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1261,19 +1261,11 @@ static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, int leni = transfer_len; int len = 0; int stat = 0; - __u32 datab[4]; - union { - void *ptr; - __u8 *u8; - __u16 *u16; - __u32 *u32; - } databuf; __u16 bmRType_bReq; __u16 wValue; __u16 wIndex; __u16 wLength; - - databuf.u32 = (__u32 *)datab; + ALLOC_ALIGN_BUFFER(__u8, databuf, 16, sizeof(u32)); #ifdef DEBUG pkt_print(NULL, dev, pipe, buffer, transfer_len, @@ -1304,20 +1296,20 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, */ case RH_GET_STATUS: - databuf.u16[0] = cpu_to_le16(1); + *(u16 *)databuf = cpu_to_le16(1); OK(2); case RH_GET_STATUS | RH_INTERFACE: - databuf.u16[0] = cpu_to_le16(0); + *(u16 *)databuf = cpu_to_le16(0); OK(2); case RH_GET_STATUS | RH_ENDPOINT: - databuf.u16[0] = cpu_to_le16(0); + *(u16 *)databuf = cpu_to_le16(0); OK(2); case RH_GET_STATUS | RH_CLASS: - databuf.u32[0] = cpu_to_le32( + *(u32 *)databuf = cpu_to_le32( RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); OK(4); case RH_GET_STATUS | RH_OTHER | RH_CLASS: - databuf.u32[0] = cpu_to_le32(RD_RH_PORTSTAT); + *(u32 *)databuf = cpu_to_le32(RD_RH_PORTSTAT); OK(4); case RH_CLEAR_FEATURE | RH_ENDPOINT: @@ -1381,14 +1373,14 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, min_t(unsigned int, sizeof(root_hub_dev_des), wLength)); - databuf.ptr = root_hub_dev_des; OK(len); + databuf = root_hub_dev_des; OK(len); case (0x02): /* configuration descriptor */ len = min_t(unsigned int, leni, min_t(unsigned int, sizeof(root_hub_config_des), wLength)); - databuf.ptr = root_hub_config_des; OK(len); + databuf = root_hub_config_des; OK(len); case (0x03): /* string descriptors */ if (wValue == 0x0300) { len = min_t(unsigned int, @@ -1396,7 +1388,7 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, min_t(unsigned int, sizeof(root_hub_str_index0), wLength)); - databuf.ptr = root_hub_str_index0; + databuf = root_hub_str_index0; OK(len); } if (wValue == 0x0301) { @@ -1405,7 +1397,7 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, min_t(unsigned int, sizeof(root_hub_str_index1), wLength)); - databuf.ptr = root_hub_str_index1; + databuf = root_hub_str_index1; OK(len); } default: @@ -1417,40 +1409,40 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, { __u32 temp = roothub_a(&gohci); - databuf.u8[0] = 9; /* min length; */ - databuf.u8[1] = 0x29; - databuf.u8[2] = temp & RH_A_NDP; + databuf[0] = 9; /* min length; */ + databuf[1] = 0x29; + databuf[2] = temp & RH_A_NDP; #ifdef CONFIG_AT91C_PQFP_UHPBUG - databuf.u8[2] = (databuf.u8[2] == 2) ? 1 : 0; + databuf[2] = (databuf[2] == 2) ? 1 : 0; #endif - databuf.u8[3] = 0; + databuf[3] = 0; if (temp & RH_A_PSM) /* per-port power switching? */ - databuf.u8[3] |= 0x1; + databuf[3] |= 0x1; if (temp & RH_A_NOCP) /* no overcurrent reporting? */ - databuf.u8[3] |= 0x10; + databuf[3] |= 0x10; else if (temp & RH_A_OCPM)/* per-port overcurrent reporting? */ - databuf.u8[3] |= 0x8; + databuf[3] |= 0x8; - /* corresponds to databuf.u8[4-7] */ - databuf.u8[1] = 0; - databuf.u8[5] = (temp & RH_A_POTPGT) >> 24; + databuf[4] = 0; + databuf[5] = (temp & RH_A_POTPGT) >> 24; + databuf[6] = 0; temp = roothub_b(&gohci); - databuf.u8[7] = temp & RH_B_DR; - if (databuf.u8[2] < 7) { - databuf.u8[8] = 0xff; + databuf[7] = temp & RH_B_DR; + if (databuf[2] < 7) { + databuf[8] = 0xff; } else { - databuf.u8[0] += 2; - databuf.u8[8] = (temp & RH_B_DR) >> 8; - databuf.u8[10] = databuf.u8[9] = 0xff; + databuf[0] += 2; + databuf[8] = (temp & RH_B_DR) >> 8; + databuf[10] = databuf[9] = 0xff; } len = min_t(unsigned int, leni, - min_t(unsigned int, databuf.u8[0], wLength)); + min_t(unsigned int, databuf[0], wLength)); OK(len); } case RH_GET_CONFIGURATION: - databuf.u8[0] = 0x01; + databuf[0] = 0x01; OK(1); case RH_SET_CONFIGURATION: @@ -1469,8 +1461,8 @@ pkt_print(NULL, dev, pipe, buffer, transfer_len, #endif len = min_t(int, len, leni); - if (data != databuf.ptr) - memcpy(data, databuf.ptr, len); + if (data != databuf) + memcpy(data, databuf, len); dev->act_len = len; dev->status = stat; -- cgit v1.1 From a6a78be02542dbdcd530c62281dd6bfe79074a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Da=C5=82ek?= Date: Sun, 19 Aug 2012 00:21:02 +0200 Subject: pxa25x: Add UDC registers definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Łukasz Dałek --- arch/arm/include/asm/arch-pxa/regs-usb.h | 159 +++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 arch/arm/include/asm/arch-pxa/regs-usb.h diff --git a/arch/arm/include/asm/arch-pxa/regs-usb.h b/arch/arm/include/asm/arch-pxa/regs-usb.h new file mode 100644 index 0000000..dda7954 --- /dev/null +++ b/arch/arm/include/asm/arch-pxa/regs-usb.h @@ -0,0 +1,159 @@ +/* + * PXA25x UDC definitions + * + * Copyright (C) 2012 Łukasz Dałek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __REGS_USB_H__ +#define __REGS_USB_H__ + +struct pxa25x_udc_regs { + /* UDC Control Register */ + uint32_t udccr; /* 0x000 */ + uint32_t reserved1; + + /* UDC Control Function Register */ + uint32_t udccfr; /* 0x008 */ + uint32_t reserved2; + + /* UDC Endpoint Control/Status Registers */ + uint32_t udccs[16]; /* 0x010 - 0x04c */ + + /* UDC Interrupt Control/Status Registers */ + uint32_t uicr0; /* 0x050 */ + uint32_t uicr1; /* 0x054 */ + uint32_t usir0; /* 0x058 */ + uint32_t usir1; /* 0x05c */ + + /* UDC Frame Number/Byte Count Registers */ + uint32_t ufnrh; /* 0x060 */ + uint32_t ufnrl; /* 0x064 */ + uint32_t ubcr2; /* 0x068 */ + uint32_t ubcr4; /* 0x06c */ + uint32_t ubcr7; /* 0x070 */ + uint32_t ubcr9; /* 0x074 */ + uint32_t ubcr12; /* 0x078 */ + uint32_t ubcr14; /* 0x07c */ + + /* UDC Endpoint Data Registers */ + uint32_t uddr0; /* 0x080 */ + uint32_t reserved3[7]; + uint32_t uddr5; /* 0x0a0 */ + uint32_t reserved4[7]; + uint32_t uddr10; /* 0x0c0 */ + uint32_t reserved5[7]; + uint32_t uddr15; /* 0x0e0 */ + uint32_t reserved6[7]; + uint32_t uddr1; /* 0x100 */ + uint32_t reserved7[31]; + uint32_t uddr2; /* 0x180 */ + uint32_t reserved8[31]; + uint32_t uddr3; /* 0x200 */ + uint32_t reserved9[127]; + uint32_t uddr4; /* 0x400 */ + uint32_t reserved10[127]; + uint32_t uddr6; /* 0x600 */ + uint32_t reserved11[31]; + uint32_t uddr7; /* 0x680 */ + uint32_t reserved12[31]; + uint32_t uddr8; /* 0x700 */ + uint32_t reserved13[127]; + uint32_t uddr9; /* 0x900 */ + uint32_t reserved14[127]; + uint32_t uddr11; /* 0xb00 */ + uint32_t reserved15[31]; + uint32_t uddr12; /* 0xb80 */ + uint32_t reserved16[31]; + uint32_t uddr13; /* 0xc00 */ + uint32_t reserved17[127]; + uint32_t uddr14; /* 0xe00 */ + +}; + +#define PXA25X_UDC_BASE 0x40600000 + +#define UDCCR_UDE (1 << 0) +#define UDCCR_UDA (1 << 1) +#define UDCCR_RSM (1 << 2) +#define UDCCR_RESIR (1 << 3) +#define UDCCR_SUSIR (1 << 4) +#define UDCCR_SRM (1 << 5) +#define UDCCR_RSTIR (1 << 6) +#define UDCCR_REM (1 << 7) + +/* Bulk IN endpoint 1/6/11 */ +#define UDCCS_BI_TSP (1 << 7) +#define UDCCS_BI_FST (1 << 5) +#define UDCCS_BI_SST (1 << 4) +#define UDCCS_BI_TUR (1 << 3) +#define UDCCS_BI_FTF (1 << 2) +#define UDCCS_BI_TPC (1 << 1) +#define UDCCS_BI_TFS (1 << 0) + +/* Bulk OUT endpoint 2/7/12 */ +#define UDCCS_BO_RSP (1 << 7) +#define UDCCS_BO_RNE (1 << 6) +#define UDCCS_BO_FST (1 << 5) +#define UDCCS_BO_SST (1 << 4) +#define UDCCS_BO_DME (1 << 3) +#define UDCCS_BO_RPC (1 << 1) +#define UDCCS_BO_RFS (1 << 0) + +/* Isochronous OUT endpoint 4/9/14 */ +#define UDCCS_IO_RSP (1 << 7) +#define UDCCS_IO_RNE (1 << 6) +#define UDCCS_IO_DME (1 << 3) +#define UDCCS_IO_ROF (1 << 2) +#define UDCCS_IO_RPC (1 << 1) +#define UDCCS_IO_RFS (1 << 0) + +/* Control endpoint 0 */ +#define UDCCS0_OPR (1 << 0) +#define UDCCS0_IPR (1 << 1) +#define UDCCS0_FTF (1 << 2) +#define UDCCS0_DRWF (1 << 3) +#define UDCCS0_SST (1 << 4) +#define UDCCS0_FST (1 << 5) +#define UDCCS0_RNE (1 << 6) +#define UDCCS0_SA (1 << 7) + +#define UICR0_IM0 (1 << 0) + +#define USIR0_IR0 (1 << 0) +#define USIR0_IR1 (1 << 1) +#define USIR0_IR2 (1 << 2) +#define USIR0_IR3 (1 << 3) +#define USIR0_IR4 (1 << 4) +#define USIR0_IR5 (1 << 5) +#define USIR0_IR6 (1 << 6) +#define USIR0_IR7 (1 << 7) + +#define UDCCFR_AREN (1 << 7) /* ACK response enable (now) */ +#define UDCCFR_ACM (1 << 2) /* ACK control mode (wait for AREN) */ +/* + * Intel(R) PXA255 Processor Specification, September 2003 (page 31) + * define new "must be one" bits in UDCCFR (see Table 12-13.) + */ +#define UDCCFR_MB1 (0xff & ~(UDCCFR_AREN | UDCCFR_ACM)) + +#define UFNRH_SIR (1 << 7) /* SOF interrupt request */ +#define UFNRH_SIM (1 << 6) /* SOF interrupt mask */ +#define UFNRH_IPE14 (1 << 5) /* ISO packet error, ep14 */ +#define UFNRH_IPE9 (1 << 4) /* ISO packet error, ep9 */ +#define UFNRH_IPE4 (1 << 3) /* ISO packet error, ep4 */ + +#endif /* __REGS_USB_H__ */ -- cgit v1.1 From 749f8180c2b516abefdda3f5833d39f49b60f84d Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sun, 19 Aug 2012 18:22:07 +0200 Subject: usb: fix ulpi_set_vbus prototype Match the name of the header prototype with the actual implementation. Signed-off-by: Lucas Stach --- include/usb/ulpi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/usb/ulpi.h b/include/usb/ulpi.h index 4a23fd2..9a75c24 100644 --- a/include/usb/ulpi.h +++ b/include/usb/ulpi.h @@ -61,7 +61,7 @@ int ulpi_select_transceiver(struct ulpi_viewport *ulpi_vp, unsigned speed); * * returns 0 on success, ULPI_ERROR on failure. */ -int ulpi_enable_vbus(struct ulpi_viewport *ulpi_vp, +int ulpi_set_vbus(struct ulpi_viewport *ulpi_vp, int on, int ext_power, int ext_ind); /* -- cgit v1.1 From 8c8650181904cee37721fa303622cd37255d51d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Fran=C4=8De=C5=A1kin?= Date: Thu, 30 Aug 2012 09:24:39 +0200 Subject: MUSB driver: Timeout is never detected as the while loop does not end Timeout variable is decremented once more when while condition is not met. Following "if" does not detect correctly that timeout has occurred. Because of this bug the "usb start" command on AM335X-EVM board did not detect correctly that USB device was not attached. timeout = musb_cfg.timeout; while (timeout--) if (readb(&musbr->devctl) & MUSB_DEVCTL_HM) break; /* if musb core is not in host mode, then return */ if (!timeout) return -1; Signed-off-by: Matej Franceskin CC: Marek Vasut ? --- drivers/usb/musb/musb_hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c index 2df52c1..8d44c46 100644 --- a/drivers/usb/musb/musb_hcd.c +++ b/drivers/usb/musb/musb_hcd.c @@ -1113,7 +1113,7 @@ int usb_lowlevel_init(void) * should be a usb device connected. */ timeout = musb_cfg.timeout; - while (timeout--) + while (--timeout) if (readb(&musbr->devctl) & MUSB_DEVCTL_HM) break; -- cgit v1.1 From ef55e84a89967fc8a56b095dfb100010eca94719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 09:55:43 +0000 Subject: avr32: Remove redundant LDSCRIPT definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AVR32's LD script uses a standard location that is now automatically detected by the main Makefile, so its definition in AVR32's config.mk is now obsolete and redundant. Signed-off-by: Benoît Thébaudeau Cc: Andreas Bießmann Signed-off-by: Andreas Bießmann --- arch/avr32/config.mk | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/avr32/config.mk b/arch/avr32/config.mk index d8e7ebb..a751a3d 100644 --- a/arch/avr32/config.mk +++ b/arch/avr32/config.mk @@ -29,5 +29,3 @@ PLATFORM_RELFLAGS += -ffixed-r5 -fPIC -mno-init-got -mrelax PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections LDFLAGS_u-boot = --gc-sections --relax - -LDSCRIPT = $(SRCTREE)/$(CPUDIR)/u-boot.lds -- cgit v1.1 From af778c6d9e2b945ee03cbc53bb976238a3374f33 Mon Sep 17 00:00:00 2001 From: Andrew Sharp Date: Wed, 1 Aug 2012 12:27:16 +0000 Subject: pci: fix errant data types and corresponding access functions In a couple of places, unsigned int and pci_config_*_dword were being used when u16 and _word should be used. Unsigned int was also being used in a couple of places that should be pci_addr_t. Signed-off-by: Andrew Sharp --- drivers/pci/pci.c | 7 ++++--- drivers/pci/pci_auto.c | 15 ++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 398542b..cd78312 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -118,11 +118,11 @@ PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff) void *pci_map_bar(pci_dev_t pdev, int bar, int flags) { pci_addr_t pci_bus_addr; - u32 bar_response; + pci_addr_t bar_response; /* read BAR address */ pci_read_config_dword(pdev, bar, &bar_response); - pci_bus_addr = (pci_addr_t)(bar_response & ~0xf); + pci_bus_addr = bar_response & ~0xf; /* * Pass "0" as the length argument to pci_bus_to_virt. The arg @@ -385,7 +385,8 @@ int pci_hose_config_device(struct pci_controller *hose, pci_addr_t mem, unsigned long command) { - unsigned int bar_response, old_command; + pci_addr_t bar_response; + unsigned int old_command; pci_addr_t bar_value; pci_size_t bar_size; unsigned char pin; diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 87ee2c2..2338706 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -88,15 +88,15 @@ void pciauto_setup_device(struct pci_controller *hose, struct pci_region *prefetch, struct pci_region *io) { - unsigned int bar_response; + pci_addr_t bar_response; pci_addr_t bar_value; pci_size_t bar_size; - unsigned int cmdstat = 0; + u16 cmdstat = 0; struct pci_region *bar_res; int bar, bar_nr = 0; int found_mem64 = 0; - pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat); + pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER; for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_0 + (bars_num*4); bar += 4) { @@ -167,7 +167,7 @@ void pciauto_setup_device(struct pci_controller *hose, bar_nr++; } - pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat); + pci_hose_write_config_word(hose, dev, PCI_COMMAND, cmdstat); pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, CONFIG_SYS_PCI_CACHE_LINE_SIZE); pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); @@ -179,9 +179,9 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose, struct pci_region *pci_mem = hose->pci_mem; struct pci_region *pci_prefetch = hose->pci_prefetch; struct pci_region *pci_io = hose->pci_io; - unsigned int cmdstat; + u16 cmdstat; - pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &cmdstat); + pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); /* Configure bus number registers */ pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, @@ -229,7 +229,8 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose, } /* Enable memory and I/O accesses, enable bus master */ - pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER); + pci_hose_write_config_word(hose, dev, PCI_COMMAND, + cmdstat | PCI_COMMAND_MASTER); } void pciauto_postscan_setup_bridge(struct pci_controller *hose, -- cgit v1.1 From cb2bf931dcca9ed0ee514680ed99d51b45036aa9 Mon Sep 17 00:00:00 2001 From: Andrew Sharp Date: Wed, 29 Aug 2012 14:16:29 +0000 Subject: pci: clean up some whitespace and formatting I tried to clean up the white space and formatting offenses and inconsistencies in the generic PCI code that obviously has been around for some time. Emphasis on large increases in readability and maintainability and consistency. I omitted the platform/processor specific files in the drivers/pci directory because I wanted to leave those file to those that care more about them. Signed-off-by: Andrew Sharp --- drivers/pci/pci.c | 107 ++++++++++++++++++++++++++----------------------- drivers/pci/pci_auto.c | 54 ++++++++++++++++--------- 2 files changed, 91 insertions(+), 70 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cd78312..62cb969 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -151,13 +151,14 @@ void pci_register_hose(struct pci_controller* hose) *phose = hose; } -struct pci_controller *pci_bus_to_hose (int bus) +struct pci_controller *pci_bus_to_hose(int bus) { struct pci_controller *hose; - for (hose = hose_head; hose; hose = hose->next) + for (hose = hose_head; hose; hose = hose->next) { if (bus >= hose->first_busno && bus <= hose->last_busno) return hose; + } printf("pci_bus_to_hose() failed\n"); return NULL; @@ -196,21 +197,20 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) pci_dev_t bdf; int i, bus, found_multi = 0; - for (hose = hose_head; hose; hose = hose->next) - { + for (hose = hose_head; hose; hose = hose->next) { #ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE for (bus = hose->last_busno; bus >= hose->first_busno; bus--) #else for (bus = hose->first_busno; bus <= hose->last_busno; bus++) #endif - for (bdf = PCI_BDF(bus,0,0); + for (bdf = PCI_BDF(bus, 0, 0); #if defined(CONFIG_ELPPC) || defined(CONFIG_PPMC7XX) - bdf < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1); + bdf < PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1, + PCI_MAX_PCI_FUNCTIONS - 1); #else - bdf < PCI_BDF(bus+1,0,0); + bdf < PCI_BDF(bus + 1, 0, 0); #endif - bdf += PCI_BDF(0,0,1)) - { + bdf += PCI_BDF(0, 0, 1)) { if (!PCI_FUNC(bdf)) { pci_read_config_byte(bdf, PCI_HEADER_TYPE, @@ -229,19 +229,19 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) PCI_DEVICE_ID, &device); - for (i=0; ids[i].vendor != 0; i++) + for (i = 0; ids[i].vendor != 0; i++) { if (vendor == ids[i].vendor && - device == ids[i].device) - { + device == ids[i].device) { if (index <= 0) return bdf; index--; } + } } } - return (-1); + return -1; } pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index) @@ -258,7 +258,7 @@ pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index) * */ -int __pci_hose_phys_to_bus (struct pci_controller *hose, +int __pci_hose_phys_to_bus(struct pci_controller *hose, phys_addr_t phys_addr, unsigned long flags, unsigned long skip_mask, @@ -297,12 +297,14 @@ pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose, int ret; if (!hose) { - puts ("pci_hose_phys_to_bus: invalid hose\n"); + puts("pci_hose_phys_to_bus: invalid hose\n"); return bus_addr; } - /* if PCI_REGION_MEM is set we do a two pass search with preference - * on matches that don't have PCI_REGION_SYS_MEMORY set */ + /* + * if PCI_REGION_MEM is set we do a two pass search with preference + * on matches that don't have PCI_REGION_SYS_MEMORY set + */ if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, PCI_REGION_SYS_MEMORY, &bus_addr); @@ -313,12 +315,12 @@ pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose, ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr); if (ret) - puts ("pci_hose_phys_to_bus: invalid physical address\n"); + puts("pci_hose_phys_to_bus: invalid physical address\n"); return bus_addr; } -int __pci_hose_bus_to_phys (struct pci_controller *hose, +int __pci_hose_bus_to_phys(struct pci_controller *hose, pci_addr_t bus_addr, unsigned long flags, unsigned long skip_mask, @@ -354,12 +356,14 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose, int ret; if (!hose) { - puts ("pci_hose_bus_to_phys: invalid hose\n"); + puts("pci_hose_bus_to_phys: invalid hose\n"); return phys_addr; } - /* if PCI_REGION_MEM is set we do a two pass search with preference - * on matches that don't have PCI_REGION_SYS_MEMORY set */ + /* + * if PCI_REGION_MEM is set we do a two pass search with preference + * on matches that don't have PCI_REGION_SYS_MEMORY set + */ if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) { ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, PCI_REGION_SYS_MEMORY, &phys_addr); @@ -370,7 +374,7 @@ phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose, ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr); if (ret) - puts ("pci_hose_bus_to_phys: invalid physical address\n"); + puts("pci_hose_bus_to_phys: invalid physical address\n"); return phys_addr; } @@ -392,14 +396,14 @@ int pci_hose_config_device(struct pci_controller *hose, unsigned char pin; int bar, found_mem64; - debug ("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n", - io, (u64)mem, command); + debug("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n", io, + (u64)mem, command); - pci_hose_write_config_dword (hose, dev, PCI_COMMAND, 0); + pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 0); for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar += 4) { - pci_hose_write_config_dword (hose, dev, bar, 0xffffffff); - pci_hose_read_config_dword (hose, dev, bar, &bar_response); + pci_hose_write_config_dword(hose, dev, bar, 0xffffffff); + pci_hose_read_config_dword(hose, dev, bar, &bar_response); if (!bar_response) continue; @@ -419,8 +423,10 @@ int pci_hose_config_device(struct pci_controller *hose, PCI_BASE_ADDRESS_MEM_TYPE_64) { u32 bar_response_upper; u64 bar64; - pci_hose_write_config_dword(hose, dev, bar+4, 0xffffffff); - pci_hose_read_config_dword(hose, dev, bar+4, &bar_response_upper); + pci_hose_write_config_dword(hose, dev, bar + 4, + 0xffffffff); + pci_hose_read_config_dword(hose, dev, bar + 4, + &bar_response_upper); bar64 = ((u64)bar_response_upper << 32) | bar_response; @@ -443,27 +449,28 @@ int pci_hose_config_device(struct pci_controller *hose, if (found_mem64) { bar += 4; #ifdef CONFIG_SYS_PCI_64BIT - pci_hose_write_config_dword(hose, dev, bar, (u32)(bar_value>>32)); + pci_hose_write_config_dword(hose, dev, bar, + (u32)(bar_value >> 32)); #else - pci_hose_write_config_dword (hose, dev, bar, 0x00000000); + pci_hose_write_config_dword(hose, dev, bar, 0x00000000); #endif } } /* Configure Cache Line Size Register */ - pci_hose_write_config_byte (hose, dev, PCI_CACHE_LINE_SIZE, 0x08); + pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08); /* Configure Latency Timer */ - pci_hose_write_config_byte (hose, dev, PCI_LATENCY_TIMER, 0x80); + pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); /* Disable interrupt line, if device says it wants to use interrupts */ - pci_hose_read_config_byte (hose, dev, PCI_INTERRUPT_PIN, &pin); + pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin); if (pin != 0) { - pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE, 0xff); + pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 0xff); } - pci_hose_read_config_dword (hose, dev, PCI_COMMAND, &old_command); - pci_hose_write_config_dword (hose, dev, PCI_COMMAND, + pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &old_command); + pci_hose_write_config_dword(hose, dev, PCI_COMMAND, (old_command & 0xffff0000) | command); return 0; @@ -501,7 +508,8 @@ void pci_cfgfunc_config_device(struct pci_controller *hose, pci_dev_t dev, struct pci_config_table *entry) { - pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1], entry->priv[2]); + pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1], + entry->priv[2]); } void pci_cfgfunc_do_nothing(struct pci_controller *hose, @@ -510,10 +518,7 @@ void pci_cfgfunc_do_nothing(struct pci_controller *hose, } /* - * - */ - -/* HJF: Changed this to return int. I think this is required + * HJF: Changed this to return int. I think this is required * to get the correct result when scanning bridges */ extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev); @@ -619,7 +624,7 @@ int pci_print_dev(struct pci_controller *hose, pci_dev_t dev) int pci_hose_scan_bus(struct pci_controller *hose, int bus) { - unsigned int sub_bus, found_multi=0; + unsigned int sub_bus, found_multi = 0; unsigned short vendor, device, class; unsigned char header_type; struct pci_config_table *cfg; @@ -631,8 +636,9 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus) sub_bus = bus; for (dev = PCI_BDF(bus,0,0); - dev < PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1); - dev += PCI_BDF(0,0,1)) { + dev < PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1, + PCI_MAX_PCI_FUNCTIONS - 1); + dev += PCI_BDF(0, 0, 1)) { if (pci_skip_dev(hose, dev)) continue; @@ -650,8 +656,8 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus) if (!PCI_FUNC(dev)) found_multi = header_type & 0x80; - debug ("PCI Scan: Found Bus %d, Device %d, Function %d\n", - PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev) ); + debug("PCI Scan: Found Bus %d, Device %d, Function %d\n", + PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev)); pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device); pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class); @@ -712,10 +718,11 @@ int pci_hose_scan(struct pci_controller *hose) } #endif /* CONFIG_PCI_BOOTDELAY */ - /* Start scan at current_busno. + /* + * Start scan at current_busno. * PCIe will start scan at first_busno+1. */ - /* For legacy support, ensure current>=first */ + /* For legacy support, ensure current >= first */ if (hose->first_busno > hose->current_busno) hose->current_busno = hose->first_busno; #ifdef CONFIG_PCI_PNP diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 2338706..9a42ede 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -35,7 +35,7 @@ * */ -void pciauto_region_init(struct pci_region* res) +void pciauto_region_init(struct pci_region *res) { /* * Avoid allocating PCI resources from address 0 -- this is illegal @@ -50,7 +50,8 @@ void pciauto_region_align(struct pci_region *res, pci_size_t size) res->bus_lower = ((res->bus_lower - 1) | (size - 1)) + 1; } -int pciauto_region_allocate(struct pci_region* res, pci_size_t size, pci_addr_t *bar) +int pciauto_region_allocate(struct pci_region *res, pci_size_t size, + pci_addr_t *bar) { pci_addr_t addr; @@ -99,7 +100,8 @@ void pciauto_setup_device(struct pci_controller *hose, pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER; - for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_0 + (bars_num*4); bar += 4) { + for (bar = PCI_BASE_ADDRESS_0; + bar < PCI_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) { /* Tickle the BAR and get the response */ pci_hose_write_config_dword(hose, dev, bar, 0xffffffff); pci_hose_read_config_dword(hose, dev, bar, &bar_response); @@ -118,12 +120,14 @@ void pciauto_setup_device(struct pci_controller *hose, DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ", bar_nr, (u64)bar_size); } else { - if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) { u32 bar_response_upper; u64 bar64; - pci_hose_write_config_dword(hose, dev, bar+4, 0xffffffff); - pci_hose_read_config_dword(hose, dev, bar+4, &bar_response_upper); + pci_hose_write_config_dword(hose, dev, bar + 4, + 0xffffffff); + pci_hose_read_config_dword(hose, dev, bar + 4, + &bar_response_upper); bar64 = ((u64)bar_response_upper << 32) | bar_response; @@ -249,7 +253,7 @@ void pciauto_postscan_setup_bridge(struct pci_controller *hose, pciauto_region_align(pci_mem, 0x100000); pci_hose_write_config_word(hose, dev, PCI_MEMORY_LIMIT, - (pci_mem->bus_lower-1) >> 16); + (pci_mem->bus_lower - 1) >> 16); } if (pci_prefetch) { @@ -257,7 +261,7 @@ void pciauto_postscan_setup_bridge(struct pci_controller *hose, pciauto_region_align(pci_prefetch, 0x100000); pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, - (pci_prefetch->bus_lower-1) >> 16); + (pci_prefetch->bus_lower - 1) >> 16); } if (pci_io) { @@ -265,9 +269,9 @@ void pciauto_postscan_setup_bridge(struct pci_controller *hose, pciauto_region_align(pci_io, 0x1000); pci_hose_write_config_byte(hose, dev, PCI_IO_LIMIT, - ((pci_io->bus_lower-1) & 0x0000f000) >> 8); + ((pci_io->bus_lower - 1) & 0x0000f000) >> 8); pci_hose_write_config_word(hose, dev, PCI_IO_LIMIT_UPPER16, - ((pci_io->bus_lower-1) & 0xffff0000) >> 16); + ((pci_io->bus_lower - 1) & 0xffff0000) >> 16); } } @@ -281,7 +285,7 @@ void pciauto_config_init(struct pci_controller *hose) hose->pci_io = hose->pci_mem = NULL; - for (i=0; iregion_count; i++) { + for (i = 0; i < hose->region_count; i++) { switch(hose->regions[i].flags) { case PCI_REGION_IO: if (!hose->pci_io || @@ -339,7 +343,8 @@ void pciauto_config_init(struct pci_controller *hose) } } -/* HJF: Changed this to return int. I think this is required +/* + * HJF: Changed this to return int. I think this is required * to get the correct result when scanning bridges */ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) @@ -351,7 +356,7 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class); - switch(class) { + switch (class) { case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ DEBUGF("PCI AutoConfig: Found PowerPC device\n"); pciauto_setup_device(hose, dev, 6, hose->pci_mem, @@ -360,7 +365,8 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) case PCI_CLASS_BRIDGE_PCI: hose->current_busno++; - pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_prefetch, hose->pci_io); + pciauto_setup_device(hose, dev, 2, hose->pci_mem, + hose->pci_prefetch, hose->pci_io); DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev)); @@ -386,14 +392,20 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) return sub_bus; } - pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io); + pciauto_setup_device(hose, dev, 6, hose->pci_mem, + hose->pci_prefetch, hose->pci_io); break; case PCI_CLASS_BRIDGE_CARDBUS: - /* just do a minimal setup of the bridge, let the OS take care of the rest */ - pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io); + /* + * just do a minimal setup of the bridge, + * let the OS take care of the rest + */ + pciauto_setup_device(hose, dev, 0, hose->pci_mem, + hose->pci_prefetch, hose->pci_io); - DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", PCI_DEV(dev)); + DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", + PCI_DEV(dev)); hose->current_busno++; break; @@ -413,11 +425,13 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) * the PIMMR window to be allocated (BAR0 - 1MB size) */ DEBUGF("PCI Autoconfig: Broken bridge found, only minimal config\n"); - pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io); + pciauto_setup_device(hose, dev, 0, hose->pci_mem, + hose->pci_prefetch, hose->pci_io); break; #endif default: - pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io); + pciauto_setup_device(hose, dev, 6, hose->pci_mem, + hose->pci_prefetch, hose->pci_io); break; } -- cgit v1.1 From 03992ac2c974ae3e169219ba0ccdd94a8ce0146a Mon Sep 17 00:00:00 2001 From: Andrew Sharp Date: Wed, 29 Aug 2012 14:16:30 +0000 Subject: pci: minor cleanup of CONFIG_PCI_PNP usage Refactor the common PCI code just a tiny bit surrounding the PCI_PNP (pciauto) stuff. Makes the code a tiny bit easier to read, and also makes it more obvious that almost no platform needs to setup or use the pci_config_table stuff. Signed-off-by: Andrew Sharp --- drivers/pci/pci.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 62cb969..2a6d0a7 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -627,7 +627,9 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus) unsigned int sub_bus, found_multi = 0; unsigned short vendor, device, class; unsigned char header_type; +#ifndef CONFIG_PCI_PNP struct pci_config_table *cfg; +#endif pci_dev_t dev; #ifdef CONFIG_PCI_SCAN_SHOW static int indent = 0; @@ -675,18 +677,16 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus) } #endif +#ifdef CONFIG_PCI_PNP + sub_bus = max(pciauto_config_device(hose, dev), sub_bus); +#else cfg = pci_find_config(hose, class, vendor, device, PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev)); if (cfg) { cfg->config_device(hose, dev, cfg); sub_bus = max(sub_bus, hose->current_busno); -#ifdef CONFIG_PCI_PNP - } else { - int n = pciauto_config_device(hose, dev); - - sub_bus = max(sub_bus, n); -#endif } +#endif #ifdef CONFIG_PCI_SCAN_SHOW indent--; -- cgit v1.1 From 98c397a6ed3fe58f336f6717831faa99333d72a7 Mon Sep 17 00:00:00 2001 From: Andrew Sharp Date: Wed, 29 Aug 2012 14:16:31 +0000 Subject: pci: update pci_ids.h with a few new entries Add some recent entries to pci_ids.h for Intel and AMD/ATI devices that are somewhat relevant to u-boot. Signed-off-by: Andrew Sharp --- include/pci_ids.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/pci_ids.h b/include/pci_ids.h index 6a85c06..2c6dfd4 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -364,6 +364,10 @@ #define PCI_DEVICE_ID_ATI_RS400_166 0x5a32 #define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 #define PCI_DEVICE_ID_ATI_RS480 0x5950 +/* additional Radeon families */ +#define PCI_DEVICE_ID_ATI_EVERGREEN 0x9802 +#define PCI_DEVICE_ID_ATI_EVERGREEN2 0x9804 +#define PCI_DEVICE_ID_ATI_WRESTLER 0x9806 /* ATI IXP Chipset */ #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 #define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353 @@ -375,9 +379,13 @@ #define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379 #define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a #define PCI_DEVICE_ID_ATI_IXP600_SATA 0x4380 +#define PCI_DEVICE_ID_ATI_SBX00_PCI_BRIDGE 0x4384 #define PCI_DEVICE_ID_ATI_SBX00_SMBUS 0x4385 #define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c #define PCI_DEVICE_ID_ATI_IXP700_SATA 0x4390 +#define PCI_DEVICE_ID_ATI_SBX00_SATA_AHCI 0x4391 +#define PCI_DEVICE_ID_ATI_SBX00_EHCI 0x4396 +#define PCI_DEVICE_ID_ATI_SBX00_OHCI 0x4397 #define PCI_DEVICE_ID_ATI_IXP700_IDE 0x439c #define PCI_VENDOR_ID_VLSI 0x1004 @@ -2539,9 +2547,16 @@ #define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21 #define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30 #define PCI_DEVICE_ID_INTEL_IOAT 0x1a38 +#define PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_MOBILE 0x1c03 +#define PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_SERIES6 0x1c02 +#define PCI_DEVICE_ID_INTEL_COUGARPOINT_HDA 0x1c20 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE 0x1e03 +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_HDA 0x1e20 +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN 0x1e41 +#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX 0x1e5f #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 #define PCI_DEVICE_ID_INTEL_PATSBURG_LPC 0x1d40 #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 @@ -2635,6 +2650,7 @@ #define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0 #define PCI_DEVICE_ID_INTEL_TGP_LPC 0x27bc #define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd +#define PCI_DEVICE_ID_INTEL_NM10_AHCI 0x27c1 #define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da #define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd #define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de -- cgit v1.1 From 69fd2d3b0559f221a45e9a86b8ead16490f4e47b Mon Sep 17 00:00:00 2001 From: Andrew Sharp Date: Wed, 29 Aug 2012 14:16:32 +0000 Subject: pci: add CONFIG_PCI_ENUM_ONLY for platforms that don't need PCI setup done Introduce CONFIG_PCI_ENUM_ONLY variable for platforms that just want a quick enumberation of the PCI devices, but don't need any setup work done. This is very beneficial on platforms that have u-boot loaded by another boot loader which does a more sophisticated job of setup of PCI devices than u-boot. That way, u-boot can just read what's there and get on with life. This is what SeaBIOS does. Signed-off-by: Andrew Sharp --- README | 7 +++++++ drivers/pci/pci_auto.c | 35 +++++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/README b/README index da4341f..d45eba7 100644 --- a/README +++ b/README @@ -3377,6 +3377,13 @@ Low Level (hardware related) configuration options: Disable PCI-Express on systems where it is supported but not required. +- CONFIG_PCI_ENUM_ONLY + Only scan through and get the devices on the busses. + Don't do any setup work, presumably because someone or + something has already done it, and we don't need to do it + a second time. Useful for platforms that are pre-booted + by coreboot or similar. + - CONFIG_SYS_SRIO: Chip has SRIO or not diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 9a42ede..ae61e24 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -90,12 +90,14 @@ void pciauto_setup_device(struct pci_controller *hose, struct pci_region *io) { pci_addr_t bar_response; - pci_addr_t bar_value; pci_size_t bar_size; u16 cmdstat = 0; - struct pci_region *bar_res; int bar, bar_nr = 0; +#ifndef CONFIG_PCI_ENUM_ONLY + pci_addr_t bar_value; + struct pci_region *bar_res; int found_mem64 = 0; +#endif pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER; @@ -103,20 +105,26 @@ void pciauto_setup_device(struct pci_controller *hose, for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) { /* Tickle the BAR and get the response */ +#ifndef CONFIG_PCI_ENUM_ONLY pci_hose_write_config_dword(hose, dev, bar, 0xffffffff); +#endif pci_hose_read_config_dword(hose, dev, bar, &bar_response); /* If BAR is not implemented go to the next BAR */ if (!bar_response) continue; +#ifndef CONFIG_PCI_ENUM_ONLY found_mem64 = 0; +#endif /* Check the BAR type and set our address mask */ if (bar_response & PCI_BASE_ADDRESS_SPACE) { bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK)) & 0xffff) + 1; +#ifndef CONFIG_PCI_ENUM_ONLY bar_res = io; +#endif DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ", bar_nr, (u64)bar_size); } else { @@ -124,26 +132,34 @@ void pciauto_setup_device(struct pci_controller *hose, PCI_BASE_ADDRESS_MEM_TYPE_64) { u32 bar_response_upper; u64 bar64; + +#ifndef CONFIG_PCI_ENUM_ONLY pci_hose_write_config_dword(hose, dev, bar + 4, 0xffffffff); +#endif pci_hose_read_config_dword(hose, dev, bar + 4, &bar_response_upper); bar64 = ((u64)bar_response_upper << 32) | bar_response; bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1; +#ifndef CONFIG_PCI_ENUM_ONLY found_mem64 = 1; +#endif } else { bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1); } +#ifndef CONFIG_PCI_ENUM_ONLY if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH)) bar_res = prefetch; else bar_res = mem; +#endif DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%llx, ", bar_nr, (u64)bar_size); } +#ifndef CONFIG_PCI_ENUM_ONLY if (pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0) { /* Write it out and update our limit */ pci_hose_write_config_dword(hose, dev, bar, (u32)bar_value); @@ -162,9 +178,10 @@ void pciauto_setup_device(struct pci_controller *hose, #endif } - cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ? - PCI_COMMAND_IO : PCI_COMMAND_MEMORY; } +#endif + cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ? + PCI_COMMAND_IO : PCI_COMMAND_MEMORY; DEBUGF("\n"); @@ -357,12 +374,6 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class); switch (class) { - case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ - DEBUGF("PCI AutoConfig: Found PowerPC device\n"); - pciauto_setup_device(hose, dev, 6, hose->pci_mem, - hose->pci_prefetch, hose->pci_io); - break; - case PCI_CLASS_BRIDGE_PCI: hose->current_busno++; pciauto_setup_device(hose, dev, 2, hose->pci_mem, @@ -429,6 +440,10 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) hose->pci_prefetch, hose->pci_io); break; #endif + + case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ + DEBUGF("PCI AutoConfig: Found PowerPC device\n"); + default: pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io); -- cgit v1.1 From 05e5b73506f0a07660f0930f4ecec6e6f5b7cd03 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Mon, 6 Aug 2012 23:46:05 +0000 Subject: patman: fix end of changes detection Changes may end in '---' line or Signoff line (generated by git format-patch) in case of Series-changes: lines being the last ones in commit message. So detect it properly. Signed-off-by: Ilya Yanok --- tools/patman/patchstream.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index be40af3..036b129 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -36,6 +36,9 @@ re_remove = re.compile('^BUG=|^TEST=|^Change-Id:|^Review URL:' # Lines which are allowed after a TEST= line re_allowed_after_test = re.compile('^Signed-off-by:') +# Signoffs +re_signoff = re.compile('^Signed-off-by:') + # The start of the cover letter re_cover = re.compile('^Cover-letter:') @@ -207,6 +210,9 @@ class PatchStream: if is_blank: # Blank line ends this change list self.in_change = 0 + elif line == '---' or re_signoff.match(line): + self.in_change = 0 + out = self.ProcessLine(line) else: self.series.AddChange(self.in_change, self.commit, line) self.skip_blank = False -- cgit v1.1 From a8840cb2f040b8aa1c870b7431ce27e9ec81284e Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Mon, 6 Aug 2012 23:46:06 +0000 Subject: patman: don't pick changes while processing patches We already got all changes from git log output and the comment to the ProcessLine function clearly states that 'patch' mode is not for scanning tags. Signed-off-by: Ilya Yanok --- tools/patman/patchstream.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index 036b129..3de32d5 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -214,7 +214,8 @@ class PatchStream: self.in_change = 0 out = self.ProcessLine(line) else: - self.series.AddChange(self.in_change, self.commit, line) + if self.is_log: + self.series.AddChange(self.in_change, self.commit, line) self.skip_blank = False # Detect Series-xxx tags -- cgit v1.1 From 73fe07a79a65600acce3d96c0b0d6ad1ca3e8551 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Mon, 6 Aug 2012 23:46:07 +0000 Subject: patman: don't mess with changelog Don't try to sort and uniq changelog entries as this breaks multiline entries. It will be better to add some real multi-line support but for now just preserve the entries as is. Signed-off-by: Ilya Yanok --- tools/patman/series.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/patman/series.py b/tools/patman/series.py index 05d9e73..4e7cb71 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -154,10 +154,9 @@ class Series(dict): for this_commit, text in self.changes[change]: if commit and this_commit != commit: continue - if text not in out: - out.append(text) + out.append(text) if out: - out = ['Changes in v%d:' % change] + sorted(out) + out = ['Changes in v%d:' % change] + out if need_blank: out = [''] + out final += out -- cgit v1.1 From c7379149ffa2c8ba2807dd2e3ff0847f256a982e Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Mon, 6 Aug 2012 23:46:08 +0000 Subject: patman: don't mess with signoffs Currently patman assumes that there should be only one Signoff line and this is obviously incorrect: we often have to work with patches containing other people signoffs. Moreover, it's really desirable to preserve the comments between signoffs. So until some sophisticated signoff processing will be developed I suggest just don't mess with signoffs at all and treat them like plain text lines. The only drawback I've found so far is the case where you have a patch with someones else signoff but not yours and also have to patman tags under signoff line. In this case you will get extra empty line between signoffs. Signed-off-by: Ilya Yanok --- tools/patman/patchstream.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index 3de32d5..0503bac 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -46,7 +46,7 @@ re_cover = re.compile('^Cover-letter:') re_series = re.compile('^Series-(\w*): *(.*)') # Commit tags that we want to collect and keep -re_tag = re.compile('^(Tested-by|Acked-by|Signed-off-by|Cc): (.*)') +re_tag = re.compile('^(Tested-by|Acked-by|Cc): (.*)') # The start of a new commit in the git log re_commit = re.compile('^commit (.*)') @@ -241,15 +241,8 @@ class PatchStream: # Detect tags in the commit message elif tag_match: - # Onlly allow a single signoff tag - if tag_match.group(1) == 'Signed-off-by': - if self.signoff: - self.warn.append('Patch has more than one Signed-off-by ' - 'tag') - self.signoff += [line] - # Remove Tested-by self, since few will take much notice - elif (tag_match.group(1) == 'Tested-by' and + if (tag_match.group(1) == 'Tested-by' and tag_match.group(2).find(os.getenv('USER') + '@') != -1): self.warn.append("Ignoring %s" % line) elif tag_match.group(1) == 'Cc': @@ -288,8 +281,6 @@ class PatchStream: # Output the tags (signeoff first), then change list out = [] - if self.signoff: - out += self.signoff log = self.series.MakeChangeLog(self.commit) out += self.FormatTags(self.tags) out += [line] + log -- cgit v1.1 From d5f81d8acd14329095722879cf17a9b5295111dd Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Mon, 13 Aug 2012 10:08:22 +0000 Subject: patman: Allow for changelog use in first version of a series When a patchset had a RFC series, a v1 might have a changelog of changes done since the RFC. The patch changes the range checked for changelog and allow it to start for version 1. Signed-off-by: Otavio Salvador Acked-by: Simon Glass --- tools/patman/series.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/patman/series.py b/tools/patman/series.py index 4e7cb71..518834c 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -173,12 +173,13 @@ class Series(dict): col = terminal.Color() if self.get('version'): changes_copy = dict(self.changes) - for version in range(2, int(self.version) + 1): + for version in range(1, int(self.version) + 1): if self.changes.get(version): del changes_copy[version] else: - str = 'Change log missing for v%d' % version - print col.Color(col.RED, str) + if version > 1: + str = 'Change log missing for v%d' % version + print col.Color(col.RED, str) for version in changes_copy: str = 'Change log for unknown version v%d' % version print col.Color(col.RED, str) -- cgit v1.1 From 43de0244c133b6cb9041ae6e7e4ae79839f22c44 Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Sat, 18 Aug 2012 07:19:51 +0000 Subject: patman: Do not Cc addresses included in To list In case an address is listed in the To list, those will be skipped on Cc list or user might end with a duplicated message. This fixes the case when a tag points to same address used as series destination thus avoiding duplicated sending. Signed-off-by: Otavio Salvador --- tools/patman/series.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/patman/series.py b/tools/patman/series.py index 518834c..27528bf 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -114,6 +114,13 @@ class Series(dict): cc_list += gitutil.BuildEmailList(commit.tags) cc_list += gitutil.BuildEmailList(commit.cc_list) + # Skip items in To list + if 'to' in self: + try: + map(cc_list.remove, gitutil.BuildEmailList(self.to)) + except ValueError: + pass + for email in cc_list: if email == None: email = col.Color(col.YELLOW, "" -- cgit v1.1 From 74f45b739be635eaa4ec3a40dec6ad66084748c4 Mon Sep 17 00:00:00 2001 From: Charles Manning Date: Tue, 14 Aug 2012 18:26:10 +0000 Subject: u-boot yaffs2: Fix compilation warnings Also remove yaffs_hweight and use the hweight in u-boot. Signed-off-by: Charles Manning --- fs/yaffs2/Makefile | 2 +- fs/yaffs2/stdio.h | 1 - fs/yaffs2/stdlib.h | 1 - fs/yaffs2/string.h | 4 ---- fs/yaffs2/yaffs_hweight.c | 52 ----------------------------------------------- fs/yaffs2/yaffs_hweight.h | 24 ---------------------- fs/yaffs2/yaffs_mtdif2.c | 3 --- fs/yaffs2/yaffsfs.c | 2 -- fs/yaffs2/ydirectenv.h | 16 ++++----------- fs/yaffs2/yportenv.h | 1 + 10 files changed, 6 insertions(+), 100 deletions(-) delete mode 100644 fs/yaffs2/stdio.h delete mode 100644 fs/yaffs2/stdlib.h delete mode 100644 fs/yaffs2/string.h delete mode 100644 fs/yaffs2/yaffs_hweight.c delete mode 100644 fs/yaffs2/yaffs_hweight.h diff --git a/fs/yaffs2/Makefile b/fs/yaffs2/Makefile index 31c12af..9b29d22 100644 --- a/fs/yaffs2/Makefile +++ b/fs/yaffs2/Makefile @@ -23,7 +23,7 @@ LIB = $(obj)libyaffs2.o COBJS-$(CONFIG_YAFFS2) := \ yaffs_allocator.o yaffs_attribs.o yaffs_bitmap.o yaffs_uboot_glue.o\ yaffs_checkptrw.o yaffs_ecc.o yaffs_error.o \ - yaffsfs.o yaffs_guts.o yaffs_hweight.o yaffs_nameval.o yaffs_nand.o\ + yaffsfs.o yaffs_guts.o yaffs_nameval.o yaffs_nand.o\ yaffs_packedtags1.o yaffs_packedtags2.o yaffs_qsort.o \ yaffs_summary.o yaffs_tagscompat.o yaffs_verify.o yaffs_yaffs1.o \ yaffs_yaffs2.o yaffs_mtdif.o yaffs_mtdif2.o diff --git a/fs/yaffs2/stdio.h b/fs/yaffs2/stdio.h deleted file mode 100644 index 9f379d7..0000000 --- a/fs/yaffs2/stdio.h +++ /dev/null @@ -1 +0,0 @@ -/* Dummy header for u-boot */ diff --git a/fs/yaffs2/stdlib.h b/fs/yaffs2/stdlib.h deleted file mode 100644 index 9f379d7..0000000 --- a/fs/yaffs2/stdlib.h +++ /dev/null @@ -1 +0,0 @@ -/* Dummy header for u-boot */ diff --git a/fs/yaffs2/string.h b/fs/yaffs2/string.h deleted file mode 100644 index 6501fa7..0000000 --- a/fs/yaffs2/string.h +++ /dev/null @@ -1,4 +0,0 @@ -#include -#include -#include -#include diff --git a/fs/yaffs2/yaffs_hweight.c b/fs/yaffs2/yaffs_hweight.c deleted file mode 100644 index d96773e..0000000 --- a/fs/yaffs2/yaffs_hweight.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2011 Aleph One Ltd. - * for Toby Churchill Ltd and Brightstar Engineering - * - * Created by Charles Manning - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* These functions have been renamed to hweightxx to match the - * equivaqlent functions in the Linux kernel. - */ - -#include "yaffs_hweight.h" - -static const char yaffs_count_bits_table[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - -int yaffs_hweight8(u8 x) -{ - int ret_val; - ret_val = yaffs_count_bits_table[x]; - return ret_val; -} - -int yaffs_hweight32(u32 x) -{ - return yaffs_hweight8(x & 0xff) + - yaffs_hweight8((x >> 8) & 0xff) + - yaffs_hweight8((x >> 16) & 0xff) + - yaffs_hweight8((x >> 24) & 0xff); -} diff --git a/fs/yaffs2/yaffs_hweight.h b/fs/yaffs2/yaffs_hweight.h deleted file mode 100644 index 3f7c6c3..0000000 --- a/fs/yaffs2/yaffs_hweight.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * YAFFS: Yet another Flash File System . A NAND-flash specific file system. - * - * Copyright (C) 2002-2011 Aleph One Ltd. - * for Toby Churchill Ltd and Brightstar Engineering - * - * Created by Charles Manning - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 as - * published by the Free Software Foundation. - * - * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. - */ - -#ifndef __YAFFS_HWEIGHT_H__ -#define __YAFFS_HWEIGHT_H__ - -#include "yportenv.h" - -int yaffs_hweight8(u8 x); -int yaffs_hweight32(u32 x); - -#endif diff --git a/fs/yaffs2/yaffs_mtdif2.c b/fs/yaffs2/yaffs_mtdif2.c index b27fe56..8135bcc 100644 --- a/fs/yaffs2/yaffs_mtdif2.c +++ b/fs/yaffs2/yaffs_mtdif2.c @@ -28,7 +28,6 @@ #include "yaffs_trace.h" #include "yaffs_packedtags2.h" -#include "string.h" #define yaffs_dev_to_mtd(dev) ((struct mtd_info *)((dev)->driver_context)) #define yaffs_dev_to_lc(dev) ((struct yaffs_linux_context *)((dev)->os_context)) @@ -46,9 +45,7 @@ int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk, struct mtd_oob_ops ops; int retval = 0; - loff_t addr; - u8 local_spare[128]; struct yaffs_packed_tags2 pt; diff --git a/fs/yaffs2/yaffsfs.c b/fs/yaffs2/yaffsfs.c index 9f1397b..ac4a010 100644 --- a/fs/yaffs2/yaffsfs.c +++ b/fs/yaffs2/yaffsfs.c @@ -17,8 +17,6 @@ #include "yportenv.h" #include "yaffs_trace.h" -#include "string.h" - #define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5 #ifndef NULL diff --git a/fs/yaffs2/ydirectenv.h b/fs/yaffs2/ydirectenv.h index df0b8fb..c912b09 100644 --- a/fs/yaffs2/ydirectenv.h +++ b/fs/yaffs2/ydirectenv.h @@ -20,15 +20,14 @@ #ifndef __YDIRECTENV_H__ #define __YDIRECTENV_H__ -#include "stdlib.h" -#include "stdio.h" -#include "string.h" +#include +#include +#include + #include "yaffs_osglue.h" -#include "yaffs_hweight.h" void yaffs_bug_fn(const char *file_name, int line_no); -#define BUG() do { yaffs_bug_fn(__FILE__, __LINE__); } while (0) #define YCHAR char @@ -47,8 +46,6 @@ void yaffs_bug_fn(const char *file_name, int line_no); #define yaffs_strncmp(a, b, c) strncmp(a, b, c) #endif -#define hweight8(x) yaffs_hweight8(x) -#define hweight32(x) yaffs_hweight32(x) void yaffs_qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *)); @@ -63,11 +60,6 @@ void yaffs_qsort(void *aa, size_t n, size_t es, #define inline __inline__ #endif -#define kmalloc(x, flags) yaffsfs_malloc(x) -#define kfree(x) yaffsfs_free(x) -#define vmalloc(x) yaffsfs_malloc(x) -#define vfree(x) yaffsfs_free(x) - #define cond_resched() do {} while (0) #define yaffs_trace(msk, fmt, ...) do { \ diff --git a/fs/yaffs2/yportenv.h b/fs/yaffs2/yportenv.h index b47a4d6..251eba0 100644 --- a/fs/yaffs2/yportenv.h +++ b/fs/yaffs2/yportenv.h @@ -17,6 +17,7 @@ #ifndef __YPORTENV_H__ #define __YPORTENV_H__ +#include /* Definition of types */ #ifdef CONFIG_YAFFS_DEFINES_TYPES -- cgit v1.1 From 67cbbf25c5b161bfb76958cd6c4c38aa72161029 Mon Sep 17 00:00:00 2001 From: Kaspter Ju Date: Thu, 31 May 2012 04:27:50 +0000 Subject: mmc: Remove unused item flags in struct mmc_cmd Signed-off-by: Kaspter Ju --- drivers/mmc/mmc.c | 28 ---------------------------- include/mmc.h | 1 - 2 files changed, 29 deletions(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index c1c2862..fa673cf 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -151,7 +151,6 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) printf("CMD_SEND:%d\n", cmd->cmdidx); printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg); - printf("\t\tFLAG\t\t\t %d\n", cmd->flags); ret = mmc->send_cmd(mmc, cmd, data); switch (cmd->resp_type) { case MMC_RSP_NONE: @@ -213,7 +212,6 @@ int mmc_send_status(struct mmc *mmc, int timeout) cmd.resp_type = MMC_RSP_R1; if (!mmc_host_is_spi(mmc)) cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; do { err = mmc_send_cmd(mmc, &cmd, NULL); @@ -253,7 +251,6 @@ int mmc_set_blocklen(struct mmc *mmc, int len) cmd.cmdidx = MMC_CMD_SET_BLOCKLEN; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = len; - cmd.flags = 0; return mmc_send_cmd(mmc, &cmd, NULL); } @@ -299,7 +296,6 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) cmd.cmdidx = start_cmd; cmd.cmdarg = start; cmd.resp_type = MMC_RSP_R1; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -386,7 +382,6 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src) cmd.cmdarg = start * mmc->write_bl_len; cmd.resp_type = MMC_RSP_R1; - cmd.flags = 0; data.src = src; data.blocks = blkcnt; @@ -405,7 +400,6 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src) cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_R1b; - cmd.flags = 0; if (mmc_send_cmd(mmc, &cmd, NULL)) { printf("mmc fail to send stop cmd\n"); return 0; @@ -459,7 +453,6 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt) cmd.cmdarg = start * mmc->read_bl_len; cmd.resp_type = MMC_RSP_R1; - cmd.flags = 0; data.dest = dst; data.blocks = blkcnt; @@ -473,7 +466,6 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt) cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION; cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_R1b; - cmd.flags = 0; if (mmc_send_cmd(mmc, &cmd, NULL)) { printf("mmc fail to send stop cmd\n"); return 0; @@ -525,7 +517,6 @@ int mmc_go_idle(struct mmc* mmc) cmd.cmdidx = MMC_CMD_GO_IDLE_STATE; cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_NONE; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -548,7 +539,6 @@ sd_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_APP_CMD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -589,7 +579,6 @@ sd_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SPI_READ_OCR; cmd.resp_type = MMC_RSP_R3; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -618,7 +607,6 @@ int mmc_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SEND_OP_COND; cmd.resp_type = MMC_RSP_R3; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -638,8 +626,6 @@ int mmc_send_op_cond(struct mmc *mmc) if (mmc->host_caps & MMC_MODE_HC) cmd.cmdarg |= OCR_HCS; - cmd.flags = 0; - err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -655,7 +641,6 @@ int mmc_send_op_cond(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SPI_READ_OCR; cmd.resp_type = MMC_RSP_R3; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -683,7 +668,6 @@ int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd) cmd.cmdidx = MMC_CMD_SEND_EXT_CSD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 0; - cmd.flags = 0; data.dest = ext_csd; data.blocks = 1; @@ -707,7 +691,6 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | (index << 16) | (value << 8); - cmd.flags = 0; ret = mmc_send_cmd(mmc, &cmd, NULL); @@ -800,7 +783,6 @@ int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp) cmd.cmdarg = (mode << 31) | 0xffffff; cmd.cmdarg &= ~(0xf << (group * 4)); cmd.cmdarg |= value << (group * 4); - cmd.flags = 0; data.dest = (char *)resp; data.blocksize = 64; @@ -829,7 +811,6 @@ int sd_change_freq(struct mmc *mmc) cmd.cmdidx = MMC_CMD_APP_CMD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -839,7 +820,6 @@ int sd_change_freq(struct mmc *mmc) cmd.cmdidx = SD_CMD_APP_SEND_SCR; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 0; - cmd.flags = 0; timeout = 3; @@ -992,7 +972,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 1; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -1005,7 +984,6 @@ int mmc_startup(struct mmc *mmc) MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */ cmd.resp_type = MMC_RSP_R2; cmd.cmdarg = 0; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -1023,7 +1001,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR; cmd.cmdarg = mmc->rca << 16; cmd.resp_type = MMC_RSP_R6; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -1038,7 +1015,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SEND_CSD; cmd.resp_type = MMC_RSP_R2; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -1115,7 +1091,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_SELECT_CARD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -1182,7 +1157,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = MMC_CMD_APP_CMD; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = mmc->rca << 16; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) @@ -1191,7 +1165,6 @@ int mmc_startup(struct mmc *mmc) cmd.cmdidx = SD_CMD_APP_SET_BUS_WIDTH; cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 2; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); if (err) return err; @@ -1273,7 +1246,6 @@ int mmc_send_if_cond(struct mmc *mmc) /* We set the bit if the host supports voltages between 2.7 and 3.6 V */ cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa; cmd.resp_type = MMC_RSP_R7; - cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); diff --git a/include/mmc.h b/include/mmc.h index 7546b4a..7b094a4 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -214,7 +214,6 @@ struct mmc_cmd { uint resp_type; uint cmdarg; uint response[4]; - uint flags; }; struct mmc_data { -- cgit v1.1 From 64a08a9ffc0ff8c9e56b204842a5650c19b48db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 13 Jul 2012 21:31:03 +0200 Subject: part_mac: dcache: allocate cacheline-aligned buffers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch forces the correct alignment for DMA operations of buffers used by part_mac.c. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- disk/part_mac.c | 68 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/disk/part_mac.c b/disk/part_mac.c index c1afc8c..cb443ac 100644 --- a/disk/part_mac.c +++ b/disk/part_mac.c @@ -60,23 +60,23 @@ static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partitio */ int test_part_mac (block_dev_desc_t *dev_desc) { - mac_driver_desc_t ddesc; - mac_partition_t mpart; + ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); + ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); ulong i, n; - if (part_mac_read_ddb (dev_desc, &ddesc)) { + if (part_mac_read_ddb (dev_desc, ddesc)) { /* error reading Driver Desriptor Block, or no valid Signature */ return (-1); } n = 1; /* assuming at least one partition */ for (i=1; i<=n; ++i) { - if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)&mpart) != 1) || - (mpart.signature != MAC_PARTITION_MAGIC) ) { + if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)mpart) != 1) || + (mpart->signature != MAC_PARTITION_MAGIC) ) { return (-1); } /* update partition count */ - n = mpart.map_count; + n = mpart->map_count; } return (0); } @@ -85,20 +85,20 @@ int test_part_mac (block_dev_desc_t *dev_desc) void print_part_mac (block_dev_desc_t *dev_desc) { ulong i, n; - mac_driver_desc_t ddesc; - mac_partition_t mpart; + ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); + ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); ldiv_t mb, gb; - if (part_mac_read_ddb (dev_desc, &ddesc)) { + if (part_mac_read_ddb (dev_desc, ddesc)) { /* error reading Driver Desriptor Block, or no valid Signature */ return; } - n = ddesc.blk_count; + n = ddesc->blk_count; - mb = ldiv(n, ((1024 * 1024) / ddesc.blk_size)); /* MB */ + mb = ldiv(n, ((1024 * 1024) / ddesc->blk_size)); /* MB */ /* round to 1 digit */ - mb.rem *= 10 * ddesc.blk_size; + mb.rem *= 10 * ddesc->blk_size; mb.rem += 512 * 1024; mb.rem /= 1024 * 1024; @@ -112,10 +112,10 @@ void print_part_mac (block_dev_desc_t *dev_desc) "DeviceType=0x%x, DeviceId=0x%x\n\n" " #: type name" " length base (size)\n", - ddesc.blk_size, - ddesc.blk_count, + ddesc->blk_size, + ddesc->blk_count, mb.quot, mb.rem, gb.quot, gb.rem, - ddesc.dev_type, ddesc.dev_id + ddesc->dev_type, ddesc->dev_id ); n = 1; /* assuming at least one partition */ @@ -124,25 +124,25 @@ void print_part_mac (block_dev_desc_t *dev_desc) char c; printf ("%4ld: ", i); - if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)&mpart) != 1) { + if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)mpart) != 1) { printf ("** Can't read Partition Map on %d:%ld **\n", dev_desc->dev, i); return; } - if (mpart.signature != MAC_PARTITION_MAGIC) { + if (mpart->signature != MAC_PARTITION_MAGIC) { printf ("** Bad Signature on %d:%ld - " "expected 0x%04x, got 0x%04x\n", - dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart.signature); + dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart->signature); return; } /* update partition count */ - n = mpart.map_count; + n = mpart->map_count; c = 'k'; - bytes = mpart.block_count; - bytes /= (1024 / ddesc.blk_size); /* kB; assumes blk_size == 512 */ + bytes = mpart->block_count; + bytes /= (1024 / ddesc->blk_size); /* kB; assumes blk_size == 512 */ if (bytes >= 1024) { bytes >>= 10; c = 'M'; @@ -153,10 +153,10 @@ void print_part_mac (block_dev_desc_t *dev_desc) } printf ("%20.32s %-18.32s %10u @ %-10u (%3ld%c)\n", - mpart.type, - mpart.name, - mpart.block_count, - mpart.start_block, + mpart->type, + mpart->name, + mpart->block_count, + mpart->start_block, bytes, c ); } @@ -231,23 +231,23 @@ static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partitio int get_partition_info_mac (block_dev_desc_t *dev_desc, int part, disk_partition_t *info) { - mac_driver_desc_t ddesc; - mac_partition_t mpart; + ALLOC_CACHE_ALIGN_BUFFER(mac_driver_desc_t, ddesc, 1); + ALLOC_CACHE_ALIGN_BUFFER(mac_partition_t, mpart, 1); - if (part_mac_read_ddb (dev_desc, &ddesc)) { + if (part_mac_read_ddb (dev_desc, ddesc)) { return (-1); } - info->blksz = ddesc.blk_size; + info->blksz = ddesc->blk_size; - if (part_mac_read_pdb (dev_desc, part, &mpart)) { + if (part_mac_read_pdb (dev_desc, part, mpart)) { return (-1); } - info->start = mpart.start_block; - info->size = mpart.block_count; - memcpy (info->type, mpart.type, sizeof(info->type)); - memcpy (info->name, mpart.name, sizeof(info->name)); + info->start = mpart->start_block; + info->size = mpart->block_count; + memcpy (info->type, mpart->type, sizeof(info->type)); + memcpy (info->name, mpart->name, sizeof(info->name)); return (0); } -- cgit v1.1 From 83f83d19354f9d9b4d5d6fc06dd9c00d2340dab5 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Mon, 16 Jul 2012 21:25:40 +0000 Subject: ppc: Create a stack frame for wait_ticks() wait_ticks() calls get_ticks() without building a back chain which makes gdb unhappy when doing back trace. This can also cause improper memory accesses. Signed-off-by: Joakim Tjernlund --- arch/powerpc/lib/ticks.S | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/lib/ticks.S b/arch/powerpc/lib/ticks.S index b8d25b7..1781039 100644 --- a/arch/powerpc/lib/ticks.S +++ b/arch/powerpc/lib/ticks.S @@ -47,7 +47,9 @@ get_ticks: */ .globl wait_ticks wait_ticks: - mflr r8 /* save link register */ + stwu r1, -16(r1) + mflr r0 /* save link register */ + stw r0, 20(r1) /* Use r0 or GDB will be unhappy */ mr r7, r3 /* save tick count */ bl get_ticks /* Get start time */ @@ -61,5 +63,6 @@ wait_ticks: subfe. r3, r3, r6 bge 1b /* Loop until time expired */ - mtlr r8 /* restore link register */ + mtlr r0 /* restore link register */ + addi r1,r1,16 blr -- cgit v1.1 From 9795e07b04d8563c181352fd2839643b066a830c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 20 Jul 2012 15:18:44 +0200 Subject: FAT: cosmetic: Remove extra spaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove spaces before opening parentheses in function calls. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- fs/fat/fat.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index bc46cc5..9f83572 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -37,7 +37,7 @@ /* * Convert a string to lowercase. */ -static void downcase (char *str) +static void downcase(char *str) { while (*str != '\0') { TOLOWER(*str); @@ -62,7 +62,7 @@ static int disk_read(__u32 block, __u32 nr_blocks, void *buf) cur_part_info.start + block, nr_blocks, buf); } -int fat_register_device (block_dev_desc_t * dev_desc, int part_no) +int fat_register_device(block_dev_desc_t * dev_desc, int part_no) { ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); @@ -127,7 +127,7 @@ int fat_register_device (block_dev_desc_t * dev_desc, int part_no) * Get the first occurence of a directory delimiter ('/' or '\') in a string. * Return index into string if found, -1 otherwise. */ -static int dirdelim (char *str) +static int dirdelim(char *str) { char *start = str; @@ -142,7 +142,7 @@ static int dirdelim (char *str) /* * Extract zero terminated short name from a directory entry. */ -static void get_name (dir_entry *dirent, char *s_name) +static void get_name(dir_entry *dirent, char *s_name) { char *ptr; @@ -171,7 +171,7 @@ static void get_name (dir_entry *dirent, char *s_name) * Get the entry at index 'entry' in a FAT (12/16/32) table. * On failure 0x00 is returned. */ -static __u32 get_fatent (fsdata *mydata, __u32 entry) +static __u32 get_fatent(fsdata *mydata, __u32 entry) { __u32 bufnum; __u32 off16, offset; @@ -270,8 +270,7 @@ static __u32 get_fatent (fsdata *mydata, __u32 entry) * Return 0 on success, -1 otherwise. */ static int -get_cluster (fsdata *mydata, __u32 clustnum, __u8 *buffer, - unsigned long size) +get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size) { __u32 idx = 0; __u32 startsect; @@ -317,8 +316,8 @@ get_cluster (fsdata *mydata, __u32 clustnum, __u8 *buffer, * Return the number of bytes read or -1 on fatal errors. */ static long -get_contents (fsdata *mydata, dir_entry *dentptr, __u8 *buffer, - unsigned long maxsize) +get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer, + unsigned long maxsize) { unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0; unsigned int bytesperclust = mydata->clust_size * mydata->sect_size; @@ -397,7 +396,7 @@ getit: * starting at l_name[*idx]. * Return 1 if terminator (zero byte) is found, 0 otherwise. */ -static int slot2str (dir_slot *slotptr, char *l_name, int *idx) +static int slot2str(dir_slot *slotptr, char *l_name, int *idx) { int j; @@ -433,8 +432,8 @@ __u8 get_vfatname_block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); static int -get_vfatname (fsdata *mydata, int curclust, __u8 *cluster, - dir_entry *retdent, char *l_name) +get_vfatname(fsdata *mydata, int curclust, __u8 *cluster, + dir_entry *retdent, char *l_name) { dir_entry *realdent; dir_slot *slotptr = (dir_slot *)retdent; @@ -516,7 +515,7 @@ get_vfatname (fsdata *mydata, int curclust, __u8 *cluster, } /* Calculate short name checksum */ -static __u8 mkcksum (const char *str) +static __u8 mkcksum(const char *str) { int i; @@ -537,9 +536,9 @@ static __u8 mkcksum (const char *str) __u8 get_dentfromdir_block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); -static dir_entry *get_dentfromdir (fsdata *mydata, int startsect, - char *filename, dir_entry *retdent, - int dols) +static dir_entry *get_dentfromdir(fsdata *mydata, int startsect, + char *filename, dir_entry *retdent, + int dols) { __u16 prevcksum = 0xffff; __u32 curclust = START(retdent); @@ -699,7 +698,7 @@ static dir_entry *get_dentfromdir (fsdata *mydata, int startsect, * Read boot sector and volume info from a FAT filesystem */ static int -read_bootsectandvi (boot_sector *bs, volume_info *volinfo, int *fatsize) +read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize) { __u8 *block; volume_info *vistart; @@ -716,7 +715,7 @@ read_bootsectandvi (boot_sector *bs, volume_info *volinfo, int *fatsize) return -1; } - if (disk_read (0, 1, block) < 0) { + if (disk_read(0, 1, block) < 0) { debug("Error: reading block\n"); goto fail; } @@ -770,8 +769,7 @@ __u8 do_fat_read_block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); long -do_fat_read (const char *filename, void *buffer, unsigned long maxsize, - int dols) +do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) { char fnamecopy[2048]; boot_sector bs; @@ -1114,7 +1112,7 @@ exit: return ret; } -int file_fat_detectfs (void) +int file_fat_detectfs(void) { boot_sector bs; volume_info volinfo; @@ -1177,12 +1175,12 @@ int file_fat_detectfs (void) return 0; } -int file_fat_ls (const char *dir) +int file_fat_ls(const char *dir) { return do_fat_read(dir, NULL, 0, LS_YES); } -long file_fat_read (const char *filename, void *buffer, unsigned long maxsize) +long file_fat_read(const char *filename, void *buffer, unsigned long maxsize) { printf("reading %s\n", filename); return do_fat_read(filename, buffer, maxsize, LS_NO); -- cgit v1.1 From 8006dd2e57a9b30ff1c978e76c0dcd28d9786ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 20 Jul 2012 15:19:29 +0200 Subject: FAT: get_fatent: Fix FAT boundary check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit startblock must be taken into account in order not to read past the end of the FAT. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- fs/fat/fat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 9f83572..87a1623 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -207,8 +207,8 @@ static __u32 get_fatent(fsdata *mydata, __u32 entry) __u32 fatlength = mydata->fatlength; __u32 startblock = bufnum * FATBUFBLOCKS; - if (getsize > fatlength) - getsize = fatlength; + if (startblock + getsize > fatlength) + getsize = fatlength - startblock; fatlength *= mydata->sect_size; /* We want it in bytes now */ startblock += mydata->fat_sect; /* Offset from start of disk */ -- cgit v1.1 From 88503ad3bb5a21a95fe388a1d45e303c206a4e9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 20 Jul 2012 15:19:51 +0200 Subject: FAT: cosmetic: Remove useless assignment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fatlength is not used after this assignment, so it is useless and can be removed. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- fs/fat/fat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 87a1623..48c8844 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -210,7 +210,6 @@ static __u32 get_fatent(fsdata *mydata, __u32 entry) if (startblock + getsize > fatlength) getsize = fatlength - startblock; - fatlength *= mydata->sect_size; /* We want it in bytes now */ startblock += mydata->fat_sect; /* Offset from start of disk */ if (disk_read(startblock, getsize, bufptr) < 0) { -- cgit v1.1 From cd1b042c5c035719018cffb751714d30513af0a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 20 Jul 2012 15:20:12 +0200 Subject: FAT: Fix redundant sector read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the previous code, the remaining prefetched sectors were read again after each sector. With this patch, each sector is read only once, thus making the prefetch useful. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- fs/fat/fat.c | 59 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 48c8844..fbc2d7d 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -775,7 +775,7 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) volume_info volinfo; fsdata datablock; fsdata *mydata = &datablock; - dir_entry *dentptr; + dir_entry *dentptr = NULL; __u16 prevcksum = 0xffff; char *subname = ""; __u32 cursect; @@ -874,19 +874,21 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) while (1) { int i; - debug("FAT read sect=%d, clust_size=%d, DIRENTSPERBLOCK=%zd\n", - cursect, mydata->clust_size, DIRENTSPERBLOCK); + if (j == 0) { + debug("FAT read sect=%d, clust_size=%d, DIRENTSPERBLOCK=%zd\n", + cursect, mydata->clust_size, DIRENTSPERBLOCK); - if (disk_read(cursect, - (mydata->fatsize == 32) ? - (mydata->clust_size) : - PREFETCH_BLOCKS, - do_fat_read_block) < 0) { - debug("Error: reading rootdir block\n"); - goto exit; - } + if (disk_read(cursect, + (mydata->fatsize == 32) ? + (mydata->clust_size) : + PREFETCH_BLOCKS, + do_fat_read_block) < 0) { + debug("Error: reading rootdir block\n"); + goto exit; + } - dentptr = (dir_entry *) do_fat_read_block; + dentptr = (dir_entry *) do_fat_read_block; + } for (i = 0; i < DIRENTSPERBLOCK; i++) { char s_name[14], l_name[VFAT_MAXLEN_BYTES]; @@ -1028,28 +1030,33 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) * completely processed. */ ++j; - int fat32_end = 0; - if ((mydata->fatsize == 32) && (j == mydata->clust_size)) { - int nxtsect = 0; - int nxt_clust = 0; + int rootdir_end = 0; + if (mydata->fatsize == 32) { + if (j == mydata->clust_size) { + int nxtsect = 0; + int nxt_clust = 0; - nxt_clust = get_fatent(mydata, root_cluster); - fat32_end = CHECK_CLUST(nxt_clust, 32); + nxt_clust = get_fatent(mydata, root_cluster); + rootdir_end = CHECK_CLUST(nxt_clust, 32); - nxtsect = mydata->data_begin + - (nxt_clust * mydata->clust_size); + nxtsect = mydata->data_begin + + (nxt_clust * mydata->clust_size); - root_cluster = nxt_clust; + root_cluster = nxt_clust; - cursect = nxtsect; - j = 0; + cursect = nxtsect; + j = 0; + } } else { - cursect++; + if (j == PREFETCH_BLOCKS) + j = 0; + + rootdir_end = (++cursect - mydata->rootdir_sect >= + rootdir_size); } /* If end of rootdir reached */ - if ((mydata->fatsize == 32 && fat32_end) || - (mydata->fatsize != 32 && j == rootdir_size)) { + if (rootdir_end) { if (dols == LS_ROOT) { printf("\n%d file(s), %d dir(s)\n\n", files, dirs); -- cgit v1.1 From cc63b25efb908afa3c1405cd6fce1dd5659f91d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 20 Jul 2012 15:21:08 +0200 Subject: FAT: get_cluster: Add buffer bouncing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a buffer bouncing mechanism to get_cluster. This can be useful for misaligned applicative buffers passed through get_contents. This is required for the following patches in the case of data aligned differently relatively to buffers and clusters. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- fs/fat/fat.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index fbc2d7d..fa977b3 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -273,7 +273,6 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size) { __u32 idx = 0; __u32 startsect; - __u32 nr_sect; int ret; if (clustnum > 0) { @@ -285,25 +284,44 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size) debug("gc - clustnum: %d, startsect: %d\n", clustnum, startsect); - nr_sect = size / mydata->sect_size; - ret = disk_read(startsect, nr_sect, buffer); - if (ret != nr_sect) { - debug("Error reading data (got %d)\n", ret); - return -1; - } - if (size % mydata->sect_size) { + if ((unsigned long)buffer & (ARCH_DMA_MINALIGN - 1)) { ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size); + printf("FAT: Misaligned buffer address (%p)\n", buffer); + + while (size >= mydata->sect_size) { + ret = disk_read(startsect++, 1, tmpbuf); + if (ret != 1) { + debug("Error reading data (got %d)\n", ret); + return -1; + } + + memcpy(buffer, tmpbuf, mydata->sect_size); + buffer += mydata->sect_size; + size -= mydata->sect_size; + } + } else { idx = size / mydata->sect_size; - ret = disk_read(startsect + idx, 1, tmpbuf); + ret = disk_read(startsect, idx, buffer); + if (ret != idx) { + debug("Error reading data (got %d)\n", ret); + return -1; + } + startsect += idx; + idx *= mydata->sect_size; + buffer += idx; + size -= idx; + } + if (size) { + ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size); + + ret = disk_read(startsect, 1, tmpbuf); if (ret != 1) { debug("Error reading data (got %d)\n", ret); return -1; } - buffer += idx * mydata->sect_size; - memcpy(buffer, tmpbuf, size % mydata->sect_size); - return 0; + memcpy(buffer, tmpbuf, size); } return 0; -- cgit v1.1 From 0880e5bb0c638aec47c1f9349bbb9a0f48179313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 20 Jul 2012 15:21:37 +0200 Subject: FAT: Simplify get_contents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One call to get_cluster can be factorized with another, so avoid duplicating code. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- fs/fat/fat.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index fa977b3..f7bb1da 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -367,21 +367,9 @@ get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer, actsize += bytesperclust; } - /* actsize >= file size */ - actsize -= bytesperclust; - - /* get remaining clusters */ - if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) { - printf("Error reading cluster\n"); - return -1; - } - /* get remaining bytes */ - gotsize += (int)actsize; - filesize -= actsize; - buffer += actsize; actsize = filesize; - if (get_cluster(mydata, endclust, buffer, (int)actsize) != 0) { + if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) { printf("Error reading cluster\n"); return -1; } -- cgit v1.1 From df930e9b3c6a644d1b0b50dce31fc9f4686925c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 20 Jul 2012 16:05:36 +0200 Subject: rtc: pcf8563: Make century compatible with Linux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver uses the century bit of this RTC in the opposite way Linux does. From Linux's rtc-pcf8563.c: /* * The meaning of MO_C bit varies by the chip type. * From PCF8563 datasheet: this bit is toggled when the years * register overflows from 99 to 00 * 0 indicates the century is 20xx * 1 indicates the century is 19xx * From RTC8564 datasheet: this bit indicates change of * century. When the year digit data overflows from 99 to 00, * this bit is set. By presetting it to 0 while still in the * 20th century, it will be set in year 2000, ... * There seems no reliable way to know how the system use this * bit. So let's do it heuristically, assuming we are live in * 1970...2069. */ As U-Boot's PCF8563 driver does not say it is supposed to support the RTC8564, make this driver compatible with Linux's by giving the opposite meaning to the century bit. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- drivers/rtc/pcf8563.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/pcf8563.c b/drivers/rtc/pcf8563.c index 339e5f6..a028533 100644 --- a/drivers/rtc/pcf8563.c +++ b/drivers/rtc/pcf8563.c @@ -72,7 +72,7 @@ int rtc_get (struct rtc_time *tmp) tmp->tm_hour = bcd2bin (hour & 0x3F); tmp->tm_mday = bcd2bin (mday & 0x3F); tmp->tm_mon = bcd2bin (mon_cent & 0x1F); - tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900); + tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 1900 : 2000); tmp->tm_wday = bcd2bin (wday & 0x07); tmp->tm_yday = 0; tmp->tm_isdst= 0; @@ -94,7 +94,7 @@ int rtc_set (struct rtc_time *tmp) rtc_write (0x08, bin2bcd(tmp->tm_year % 100)); - century = (tmp->tm_year >= 2000) ? 0x80 : 0; + century = (tmp->tm_year >= 2000) ? 0 : 0x80; rtc_write (0x07, bin2bcd(tmp->tm_mon) | century); rtc_write (0x06, bin2bcd(tmp->tm_wday)); -- cgit v1.1 From cee84e82576e00fb18b0134712ee8686bab36eaa Mon Sep 17 00:00:00 2001 From: Jagannadha Sutradharudu Teki <402jagan@gmail.com> Date: Fri, 27 Jul 2012 22:02:22 +0000 Subject: image/FIT: Add ramdisk load, entry address and OS tag inclusion This patch adds support to include Load, Entry address and OS tag of ramdisk on to FIT image through mkimage tool. Signed-off-by: Jagannadha Sutradharudu Teki <402jagan@gmail.com> --- common/image.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/common/image.c b/common/image.c index 91954ac..70a112d 100644 --- a/common/image.c +++ b/common/image.c @@ -2042,13 +2042,13 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) printf("%s Architecture: %s\n", p, genimg_get_arch_name(arch)); } - if (type == IH_TYPE_KERNEL) { + if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK)) { fit_image_get_os(fit, image_noffset, &os); printf("%s OS: %s\n", p, genimg_get_os_name(os)); } if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || - (type == IH_TYPE_FIRMWARE)) { + (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK)) { ret = fit_image_get_load(fit, image_noffset, &load); printf("%s Load Address: ", p); if (ret) @@ -2057,7 +2057,8 @@ void fit_image_print(const void *fit, int image_noffset, const char *p) printf("0x%08lx\n", load); } - if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) { + if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || + (type == IH_TYPE_RAMDISK)) { fit_image_get_entry(fit, image_noffset, &entry); printf("%s Entry Point: ", p); if (ret) -- cgit v1.1 From 3801a15f67d66cf585db789d430c8f5808b0772b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 30 Jul 2012 07:38:38 +0000 Subject: env_nand: align NAND buffers This allows cache flush/invalidate operations to succeed on the buffers. Signed-off-by: Stephen Warren Acked-by: Simon Glass Acked-by: Scott Wood --- common/env_nand.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/env_nand.c b/common/env_nand.c index e8daec9..e635472 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -226,7 +226,7 @@ int saveenv(void) int saveenv(void) { int ret = 0; - env_t env_new; + ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, sizeof(env_t)); ssize_t len; char *res; nand_erase_options_t nand_erase_options; @@ -238,20 +238,20 @@ int saveenv(void) if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE) return 1; - res = (char *)&env_new.data; + res = (char *)&env_new->data; len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); return 1; } - env_new.crc = crc32(0, env_new.data, ENV_SIZE); + env_new->crc = crc32(0, env_new->data, ENV_SIZE); puts("Erasing Nand...\n"); if (nand_erase_opts(&nand_info[0], &nand_erase_options)) return 1; puts("Writing to Nand... "); - if (writeenv(CONFIG_ENV_OFFSET, (u_char *)&env_new)) { + if (writeenv(CONFIG_ENV_OFFSET, (u_char *)env_new)) { puts("FAILED!\n"); return 1; } @@ -398,7 +398,7 @@ void env_relocate_spec(void) { #if !defined(ENV_IS_EMBEDDED) int ret; - char buf[CONFIG_ENV_SIZE]; + ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); #if defined(CONFIG_ENV_OFFSET_OOB) ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset); -- cgit v1.1 From 8a156fb6e43208e77dd9a8b6265e491bc7814950 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 30 Jul 2012 22:44:53 +0000 Subject: fix out of tree building with kallsyms The call to SYSTEM_MAP assumes that the u-boot output is in $PWD when it really should be in $(obj). This fixes building out of tree. Signed-off-by: Mike Frysinger --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b9011c8..058fb53 100644 --- a/Makefile +++ b/Makefile @@ -517,7 +517,7 @@ $(obj)u-boot: depend \ $(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds $(GEN_UBOOT) ifeq ($(CONFIG_KALLSYMS),y) - smap=`$(call SYSTEM_MAP,u-boot) | \ + smap=`$(call SYSTEM_MAP,$(obj)u-boot) | \ awk '$$2 ~ /[tTwW]/ {printf $$1 $$3 "\\\\000"}'` ; \ $(CC) $(CFLAGS) -DSYSTEM_MAP="\"$${smap}\"" \ -c common/system_map.c -o $(obj)common/system_map.o -- cgit v1.1 From c20dbf64a976a40d39694a991d3bf51985cb35f6 Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Thu, 2 Aug 2012 10:49:24 +0000 Subject: input: key_matrix: fix header inclusion On Microblaze with device tree support enabled we run into the error below. I'm not sure, but I think that all source code should include at least the common.h and just this fix the problem on Microblaz architecture. The error is: In file included from key_matrix.c:29: include/malloc.h:364: error: conflicting types for 'memset' include/linux/string.h:71: error: previous declaration of 'memset' was here include/malloc.h:365: error: conflicting types for 'memcpy' include/linux/string.h:74: error: previous declaration of 'memcpy' was here Signed-off-by: Stephan Linz CC: Bernie Thompson CC: Simon Glass CC: Tom Warren CC: Michal Simek Acked-by: Simon Glass Acked-by: Michal Simek --- drivers/input/key_matrix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/key_matrix.c b/drivers/input/key_matrix.c index 84b898f..715e57a 100644 --- a/drivers/input/key_matrix.c +++ b/drivers/input/key_matrix.c @@ -23,6 +23,7 @@ * MA 02111-1307 USA */ +#include #include #include #include -- cgit v1.1 From 15c6935b0c8267d0cd70e18a0cf6e31345f50266 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 8 Aug 2012 01:42:17 +0000 Subject: dm: Initial import of design documents This patch contains UDM-design.txt, which is document containing general description of the driver model. The remaining files contains descriptions of conversion process of particular subsystems. Signed-off-by: Marek Vasut --- doc/driver-model/UDM-design.txt | 315 ++++++++++++++++++++++++++++++++++++++ doc/driver-model/UDM-fpga.txt | 115 ++++++++++++++ doc/driver-model/UDM-keyboard.txt | 47 ++++++ doc/driver-model/UDM-serial.txt | 191 +++++++++++++++++++++++ doc/driver-model/UDM-stdio.txt | 191 +++++++++++++++++++++++ doc/driver-model/UDM-tpm.txt | 48 ++++++ doc/driver-model/UDM-usb.txt | 94 ++++++++++++ doc/driver-model/UDM-video.txt | 74 +++++++++ 8 files changed, 1075 insertions(+) create mode 100644 doc/driver-model/UDM-design.txt create mode 100644 doc/driver-model/UDM-fpga.txt create mode 100644 doc/driver-model/UDM-keyboard.txt create mode 100644 doc/driver-model/UDM-serial.txt create mode 100644 doc/driver-model/UDM-stdio.txt create mode 100644 doc/driver-model/UDM-tpm.txt create mode 100644 doc/driver-model/UDM-usb.txt create mode 100644 doc/driver-model/UDM-video.txt diff --git a/doc/driver-model/UDM-design.txt b/doc/driver-model/UDM-design.txt new file mode 100644 index 0000000..185f477 --- /dev/null +++ b/doc/driver-model/UDM-design.txt @@ -0,0 +1,315 @@ +The U-Boot Driver Model Project +=============================== +Design document +=============== +Marek Vasut +Pavel Herrmann +2012-05-17 + +I) The modular concept +---------------------- + +The driver core design is done with modularity in mind. The long-term plan is to +extend this modularity to allow loading not only drivers, but various other +objects into U-Boot at runtime -- like commands, support for other boards etc. + +II) Driver core initialization stages +------------------------------------- + +The drivers have to be initialized in two stages, since the U-Boot bootloader +runs in two stages itself. The first stage is the one which is executed before +the bootloader itself is relocated. The second stage then happens after +relocation. + + 1) First stage + -------------- + + The first stage runs after the bootloader did very basic hardware init. This + means the stack pointer was configured, caches disabled and that's about it. + The problem with this part is the memory management isn't running at all. To + make things even worse, at this point, the RAM is still likely uninitialized + and therefore unavailable. + + 2) Second stage + --------------- + + At this stage, the bootloader has initialized RAM and is running from it's + final location. Dynamic memory allocations are working at this point. Most of + the driver initialization is executed here. + +III) The drivers +---------------- + + 1) The structure of a driver + ---------------------------- + + The driver will contain a structure located in a separate section, which + will allow linker to create a list of compiled-in drivers at compile time. + Let's call this list "driver_list". + + struct driver __attribute__((section(driver_list))) { + /* The name of the driver */ + char name[STATIC_CONFIG_DRIVER_NAME_LENGTH]; + + /* + * This function should connect this driver with cores it depends on and + * with other drivers, likely bus drivers + */ + int (*bind)(struct instance *i); + + /* This function actually initializes the hardware. */ + int (*probe)(struct instance *i); + + /* + * The function of the driver called when U-Boot finished relocation. + * This is particularly important to eg. move pointers to DMA buffers + * and such from the location before relocation to their final location. + */ + int (*reloc)(struct instance *i); + + /* + * This is called when the driver is shuting down, to deinitialize the + * hardware. + */ + int (*remove)(struct instance *i); + + /* This is called to remove the driver from the driver tree */ + int (*unbind)(struct instance *i); + + /* This is a list of cores this driver depends on */ + struct driver *cores[]; + }; + + The cores[] array in here is very important. It allows u-boot to figure out, + in compile-time, which possible cores can be activated at runtime. Therefore + if there are cores that won't be ever activated, GCC LTO might remove them + from the final binary. Actually, this information might be used to drive build + of the cores. + + FIXME: Should *cores[] be really struct driver, pointing to drivers that + represent the cores? Shouldn't it be core instance pointer? + + 2) Instantiation of a driver + ---------------------------- + + The driver is instantiated by calling: + + driver_bind(struct instance *bus, const struct driver_info *di) + + The "struct instance *bus" is a pointer to a bus with which this driver should + be registered with. The "root" bus pointer is supplied to the board init + functions. + + FIXME: We need some functions that will return list of busses of certain type + registered with the system so the user can find proper instance even if + he has no bus pointer (this will come handy if the user isn't + registering the driver from board init function, but somewhere else). + + The "const struct driver_info *di" pointer points to a structure defining the + driver to be registered. The structure is defined as follows: + + struct driver_info { + char name[STATIC_CONFIG_DRIVER_NAME_LENGTH]; + void *platform_data; + } + + The instantiation of a driver by calling driver_bind() creates an instance + of the driver by allocating "struct driver_instance". Note that only struct + instance is passed to the driver. The wrapping struct driver_instance is there + for purposes of the driver core: + + struct driver_instance { + uint32_t flags; + struct instance i; + }; + + struct instance { + /* Pointer to a driver information passed by driver_register() */ + const struct driver_info *info; + /* Pointer to a bus this driver is bound with */ + struct instance *bus; + /* Pointer to this driver's own private data */ + void *private_data; + /* Pointer to the first block of successor nodes (optional) */ + struct successor_block *succ; + } + + The instantiation of a driver does not mean the hardware is initialized. The + driver_bind() call only creates the instance of the driver, fills in the "bus" + pointer and calls the drivers' .bind() function. The .bind() function of the + driver should hook the driver with the remaining cores and/or drivers it + depends on. + + It's important to note here, that in case the driver instance has multiple + parents, such parent can be connected with this instance by calling: + + driver_link(struct instance *parent, struct instance *dev); + + This will connect the other parent driver with the newly instantiated driver. + Note that this must be called after driver_bind() and before driver_acticate() + (driver_activate() will be explained below). To allow struct instance to have + multiple parent pointer, the struct instance *bus will utilize it's last bit + to indicate if this is a pointer to struct instance or to an array if + instances, struct successor block. The approach is similar as the approach to + *succ in struct instance, described in the following paragraph. + + The last pointer of the struct instance, the pointer to successor nodes, is + used only in case of a bus driver. Otherwise the pointer contains NULL value. + The last bit of this field indicates if this is a bus having a single child + node (so the last bit is 0) or if this bus has multiple child nodes (the last + bit is 1). In the former case, the driver core should clear the last bit and + this pointer points directly to the child node. In the later case of a bus + driver, the pointer points to an instance of structure: + + struct successor_block { + /* Array of pointers to instances of devices attached to this bus */ + struct instance *dev[BLOCKING_FACTOR]; + /* Pointer to next block of successors */ + struct successor_block *next; + } + + Some of the *dev[] array members might be NULL in case there are no more + devices attached. The *next is NULL in case the list of attached devices + doesn't continue anymore. The BLOCKING_FACTOR is used to allocate multiple + slots for successor devices at once to avoid fragmentation of memory. + + 3) The bind() function of a driver + ---------------------------------- + + The bind function of a driver connects the driver with various cores the + driver provides functions for. The driver model related part will look like + the following example for a bus driver: + + int driver_bind(struct instance *in) + { + ... + core_bind(&core_i2c_static_instance, in, i2c_bus_funcs); + ... + } + + FIXME: What if we need to run-time determine, depending on some hardware + register, what kind of i2c_bus_funcs to pass? + + This makes the i2c core aware of a new bus. The i2c_bus_funcs is a constant + structure of functions any i2c bus driver must provide to work. This will + allow the i2c command operate with the bus. The core_i2c_static_instance is + the pointer to the instance of a core this driver provides function to. + + FIXME: Maybe replace "core-i2c" with CORE_I2C global pointer to an instance of + the core? + + 4) The instantiation of a core driver + ------------------------------------- + + The core driver is special in the way that it's single-instance driver. It is + always present in the system, though it might not be activated. The fact that + it's single instance allows it to be instantiated at compile time. + + Therefore, all possible structures of this driver can be in read-only memory, + especially struct driver and struct driver_instance. But the successor list, + which needs special treatment. + + To solve the problem with a successor list and the core driver flags, a new + entry in struct gd (global data) will be introduced. This entry will point to + runtime allocated array of struct driver_instance. It will be possible to + allocate the exact amount of struct driver_instance necessary, as the number + of cores that might be activated will be known at compile time. The cores will + then behave like any usual driver. + + Pointers to the struct instance of cores can be computed at compile time, + therefore allowing the resulting u-boot binary to save some overhead. + + 5) The probe() function of a driver + ----------------------------------- + + The probe function of a driver allocates necessary resources and does required + initialization of the hardware itself. This is usually called only when the + driver is needed, as a part of the defered probe mechanism. + + The driver core should implement a function called + + int driver_activate(struct instance *in); + + which should call the .probe() function of the driver and then configure the + state of the driver instance to "ACTIVATED". This state of a driver instance + should be stored in a wrap-around structure for the structure instance, the + struct driver_instance. + + 6) The command side interface to a driver + ----------------------------------------- + + The U-Boot command shall communicate only with the specific driver core. The + driver core in turn exports necessary API towards the command. + + 7) Demonstration imaginary board + -------------------------------- + + Consider the following computer: + + * + | + +-- System power management logic + | + +-- CPU clock controlling logc + | + +-- NAND controller + | | + | +-- NAND flash chip + | + +-- 128MB of DDR DRAM + | + +-- I2C bus #0 + | | + | +-- RTC + | | + | +-- EEPROM #0 + | | + | +-- EEPROM #1 + | + +-- USB host-only IP core + | | + | +-- USB storage device + | + +-- USB OTG-capable IP core + | | + | +-- connection to the host PC + | + +-- GPIO + | | + | +-- User LED #0 + | | + | +-- User LED #1 + | + +-- UART0 + | + +-- UART1 + | + +-- Ethernet controller #0 + | + +-- Ethernet controller #1 + | + +-- Audio codec + | + +-- PCI bridge + | | + | +-- Ethernet controller #2 + | | + | +-- SPI host card + | | | + | | +-- Audio amplifier (must be operational before codec) + | | + | +-- GPIO host card + | | + | +-- User LED #2 + | + +-- LCD controller + | + +-- PWM controller (must be enabled after LCD controller) + | + +-- SPI host controller + | | + | +-- SD/MMC connected via SPI + | | + | +-- SPI flash + | + +-- CPLD/FPGA with stored configuration of the board diff --git a/doc/driver-model/UDM-fpga.txt b/doc/driver-model/UDM-fpga.txt new file mode 100644 index 0000000..4f9df94 --- /dev/null +++ b/doc/driver-model/UDM-fpga.txt @@ -0,0 +1,115 @@ +The U-Boot Driver Model Project +=============================== +I/O system analysis +=================== +Marek Vasut +2012-02-21 + +I) Overview +----------- + +The current FPGA implementation is handled by command "fpga". This command in +turn calls the following functions: + +fpga_info() +fpga_load() +fpga_dump() + +These functions are implemented by what appears to be FPGA multiplexer, located +in drivers/fpga/fpga.c . This code determines which device to operate with +depending on the device ID. + +The fpga_info() function is multiplexer of the functions providing information +about the particular FPGA device. These functions are implemented in the drivers +for the particular FPGA device: + +xilinx_info() +altera_info() +lattice_info() + +Similar approach is used for fpga_load(), which multiplexes "xilinx_load()", +"altera_load()" and "lattice_load()" and is used to load firmware into the FPGA +device. + +The fpga_dump() function, which prints the contents of the FPGA device, is no +different either, by multiplexing "xilinx_dump()", "altera_dump()" and +"lattice_dump()" functions. + +Finally, each new FPGA device is registered by calling "fpga_add()" function. +This function takes two arguments, the second one being particularly important, +because it's basically what will become platform_data. Currently, it's data that +are passed to the driver from the board/platform code. + +II) Approach +------------ + +The path to conversion of the FPGA subsystem will be very straightforward, since +the FPGA subsystem is already quite dynamic. Multiple things will need to be +modified though. + +First is the registration of the new FPGA device towards the FPGA core. This +will be achieved by calling: + + fpga_device_register(struct instance *i, const struct fpga_ops *ops); + +The particularly interesting part is the struct fpga_ops, which contains +operations supported by the FPGA device. These are basically the already used +calls in the current implementation: + +struct fpga_ops { + int info(struct instance *i); + int load(struct instance *i, const char *buf, size_t size); + int dump(struct instance *i, const char *buf, size_t size); +} + +The other piece that'll have to be modified is how the devices are tracked. +It'll be necessary to introduce a linked list of devices within the FPGA core +instead of tracking them by ID number. + +Next, the "Xilinx_desc", "Lattice_desc" and "Altera_desc" structures will have +to be moved to driver's private_data. Finally, structures passed from the board +and/or platform files, like "Xilinx_Virtex2_Slave_SelectMap_fns" would be passed +via platform_data to the driver. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) Altera driver + ---------------- + The driver is realized using the following files: + + drivers/fpga/altera.c + drivers/fpga/ACEX1K.c + drivers/fpga/cyclon2.c + drivers/fpga/stratixII.c + + All of the sub-drivers implement basically the same info-load-dump interface + and there's no expected problem during the conversion. The driver itself will + be realised by altera.c and all the sub-drivers will be linked in. The + distinction will be done by passing different platform data. + + 2) Lattice driver + ----------------- + The driver is realized using the following files: + + drivers/fpga/lattice.c + drivers/fpga/ivm_core.c + + This driver also implements the standard interface, but to realise the + operations with the FPGA device, uses functions from "ivm_core.c" file. This + file implements the main communications logic and has to be linked in together + with "lattice.c". No problem converting is expected here. + + 3) Xilinx driver + ---------------- + The driver is realized using the following files: + + drivers/fpga/xilinx.c + drivers/fpga/spartan2.c + drivers/fpga/spartan3.c + drivers/fpga/virtex2.c + + This set of sub-drivers is special by defining a big set of macros in + "include/spartan3.h" and similar files. These macros would need to be either + rewritten or replaced. Otherwise, there are no problems expected during the + conversion process. diff --git a/doc/driver-model/UDM-keyboard.txt b/doc/driver-model/UDM-keyboard.txt new file mode 100644 index 0000000..ef3761d --- /dev/null +++ b/doc/driver-model/UDM-keyboard.txt @@ -0,0 +1,47 @@ +The U-Boot Driver Model Project +=============================== +Keyboard input analysis +======================= +Marek Vasut +2012-02-20 + +I) Overview +----------- + +The keyboard drivers are most often registered with STDIO subsystem. There are +components of the keyboard drivers though, which operate in severe ad-hoc +manner, often being related to interrupt-driven keypress reception. This +components will require the most sanitization of all parts of keyboard input +subsystem. + +Otherwise, the keyboard is no different from other standard input but with the +necessity to decode scancodes. These are decoded using tables provided by +keyboard drivers. These tables are often driver specific. + +II) Approach +------------ + +The most problematic part is the interrupt driven keypress reception. For this, +the buffers that are currently shared throughout the whole U-Boot would need to +be converted into driver's private data. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) board/mpl/common/kbd.c + ------------------------- + This driver is a classic STDIO driver, no problem with conversion is expected. + Only necessary change will be to move this driver to a proper location. + + 2) board/rbc823/kbd.c + --------------------- + This driver is a classic STDIO driver, no problem with conversion is expected. + Only necessary change will be to move this driver to a proper location. + + 3) drivers/input/keyboard.c + --------------------------- + This driver is special in many ways. Firstly because this is a universal stub + driver for converting scancodes from i8042 and the likes. Secondly because the + buffer is filled by various other ad-hoc implementations of keyboard input by + using this buffer as an extern. This will need to be fixed by allowing drivers + to pass certain routines to this driver via platform data. diff --git a/doc/driver-model/UDM-serial.txt b/doc/driver-model/UDM-serial.txt new file mode 100644 index 0000000..e9c274d --- /dev/null +++ b/doc/driver-model/UDM-serial.txt @@ -0,0 +1,191 @@ +The U-Boot Driver Model Project +=============================== +Serial I/O analysis +=================== +Marek Vasut +2012-02-20 + +I) Overview +----------- + +The serial port support currently requires the driver to export the following +functions: + + serial_putc() ...... Output a character + serial_puts() ...... Output string, often done using serial_putc() + serial_tstc() ...... Test if incoming character is in a buffer + serial_getc() ...... Retrieve incoming character + serial_setbrg() .... Configure port options + serial_init() ...... Initialize the hardware + +The simpliest implementation, supporting only one port, simply defines these six +functions and calls them. Such calls are scattered all around U-Boot, especiall +serial_putc(), serial_puts(), serial_tstc() and serial_getc(). The serial_init() +and serial_setbrg() are often called from platform-dependent places. + +It's important to consider current implementation of CONFIG_SERIAL_MULTI though. +This resides in common/serial.c and behaves as a multiplexer for serial ports. +This, by calling serial_assign(), allows user to switch I/O from one serial port +to another. Though the environmental variables "stdin", "stdout", "stderr" +remain set to "serial". + +These variables are managed by the IOMUX. This resides in common/iomux.c and +manages all console input/output from U-Boot. For serial port, only one IOMUX is +always registered, called "serial" and the switching of different serial ports +is done by code in common/serial.c. + +On a final note, it's important to mention function default_serial_console(), +which is platform specific and reports the default serial console for the +platform, unless proper environment variable overrides this. + +II) Approach +------------ + +Drivers not using CONFIG_SERIAL_MULTI already will have to be converted to +similar approach. The probe() function of a driver will call a function +registering the driver with a STDIO subsystem core, stdio_device_register(). + +The serial_init() function will now be replaced by probe() function of the +driver, the rest of the components of the driver will be converted to standard +STDIO driver calls. See [ UDM-stdio.txt ] for details. + +The serial_setbrg() function depends on global data pointer. This is wrong, +since there is likely to be user willing to configure different baudrate on two +different serial ports. The function will be replaced with STDIO's "conf()" +call, with STDIO_CONFIG_SERIAL_BAUDRATE argument. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) altera_jtag_uart.c + --------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 2) altera_uart.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 3) arm_dcc.c + ------------ + No support for CONFIG_SERIAL_MULTI. Simple conversion possible, unless used + with CONFIG_ARM_DCC_MULTI. Then it registers another separate IOMUX. + + 4) atmel_usart.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 5) mcfuart.c + ------------ + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 6) ns16550.c + ------------ + This driver seems complicated and certain consideration will need to be made + during conversion. This driver is implemented in very universal manner, + therefore it'll be necessary to properly design it's platform_data. + + 7) ns9750_serial.c + ------------------ + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 8) opencores_yanu.c + ------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 9) s3c4510b_uart.c + ------------------ + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 10) s3c64xx.c + ------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 11) sandbox.c + ------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 12) serial.c + ------------ + This is a complementary part of NS16550 UART driver, see above. + + 13) serial_clps7111.c + --------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 14) serial_imx.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. This driver + might be removed in favor of serial_mxc.c . + + 15) serial_ixp.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 16) serial_ks8695.c + ------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 17) serial_lh7a40x.c + -------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 18) serial_lpc2292.c + -------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 19) serial_max3100.c + -------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 20) serial_mxc.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 21) serial_netarm.c + ------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 22) serial_pl01x.c + ------------------ + No support for CONFIG_SERIAL_MULTI. Simple conversion possible, though this + driver in fact contains two drivers in total. + + 23) serial_pxa.c + ---------------- + This driver is a bit complicated, but due to clean support for + CONFIG_SERIAL_MULTI, there are no expected obstructions throughout the + conversion process. + + 24) serial_s3c24x0.c + -------------------- + This driver, being quite ad-hoc might need some work to bring back to shape. + + 25) serial_s3c44b0.c + -------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 26) serial_s5p.c + ---------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 27) serial_sa1100.c + ------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 28) serial_sh.c + --------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 29) serial_xuartlite.c + ---------------------- + No support for CONFIG_SERIAL_MULTI. Simple conversion possible. + + 30) usbtty.c + ------------ + This driver seems very complicated and entangled with USB framework. The + conversion might be complicated here. + + 31) arch/powerpc/cpu/mpc512x/serial.c + ------------------------------------- + This driver supports CONFIG_SERIAL_MULTI. This driver will need to be moved to + proper place. diff --git a/doc/driver-model/UDM-stdio.txt b/doc/driver-model/UDM-stdio.txt new file mode 100644 index 0000000..a6c484f --- /dev/null +++ b/doc/driver-model/UDM-stdio.txt @@ -0,0 +1,191 @@ +The U-Boot Driver Model Project +=============================== +I/O system analysis +=================== +Marek Vasut +2012-02-20 + +I) Overview +----------- + +The console input and output is currently done using the STDIO subsystem in +U-Boot. The design of this subsystem is already flexible enough to be easily +converted to new driver model approach. Minor changes will need to be done +though. + +Each device that wants to register with STDIO subsystem has to define struct +stdio_dev, defined in include/stdio_dev.h and containing the following fields: + +struct stdio_dev { + int flags; /* Device flags: input/output/system */ + int ext; /* Supported extensions */ + char name[16]; /* Device name */ + +/* GENERAL functions */ + + int (*start) (void); /* To start the device */ + int (*stop) (void); /* To stop the device */ + +/* OUTPUT functions */ + + void (*putc) (const char c); /* To put a char */ + void (*puts) (const char *s); /* To put a string (accelerator) */ + +/* INPUT functions */ + + int (*tstc) (void); /* To test if a char is ready... */ + int (*getc) (void); /* To get that char */ + +/* Other functions */ + + void *priv; /* Private extensions */ + struct list_head list; +}; + +Currently used flags are DEV_FLAGS_INPUT, DEV_FLAGS_OUTPUT and DEV_FLAGS_SYSTEM, +extensions being only one, the DEV_EXT_VIDEO. + +The private extensions are now used as a per-device carrier of private data and +finally list allows this structure to be a member of linked list of STDIO +devices. + +The STDIN, STDOUT and STDERR routing is handled by environment variables +"stdin", "stdout" and "stderr". By configuring the variable to the name of a +driver, functions of such driver are called to execute that particular +operation. + +II) Approach +------------ + + 1) Similarity of serial, video and keyboard drivers + --------------------------------------------------- + + All of these drivers can be unified under the STDIO subsystem if modified + slightly. The serial drivers basically define both input and output functions + and need function to configure baudrate. The keyboard drivers provide only + input. On the other hand, video drivers provide output, but need to be + configured in certain way. This configuration might be dynamic, therefore the + STDIO has to be modified to provide such flexibility. + + 2) Unification of serial, video and keyboard drivers + ---------------------------------------------------- + + Every STDIO device would register a structure containing operation it supports + with the STDIO core by calling: + + int stdio_device_register(struct instance *i, struct stdio_device_ops *o); + + The structure being defined as follows: + + struct stdio_device_ops { + void (*putc)(struct instance *i, const char c); + void (*puts)(struct instance *i, const char *s); /* OPTIONAL */ + + int (*tstc)(struct instance *i); + int (*getc)(struct instance *i); + + int (*init)(struct instance *i); + int (*exit)(struct instance *i); + int (*conf)(struct instance *i, enum stdio_config c, const void *data); + }; + + The "putc()" function will emit a character, the "puts()" function will emit a + string. If both of these are set to NULL, the device is considered STDIN only, + aka input only device. + + The "getc()" retrieves a character from a STDIN device, while "tstc()" tests + if there is a character in the buffer of STDIN device. In case these two are + set to NULL, this device is STDOUT / STDERR device. + + Setting all "putc()", "puts()", "getc()" and "tstc()" calls to NULL isn't an + error condition, though such device does nothing. By instroducing tests for + these functions being NULL, the "flags" and "ext" fields from original struct + stdio_dev can be eliminated. + + The "init()" and "exit()" calls are replacement for "start()" and "exit()" + calls in the old approach. The "priv" part of the old struct stdio_dev will be + replaced by common private data in the driver model and the struct list_head + list will be eliminated by introducing common STDIO core, that tracks all the + STDIO devices. + + Lastly, the "conf()" call will allow the user to configure various options of + the driver. The enum stdio_config contains all possible configuration options + available to the STDIO devices, const void *data being the argument to be + configured. Currently, the enum stdio_config will contain at least the + following options: + + enum stdio_config { + STDIO_CONFIG_SERIAL_BAUDRATE, + }; + + 3) Transformation of stdio routing + ---------------------------------- + + By allowing multiple instances of drivers, the environment variables "stdin", + "stdout" and "stderr" can no longer be set to the name of the driver. + Therefore the STDIO core, tracking all of the STDIO devices in the system will + need to have a small amount of internal data for each device: + + struct stdio_device_node { + struct instance *i; + struct stdio_device_ops *ops; + uint8_t id; + uint8_t flags; + struct list_head list; + } + + The "id" is the order of the instance of the same driver. The "flags" variable + allows multiple drivers to be used at the same time and even for different + purpose. The following flags will be defined: + + STDIO_FLG_STDIN ..... This device will be used as an input device. All input + from all devices with this flag set will be received + and passed to the upper layers. + STDIO_FLG_STDOUT .... This device will be used as an output device. All + output sent to stdout will be routed to all devices + with this flag set. + STDIO_FLG_STDERR .... This device will be used as an standard error output + device. All output sent to stderr will be routed to + all devices with this flag set. + + The "list" member of this structure allows to have a linked list of all + registered STDIO devices. + +III) Analysis of in-tree drivers +-------------------------------- + +For in-depth analysis of serial port drivers, refer to [ UDM-serial.txt ]. +For in-depth analysis of keyboard drivers, refer to [ UDM-keyboard.txt ]. +For in-depth analysis of video drivers, refer to [ UDM-video.txt ]. + + 1) arch/blackfin/cpu/jtag-console.c + ----------------------------------- + This driver is a classic STDIO driver, no problem with conversion is expected. + + 2) board/mpl/pati/pati.c + ------------------------ + This driver registers with the STDIO framework, though it uses a lot of ad-hoc + stuff which will need to be sorted out. + + 3) board/netphone/phone_console.c + --------------------------------- + This driver is a classic STDIO driver, no problem with conversion is expected. + + 4) drivers/net/netconsole.c + --------------------------- + This driver is a classic STDIO driver, no problem with conversion is expected. + +IV) Other involved files (To be removed) +---------------------------------------- + +common/cmd_console.c +common/cmd_log.c +common/cmd_terminal.c +common/console.c +common/fdt_support.c +common/iomux.c +common/lcd.c +common/serial.c +common/stdio.c +common/usb_kbd.c +doc/README.iomux diff --git a/doc/driver-model/UDM-tpm.txt b/doc/driver-model/UDM-tpm.txt new file mode 100644 index 0000000..91a953a --- /dev/null +++ b/doc/driver-model/UDM-tpm.txt @@ -0,0 +1,48 @@ +The U-Boot Driver Model Project +=============================== +TPM system analysis +=================== +Marek Vasut +2012-02-23 + +I) Overview +----------- + +There is currently only one TPM chip driver available and therefore the API +controlling it is very much based on this. The API is very simple: + + int tis_open(void); + int tis_close(void); + int tis_sendrecv(const u8 *sendbuf, size_t send_size, + u8 *recvbuf, size_t *recv_len); + +The command operating the TPM chip only provides operations to send and receive +bytes from the chip. + +II) Approach +------------ + +The API can't be generalised too much considering there's only one TPM chip +supported. But it's a good idea to split the tis_sendrecv() function in two +functions. Therefore the new API will use register the TPM chip by calling: + + tpm_device_register(struct instance *i, const struct tpm_ops *ops); + +And the struct tpm_ops will contain the following members: + + struct tpm_ops { + int (*tpm_open)(struct instance *i); + int (*tpm_close)(struct instance *i); + int (*tpm_send)(const uint8_t *buf, const size_t size); + int (*tpm_recv)(uint8_t *buf, size_t *size); + }; + +The behaviour of "tpm_open()" and "tpm_close()" will basically copy the +behaviour of "tis_open()" and "tis_close()". The "tpm_send()" will be based on +the "tis_senddata()" and "tis_recv()" will be based on "tis_readresponse()". + +III) Analysis of in-tree drivers +-------------------------------- + +There is only one in-tree driver present, the "drivers/tpm/generic_lpc_tpm.c", +which will be simply converted as outlined in previous chapter. diff --git a/doc/driver-model/UDM-usb.txt b/doc/driver-model/UDM-usb.txt new file mode 100644 index 0000000..5ce85b5 --- /dev/null +++ b/doc/driver-model/UDM-usb.txt @@ -0,0 +1,94 @@ +The U-Boot Driver Model Project +=============================== +USB analysis +============ +Marek Vasut +2012-02-16 + +I) Overview +----------- + + 1) The USB Host driver + ---------------------- + There are basically four or five USB host drivers. All such drivers currently + provide at least the following fuctions: + + usb_lowlevel_init() ... Do the initialization of the USB controller hardware + usb_lowlevel_stop() ... Do the shutdown of the USB controller hardware + + usb_event_poll() ...... Poll interrupt from USB device, often used by KBD + + submit_control_msg() .. Submit message via Control endpoint + submit_int_msg() ...... Submit message via Interrupt endpoint + submit_bulk_msg() ..... Submit message via Bulk endpoint + + + This allows for the host driver to be easily abstracted. + + 2) The USB hierarchy + -------------------- + + In the current implementation, the USB Host driver provides operations to + communicate via the USB bus. This is realised by providing access to a USB + root port to which an USB root hub is attached. The USB bus is scanned and for + each newly found device, a struct usb_device is allocated. See common/usb.c + and include/usb.h for details. + +II) Approach +------------ + + 1) The USB Host driver + ---------------------- + + Converting the host driver will follow the classic driver model consideration. + Though, the host driver will have to call a function that registers a root + port with the USB core in it's probe() function, let's call this function + + usb_register_root_port(&ops); + + This will allow the USB core to track all available root ports. The ops + parameter will contain structure describing operations supported by the root + port: + + struct usb_port_ops { + void (*usb_event_poll)(); + int (*submit_control_msg)(); + int (*submit_int_msg)(); + int (*submit_bulk_msg)(); + } + + 2) The USB hierarchy and hub drivers + ------------------------------------ + + Converting the USB heirarchy should be fairy simple, considering the already + dynamic nature of the implementation. The current usb_hub_device structure + will have to be converted to a struct instance. Every such instance will + contain components of struct usb_device and struct usb_hub_device in it's + private data, providing only accessors in order to properly encapsulate the + driver. + + By registering the root port, the USB framework will instantiate a USB hub + driver, which is always present, the root hub. The root hub and any subsequent + hub instance is represented by struct instance and it's private data contain + amongst others common bits from struct usb_device. + + Note the USB hub driver is partly defying the usual method of registering a + set of callbacks to a particular core driver. Instead, a static set of + functions is defined and the USB hub instance is passed to those. This creates + certain restrictions as of how the USB hub driver looks, but considering the + specification for USB hub is given and a different type of USB hub won't ever + exist, this approach is ok: + + - Report how many ports does this hub have: + uint get_nr_ports(struct instance *hub); + - Get pointer to device connected to a port: + struct instance *(*get_child)(struct instance *hub, int port); + - Instantiate and configure device on port: + struct instance *(*enum_dev_on_port)(struct instance *hub, int port); + + 3) USB device drivers + --------------------- + + The USB device driver, in turn, will have to register various ops structures + with certain cores. For example, USB disc driver will have to register it's + ops with core handling USB discs etc. diff --git a/doc/driver-model/UDM-video.txt b/doc/driver-model/UDM-video.txt new file mode 100644 index 0000000..342aeee --- /dev/null +++ b/doc/driver-model/UDM-video.txt @@ -0,0 +1,74 @@ +The U-Boot Driver Model Project +=============================== +Video output analysis +===================== +Marek Vasut +2012-02-20 + +I) Overview +----------- + +The video drivers are most often registered with video subsystem. This subsystem +often expects to be allowed access to framebuffer of certain parameters. This +subsystem also provides calls for STDIO subsystem to allow it to output +characters on the screen. For this part, see [ UDM-stdio.txt ]. + +Therefore the API has two parts, the video driver part and the part where the +video driver core registers with STDIO API. + +The video driver part will follow the current cfb_console approach, though +allowing it to be more dynamic. + +II) Approach +------------ + +Registering the video driver into the video driver core is done by calling the +following function from the driver probe() function: + + video_device_register(struct instance *i, GraphicDevice *gd); + +Because the video driver core is in charge or rendering characters as well as +bitmaps on the screen, it will in turn call stdio_device_register(i, so), where +"i" is the same instance as the video driver's one. But "so" will be special +static struct stdio_device_ops handling the character output. + + +III) Analysis of in-tree drivers +-------------------------------- + + 1) arch/powerpc/cpu/mpc8xx/video.c + ---------------------------------- + This driver copies the cfb_console [ see drivers/video/cfb_console.c ] + approach and acts only as a STDIO device. Therefore there are currently two + possible approaches, first being the conversion of this driver to usual STDIO + device and second, long-term one, being conversion of this driver to video + driver that provides console. + + 2) arch/x86/lib/video.c + ----------------------- + This driver registers two separate STDIO devices and should be therefore + converted as such. + + 3) board/bf527-ezkit/video.c + ---------------------------- + This driver seems bogus as it behaves as STDIO device, but provides no input + or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use + or present otherwise than as a dead code/define. + + 4) board/bf533-stamp/video.c + ---------------------------- + This driver seems bogus as it behaves as STDIO device, but provides no input + or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use + or present otherwise than as a dead code/define. + + 5) board/bf548-ezkit/video.c + ---------------------------- + This driver seems bogus as it behaves as STDIO device, but provides no input + or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use + or present otherwise than as a dead code/define. + + 6) board/cm-bf548/video.c + ---------------------------- + This driver seems bogus as it behaves as STDIO device, but provides no input + or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use + or present otherwise than as a dead code/define. -- cgit v1.1 From 3f4669334d3bfd795777c18423765210b9180278 Mon Sep 17 00:00:00 2001 From: Pavel Herrmann Date: Wed, 8 Aug 2012 01:42:18 +0000 Subject: dm: Add Driver cores design document Signed-off-by: Pavel Herrmann --- doc/driver-model/UDM-cores.txt | 126 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 doc/driver-model/UDM-cores.txt diff --git a/doc/driver-model/UDM-cores.txt b/doc/driver-model/UDM-cores.txt new file mode 100644 index 0000000..4e13188 --- /dev/null +++ b/doc/driver-model/UDM-cores.txt @@ -0,0 +1,126 @@ +The U-Boot Driver Model Project +=============================== +Driver cores API document +========================= + +Pavel Herrmann + +1) Overview +----------- + Driver cores will be used as a wrapper for devices of the same type, and as + an abstraction for device driver APIs. For each driver API (which roughly + correspond to device types), there will be one driver core. Each driver core + will implement three APIs - a driver API (which will be the same as API of + drivers the core wraps around), a core API (which will be implemented by all + cores) and a command API (core-specific API which will be exposed to + commands). + + A) Command API + The command API will provide access to shared functionality for a specific + device, which is currently located mostly in commands. Commands will be + rewritten to be more lightweight by using this API. As this API will be + different for each core, it is out of scope of this document. + + B) Driver API + The driver API will act as a wrapper around actual device drivers, + providing a single entrypoint for device access. All functions in this API + have an instance* argument (probably called "this" or "i"), which will be + examined by the core, and a correct function for the specified driver will + get called. + + If the core gets called with a group instance pointer (as discussed in + design), it will automatically select the instance that is associated + with this core, and use it as target of the call. if the group contains + multiple instances of a single type, the caller must explicitly use an + accessor to select the correct instance. + + This accessor will look like: + struct instance *get_instance_from_group(struct instance *group, int i) + + When called with a non-group instance, it will simply return the instance. + + C) Core API + The core API will be implemented by all cores, and will provide + functionality for getting driver instances from non-driver code. This API + will consist of following functions: + + int get_count(struct instance *core); + struct instance* get_instance(struct instance *core, int index); + int init(struct instance *core); + int bind(struct instance *core, struct instance *dev, void *ops, + void *hint); + int unbind(struct instance *core, instance *dev); + int replace(struct instance *core, struct_instance *new_dev, + struct instance *old_dev); + int destroy(struct instance *core); + int reloc(struct instance *new_core, struct instance *old_core); + + The 'hint' parameter of bind() serves for additional data a driver can + pass to the core, to help it create the correct internal state for this + instance. the replace() function will get called during instance + relocation, and will replace the old instance with the new one, keeping + the internal state untouched. + + +2) Lifetime of a driver core +---------------------------- + Driver cores will be initialized at runtime, to limit memory footprint in + early-init stage, when we have to fit into ~1KB of memory. All active cores + will be stored in a tree structure (referenced as "Core tree") in global data, + which provides good tradeoff between size and access time. + Every core will have a number constant associated with it, which will be used + to find the instance in Core tree, and to refer to the core in all calls + working with the Core tree. + The Core Tree should be implemented using B-tree (or a similar structure) + to guarantee acceptable time overhead in all cases. + + Code for working with the core (i2c in this example) follows: + + core_init(CORE_I2C); + This will check whether we already have a i2c core, and if not it creates + a new instance and adds it into the Core tree. This will not be exported, + all code should depend on get_core_instance to init the core when + necessary. + + get_core_instance(CORE_I2C); + This is an accessor into the Core tree, which will return the instance + of i2c core, creating it if necessary + + core_bind(CORE_I2C, instance, driver_ops); + This will get called in bind() function of a driver, and will add the + instance into cores internal list of devices. If the core is not found, it + will get created. + + driver_activate(instance *inst); + This call will recursively activate all devices necessary for using the + specified device. the code could be simplified as: + { + if (is_activated(inst)) + return; + driver_activate(inst->bus); + get_driver(inst)->probe(inst); + } + + The case with multiple parents will need to be handled here as well. + get_driver is an accessor to available drivers, which will get struct + driver based on a name in the instance. + + i2c_write(instance *inst, ...); + An actual call to some method of the driver. This code will look like: + { + driver_activate(inst); + struct instance *core = get_core_instance(CORE_I2C); + device_ops = get_ops(inst); + device_ops->write(...); + } + + get_ops will not be an exported function, it will be internal and specific + to the core, as it needs to know how are the ops stored, and what type + they are. + + Please note that above examples represent the algorithm, not the actual code, + as they are missing checks for validity of return values. + + core_init() function will get called the first time the core is requested, + either by core_link() or core_get_instance(). This way, the cores will get + created only when they are necessary, which will reduce our memory footprint. -- cgit v1.1 From 68bce384f44a15ebaa6f9441c713703e92c8bb94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20K=C5=99iv=C3=A1k?= Date: Wed, 8 Aug 2012 13:42:19 +0200 Subject: dm: Add GPIO API transition document MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Viktor Křivák --- doc/driver-model/UDM-gpio.txt | 106 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 doc/driver-model/UDM-gpio.txt diff --git a/doc/driver-model/UDM-gpio.txt b/doc/driver-model/UDM-gpio.txt new file mode 100644 index 0000000..8ff0a96 --- /dev/null +++ b/doc/driver-model/UDM-gpio.txt @@ -0,0 +1,106 @@ +The U-Boot Driver Model Project +=============================== +GPIO analysis +============= +Viktor Krivak +2012-02-24 + +I) Overview +----------- + + At this moment U-Boot provides standard API that consists of 7 functions. + + int gpio_request(unsigned gpio, const char *label) + int gpio_free(unsigned gpio) + int gpio_direction_input(unsigned gpio) + int gpio_direction_output(unsigned gpio, int value) + int gpio_get_value(unsigned gpio) + void gpio_set_value(unsigned gpio, int value) + + Methods "gpio_request()" and "gpio_free()" are used for claiming and releasing + GPIOs. First one should check if the desired pin exists and if the pin wasn't + requested already elsewhere. The method also has a label argument that can be + used for debug purposes. The label argument should be copied into the internal + memory, but only if the DEBUG macro is set. The "gpio_free()" is the exact + opposite. It releases the particular pin. Other methods are used for setting + input or output direction and obtaining or setting values of the pins. + +II) Approach +------------ + + 1) Request and free GPIO + ------------------------ + + The "gpio_request()" implementation is basically the same for all boards. + The function checks if the particular GPIO is correct and checks if the + GPIO pin is still free. If the conditions are met, the method marks the + GPIO claimed in it's internal structure. If macro DEBUG is defined, the + function also copies the label argument to the structure. If the pin is + already locked, the function returns -1 and if DEBUG is defined, certain + debug output is generated, including the contents of the label argument. + The "gpio_free()" function releases the lock and eventually deallocates + data used by the copied label argument. + + 2) Internal data + ---------------- + + Internal data are driver specific. They have to contain some mechanism to + realise the locking though. This can be done for example using a bit field. + + 3) Operations provided by the driver + ------------------------------------ + + The driver operations basically meet API that is already defined and used. + Except for "gpio_request()" and "gpio_free()", all methods can be converted in + a simple manner. The driver provides the following structure: + + struct gpio_driver_ops { + int (*gpio_request)(struct instance *i, unsigned gpio, + const char *label); + int (*gpio_free)(struct instance *i, unsigned gpio); + int (*gpio_direction_input)(struct instance *i, unsigned gpio); + int (*gpio_direction_output)(struct instance *i, unsigned gpio, + int value); + int (*gpio_get_value)(struct instance *i, unsigned gpio); + void (*gpio_set_value)(struct instance *i, unsigned gpio, int value); + } + +III) Analysis of in-tree drivers +-------------------------------- + + 1) altera_pio.c + --------------- + Meets standard API. Implements gpio_request() properly. Simple conversion + possible. + + 2) at91_gpio.c + -------------- + Don't meet standard API. Need some other methods to implement. + + 3) da8xx_gpio.c + --------------- + Meets standard API. Implements gpio_request() properly. Simple conversion + possible. + + 4) kw_gpio.c + ------------ + Doesn't meet standard API. Needs some other methods to implement and move some + methods to another file. + + 5) mpc83xx_gpio.c + ----------------- + Meets standard API. Doesn't implement gpio_request() properly (only checks + if the pin is valid). Simple conversion possible. + + 6) mvgpio.c + ----------- + Meets standard API. Doesn't implement gpio_request() properly (only checks + if the pin is valid). Simple conversion possible. + + 7) mvgpio.h + ----------- + Wrong placement. Will be moved to another location. + + 8) mvmfp.c + ---------- + Wrong placement. Will be moved to another location. -- cgit v1.1 From 25681826740a3fda9176ae8e63bc957579e9b288 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 8 Aug 2012 01:42:20 +0000 Subject: dm: Add MMC subsystem analysis Signed-off-by: Marek Vasut --- doc/driver-model/UDM-mmc.txt | 319 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 319 insertions(+) create mode 100644 doc/driver-model/UDM-mmc.txt diff --git a/doc/driver-model/UDM-mmc.txt b/doc/driver-model/UDM-mmc.txt new file mode 100644 index 0000000..bed4306 --- /dev/null +++ b/doc/driver-model/UDM-mmc.txt @@ -0,0 +1,319 @@ +The U-Boot Driver Model Project +=============================== +MMC system analysis +=================== +Marek Vasut +2012-02-25 + +I) Overview +----------- + +The MMC subsystem is already quite dynamic in it's nature. It's only necessary +to flip the subsystem to properly defined API. + +The probing process of MMC drivers start by calling "mmc_initialize()", +implemented by MMC framework, from the architecture initialization file. The +"mmc_initialize()" function in turn calls "board_mmc_init()" function and if +this doesn't succeed, "cpu_mmc_init()" function is called. It is important to +note that both of the "*_mmc_init()" functions have weak aliases to functions +which automatically fail. + +Both of the "*_mmc_init()" functions though serve only one purpose. To call +driver specific probe function, which in turn actually registers the driver with +MMC subsystem. Each of the driver specific probe functions is currently done in +very ad-hoc manner. + +The registration with the MMC subsystem is done by calling "mmc_register()", +whose argument is a runtime configured structure of information about the MMC +driver. Currently, the information structure is intermixed with driver's internal +data. The description of the structure follows: + +struct mmc { + /* + * API: Allows this driver to be a member of the linked list of all MMC drivers + * registered with MMC subsystem + */ + struct list_head link; + + /* DRIVER: Name of the registered driver */ + char name[32]; + + /* DRIVER: Driver's private data */ + void *priv; + + /* DRIVER: Voltages the host bus can provide */ + uint voltages; + + /* API: Version of the card */ + uint version; + + /* API: Test if the driver was already initialized */ + uint has_init; + + /* DRIVER: Minimum frequency the host bus can provide */ + uint f_min; + + /* DRIVER: Maximum frequency the host bus can provide */ + uint f_max; + + /* API: Is the card SDHC */ + int high_capacity; + + /* API: Actual width of the bus used by the current card */ + uint bus_width; + + /* + * DRIVER: Clock frequency to be configured on the host bus, this is read-only + * for the driver. + */ + uint clock; + + /* API: Capabilities of the card */ + uint card_caps; + + /* DRIVER: MMC bus capabilities */ + uint host_caps; + + /* API: Configuration and ID data retrieved from the card */ + uint ocr; + uint scr[2]; + uint csd[4]; + uint cid[4]; + ushort rca; + + /* API: Partition configuration */ + char part_config; + + /* API: Number of partitions */ + char part_num; + + /* API: Transmission speed */ + uint tran_speed; + + /* API: Read block length */ + uint read_bl_len; + + /* API: Write block length */ + uint write_bl_len; + + /* API: Erase group size */ + uint erase_grp_size; + + /* API: Capacity of the card */ + u64 capacity; + + /* API: Descriptor of this block device */ + block_dev_desc_t block_dev; + + /* DRIVER: Function used to submit command to the card */ + int (*send_cmd)(struct mmc *mmc, + struct mmc_cmd *cmd, struct mmc_data *data); + + /* DRIVER: Function used to configure the host */ + void (*set_ios)(struct mmc *mmc); + + /* DRIVER: Function used to initialize the host */ + int (*init)(struct mmc *mmc); + + /* DRIVER: Function used to report the status of Card Detect pin */ + int (*getcd)(struct mmc *mmc); + + /* + * DRIVER: Maximum amount of blocks sent during multiblock xfer, + * set to 0 to autodetect. + */ + uint b_max; +}; + +The API above is the new API used by most of the drivers. There're still drivers +in the tree that use old, legacy API though. + +2) Approach +----------- + +To convert the MMC subsystem to a proper driver model, the "struct mmc" +structure will have to be properly split in the first place. The result will +consist of multiple parts, first will be the structure defining operations +provided by the MMC driver: + +struct mmc_driver_ops { + /* Function used to submit command to the card */ + int (*send_cmd)(struct mmc *mmc, + struct mmc_cmd *cmd, struct mmc_data *data); + /* DRIVER: Function used to configure the host */ + void (*set_ios)(struct mmc *mmc); + /* Function used to initialize the host */ + int (*init)(struct mmc *mmc); + /* Function used to report the status of Card Detect pin */ + int (*getcd)(struct mmc *mmc); +} + +The second part will define the parameters of the MMC driver: + +struct mmc_driver_params { + /* Voltages the host bus can provide */ + uint32_t voltages; + /* Minimum frequency the host bus can provide */ + uint32_t f_min; + /* Maximum frequency the host bus can provide */ + uint32_t f_max; + /* MMC bus capabilities */ + uint32_t host_caps; + /* + * Maximum amount of blocks sent during multiblock xfer, + * set to 0 to autodetect. + */ + uint32_t b_max; +} + +And finally, the internal per-card data of the MMC subsystem core: + +struct mmc_card_props { + /* Version of the card */ + uint32_t version; + /* Test if the driver was already initializes */ + bool has_init; + /* Is the card SDHC */ + bool high_capacity; + /* Actual width of the bus used by the current card */ + uint8_t bus_width; + /* Capabilities of the card */ + uint32_t card_caps; + /* Configuration and ID data retrieved from the card */ + uint32_t ocr; + uint32_t scr[2]; + uint32_t csd[4]; + uint32_t cid[4]; + uint16_t rca; + /* Partition configuration */ + uint8_t part_config; + /* Number of partitions */ + uint8_t part_num; + /* Transmission speed */ + uint32_t tran_speed; + /* Read block length */ + uint32_t read_bl_len; + /* Write block length */ + uint32_t write_bl_len; + /* Erase group size */ + uint32_t erase_grp_size; + /* Capacity of the card */ + uint64_t capacity; + /* Descriptor of this block device */ + block_dev_desc_t block_dev; +} + +The probe() function will then register the MMC driver by calling: + + mmc_device_register(struct instance *i, struct mmc_driver_ops *o, + struct mmc_driver_params *p); + +The struct mmc_driver_params will have to be dynamic in some cases, but the +driver shouldn't modify it's contents elsewhere than in probe() call. + +Next, since the MMC drivers will now be consistently registered into the driver +tree from board file, the functions "board_mmc_init()" and "cpu_mmc_init()" will +disappear altogether. + +As for the legacy drivers, these will either be converted or removed altogether. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) arm_pl180_mmci.c + ------------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 2) atmel_mci.c + -------------- + This driver uses the legacy API and should be removed unless converted. It is + probably possbible to replace this driver with gen_atmel_mci.c . No conversion + will be done on this driver. + + 3) bfin_sdh.c + ------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 4) davinci_mmc.c + ---------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 5) fsl_esdhc.c + -------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple, unless some problem appears due to the FDT + component of the driver. + + 6) ftsdc010_esdhc.c + ------------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 7) gen_atmel_mci.c + ------------------ + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 8) mmc_spi.c + ------------ + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 9) mv_sdhci.c + ------------- + This is a component of the SDHCI support, allowing it to run on Marvell + Kirkwood chip. It is probable the SDHCI support will have to be modified to + allow calling functions from this file based on information passed via + platform_data. + + 10) mxcmmc.c + ------------ + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 11) mxsmmc.c + ------------ + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 12) omap_hsmmc.c + ---------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 13) pxa_mmc.c + ------------- + This driver uses the legacy API and is written in a severely ad-hoc manner. + This driver will be removed in favor of pxa_mmc_gen.c, which is proved to work + better and is already well tested. No conversion will be done on this driver + anymore. + + 14) pxa_mmc_gen.c + ----------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 15) s5p_mmc.c + ------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 16) sdhci.c + ----------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple, though it'd be necessary to modify this driver + to also support the Kirkwood series and probably also Tegra series of CPUs. + See the respective parts of this section for details. + + 17) sh_mmcif.c + -------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. + + 18) tegra2_mmc.c + ---------------- + Follows the new API and also has a good encapsulation of the whole driver. The + conversion here will be simple. -- cgit v1.1 From b59d2802d22213c87f64c4839ac1cbf825258bea Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 8 Aug 2012 01:42:21 +0000 Subject: dm: Add networking subsystem analysis Signed-off-by: Marek Vasut --- doc/driver-model/UDM-net.txt | 434 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 434 insertions(+) create mode 100644 doc/driver-model/UDM-net.txt diff --git a/doc/driver-model/UDM-net.txt b/doc/driver-model/UDM-net.txt new file mode 100644 index 0000000..e2ea8f5 --- /dev/null +++ b/doc/driver-model/UDM-net.txt @@ -0,0 +1,434 @@ +The U-Boot Driver Model Project +=============================== +Net system analysis +=================== +Marek Vasut +2012-03-03 + +I) Overview +----------- + +The networking subsystem already supports multiple devices. Therefore the +conversion shall not be very hard. + +The network subsystem is operated from net/eth.c, which tracks all registered +ethernet interfaces and calls their particular functions registered via +eth_register(). + +The eth_register() is called from the network driver initialization function, +which in turn is called most often either from "board_net_init()" or +"cpu_net_init()". This function has one important argument, which is the +"struct eth_device", defined at include/net.h: + +struct eth_device { + /* DRIVER: Name of the device */ + char name[NAMESIZE]; + /* DRIVER: MAC address */ + unsigned char enetaddr[6]; + /* DRIVER: Register base address */ + int iobase; + /* CORE: state of the device */ + int state; + + /* DRIVER: Device initialization function */ + int (*init) (struct eth_device*, bd_t*); + /* DRIVER: Function for sending packets */ + int (*send) (struct eth_device*, volatile void* packet, int length); + /* DRIVER: Function for receiving packets */ + int (*recv) (struct eth_device*); + /* DRIVER: Function to cease operation of the device */ + void (*halt) (struct eth_device*); + /* DRIVER: Function to send multicast packet (OPTIONAL) */ + int (*mcast) (struct eth_device*, u32 ip, u8 set); + /* DRIVER: Function to change ethernet MAC address */ + int (*write_hwaddr) (struct eth_device*); + /* CORE: Next device in the linked list of devices managed by net core */ + struct eth_device *next; + /* CORE: Device index */ + int index; + /* DRIVER: Driver's private data */ + void *priv; +}; + +This structure defines the particular driver, though also contains elements that +should not be exposed to the driver, like core state. + +Small, but important part of the networking subsystem is the PHY management +layer, whose drivers are contained in drivers/net/phy. These drivers register in +a very similar manner to network drivers, by calling "phy_register()" with the +argument of "struct phy_driver": + +struct phy_driver { + /* DRIVER: Name of the PHY driver */ + char *name; + /* DRIVER: UID of the PHY driver */ + unsigned int uid; + /* DRIVER: Mask for UID of the PHY driver */ + unsigned int mask; + /* DRIVER: MMDS of the PHY driver */ + unsigned int mmds; + /* DRIVER: Features the PHY driver supports */ + u32 features; + /* DRIVER: Initialize the PHY hardware */ + int (*probe)(struct phy_device *phydev); + /* DRIVER: Reconfigure the PHY hardware */ + int (*config)(struct phy_device *phydev); + /* DRIVER: Turn on the PHY hardware, allow it to send/receive */ + int (*startup)(struct phy_device *phydev); + /* DRIVER: Turn off the PHY hardware */ + int (*shutdown)(struct phy_device *phydev); + /* CORE: Allows this driver to be part of list of drivers */ + struct list_head list; +}; + +II) Approach +------------ + +To convert the elements of network subsystem to proper driver model method, the +"struct eth_device" will have to be split into multiple components. The first +will be a structure defining the driver operations: + +struct eth_driver_ops { + int (*init)(struct instance*, bd_t*); + int (*send)(struct instance*, void *packet, int length); + int (*recv)(struct instance*); + void (*halt)(struct instance*); + int (*mcast)(struct instance*, u32 ip, u8 set); + int (*write_hwaddr)(struct instance*); +}; + +Next, there'll be platform data which will be per-driver and will replace the +"priv" part of "struct eth_device". Last part will be the per-device core state. + +With regards to the PHY part of the API, the "struct phy_driver" is almost ready +to be used with the new driver model approach. The only change will be the +replacement of per-driver initialization functions and removal of +"phy_register()" function in favor or driver model approach. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) drivers/net/4xx_enet.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 2) drivers/net/altera_tse.c + --------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 3) drivers/net/armada100_fec.c + ------------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 4) drivers/net/at91_emac.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 5) drivers/net/ax88180.c + ------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 6) drivers/net/ax88796.c + ------------------------ + + This file contains a components of the NE2000 driver, implementing only + different parts on the NE2000 clone AX88796. This being no standalone driver, + no conversion will be done here. + + 7) drivers/net/bfin_mac.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 8) drivers/net/calxedaxgmac.c + ----------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 9) drivers/net/cs8900.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 10) drivers/net/davinci_emac.c + ------------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 11) drivers/net/dc2114x.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 12) drivers/net/designware.c + ---------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 13) drivers/net/dm9000x.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 14) drivers/net/dnet.c + ---------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 15) drivers/net/e1000.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 16) drivers/net/e1000_spi.c + --------------------------- + + Driver for the SPI bus integrated on the Intel E1000. This is not part of the + network stack. + + 17) drivers/net/eepro100.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 18) drivers/net/enc28j60.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 19) drivers/net/ep93xx_eth.c + ---------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 20) drivers/net/ethoc.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 21) drivers/net/fec_mxc.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 22) drivers/net/fsl_mcdmafec.c + ------------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 23) drivers/net/fsl_mdio.c + -------------------------- + + This file contains driver for FSL MDIO interface, which is not part of the + networking stack. + + 24) drivers/net/ftgmac100.c + --------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 25) drivers/net/ftmac100.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 26) drivers/net/greth.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 27) drivers/net/inca-ip_sw.c + ---------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 28) drivers/net/ks8695eth.c + --------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 29) drivers/net/lan91c96.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 30) drivers/net/macb.c + ---------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 31) drivers/net/mcffec.c + ------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 32) drivers/net/mcfmii.c + ------------------------ + + This file contains MII interface driver for MCF FEC. + + 33) drivers/net/mpc512x_fec.c + ----------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 34) drivers/net/mpc5xxx_fec.c + ----------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 35) drivers/net/mvgbe.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 36) drivers/net/natsemi.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 37) drivers/net/ne2000_base.c + ----------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. This driver contains the core + implementation of NE2000, which needs a few external functions, implemented by + AX88796, NE2000 etc. + + 38) drivers/net/ne2000.c + ------------------------ + + This file implements external functions necessary for native NE2000 compatible + networking card to work. + + 39) drivers/net/netarm_eth.c + ---------------------------- + + This driver uses the old, legacy, network API and will either have to be + converted or removed. + + 40) drivers/net/netconsole.c + ---------------------------- + + This is actually an STDIO driver. + + 41) drivers/net/ns8382x.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 42) drivers/net/pcnet.c + ----------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 43) drivers/net/plb2800_eth.c + ----------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 44) drivers/net/rtl8139.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 45) drivers/net/rtl8169.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 46) drivers/net/sh_eth.c + ------------------------ + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 47) drivers/net/smc91111.c + -------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 48) drivers/net/smc911x.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 49) drivers/net/tsec.c + ---------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 50) drivers/net/tsi108_eth.c + ---------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 51) drivers/net/uli526x.c + ------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 52) drivers/net/vsc7385.c + ------------------------- + + This is a driver that only uploads firmware to a switch. This is not subject + of conversion. + + 53) drivers/net/xilinx_axi_emac.c + --------------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. + + 54) drivers/net/xilinx_emaclite.c + --------------------------------- + + This driver uses the standard new networking API, therefore there should be no + obstacles throughout the conversion process. -- cgit v1.1 From 707a5e2226a3dac8aa56ac236aff5e03b7625b2c Mon Sep 17 00:00:00 2001 From: Viktor Krivak Date: Wed, 8 Aug 2012 01:42:22 +0000 Subject: dm: Add SPI API transition document Signed-off-by: Viktor Krivak --- doc/driver-model/UDM-spi.txt | 200 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 doc/driver-model/UDM-spi.txt diff --git a/doc/driver-model/UDM-spi.txt b/doc/driver-model/UDM-spi.txt new file mode 100644 index 0000000..7442a32 --- /dev/null +++ b/doc/driver-model/UDM-spi.txt @@ -0,0 +1,200 @@ +The U-Boot Driver Model Project +=============================== +SPI analysis +============ +Viktor Krivak +2012-03-03 + +I) Overview +----------- + + 1) The SPI driver + ----------------- + + At this moment U-Boot provides standard API that consist of 7 functions: + + void spi_init(void); + struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode); + void spi_free_slave(struct spi_slave *slave); + int spi_claim_bus(struct spi_slave *slave); + void spi_release_bus(struct spi_slave *slave); + int spi_xfer(struct spi_slave *slave, unsigned int bitlen, + const void *dout, void *din, unsigned long flags); + int spi_cs_is_valid(unsigned int bus, unsigned int cs); + void spi_cs_activate(struct spi_slave *slave); + void spi_cs_deactivate(struct spi_slave *slave); + void spi_set_speed(struct spi_slave *slave, uint hz); + + Method spi_init() is usually empty. All necessary configuration are sets by + spi_setup_slave(). But this configuration is usually stored only in memory. + No real hardware sets are made. All hardware settings are provided by method + spi_claim_bus(). This method claims the bus and it can't be claimed again + until it's release. That's mean all calls of method spi_claim_bus() will + fail. But lots of cpu implementation don't meet this behaviour. + Method spi_release_bus() does exact opposite. It release bus directly by + some hardware sets. spi_free_slave() only free memory allocated by + spi_setup_slave(). Method spi_xfer() do actually read and write operation + throw specified bus and cs. Other methods are self explanatory. + + 2) Current limitations + ---------------------- + + Theoretically at this moment api allows use more then one bus per device at + the time. But in real this can be achieved only when all buses have their + own base addresses in memory. + + +II) Approach +------------ + + 1) Claiming bus + --------------- + + The current api cannot be used because struct spi_slave have to be in + private data. In that case user are prohibited to use different bus on one + device at same time. But when base memory address for bus are different. + It's possible make more instance of this driver. Otherwise it can't can be + done because of hardware limitation. + + 2) API change + ------------- + + Method spi_init() is moved to probe. Methods spi_setup_slave() and + spi_claim_bus() are joined to one method. This method checks if desired bus + exists and is available then configure necessary hardware and claims bus. + Method spi_release_bus() and spi_free_slave() are also joined to meet this + new approach. Other function remain same. Only struct spi_slave was change + to instance. + + struct ops { + int (*spi_request_bus)(struct instance *i, unsigned int bus, + unsigned int cs, unsigned int max_hz, + unsigned int mode); + void (*spi_release_bus)(struct instance *i); + int (*spi_xfer) (struct instance *i, unsigned int bitlen, + const void *dout, void *din, unsigned long flags); + int (*spi_cs_is_valid)(struct instance *i, unsigned int bus, + unsigned int cs); + void (*spi_cs_activate)(struct instance *i); + void (*spi_cs_deactivate)(struct instance *i); + void (*spi_set_speed)(struct instance *i, uint hz); + } + + 3) Legacy API + ------------- + + To easy conversion of the whole driver. Original and new api can exist next + to each other. New API is designed to be only a wrapper that extracts + necessary information from private_data and use old api. When driver can + use more than one bus at the time. New API require multiple instance. One + for each bus. In this case spi_slave have to be copied in each instance. + + 4) Conversion TIME-LINE + ----------------------- + + To prevent build corruption api conversion have to be processed in several + independent steps. In first step all old API methods are renamed. After that + new API and core function are implemented. Next step is conversion of all + board init methods to set platform data. After all these steps it is possible + to start conversion of all remaining calls. This procedure guarantees that + build procedure and binaries are never broken. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) altera_spi.c + --------------- + All methods have designated structure. Simple conversion possible. + + 2) andes_spi.c + -------------- + All methods have designated structure. Simple conversion possible. + + 3) andes_spi.h + -------------- + Support file for andes_spi.c. No conversion is needed. + + 4) armada100_spi.c + ------------------ + All methods have designated structure. Simple conversion possible. + + 5) atmel_dataflash_spi.c + ------------------------ + Wrong placement. Will be moved to another location. + + 6) atmel_spi.c + -------------- + Supports more than one bus. Need some minor change. + + 7) atmel_spi.h + -------------- + Support file for andes_spi.c. No conversion is needed. + + 8) bfin_spi.c + ------------- + Supports more than one bus. Need some minor change. + + 9) cf_spi.c + ----------- + Cooperate with some cpu specific methods from other files. Hard conversion. + + 10) davinci_spi.c + ----------------- + All methods have designated structure. Simple conversion possible. + + 11) davinci_spi.h + ----------------- + Support file for davinci_spi.h. No conversion is needed. + + 12) fsl_espi.c + -------------- + All methods have designated structure. Simple conversion possible. + + 13) kirkwood_spi.c + ------------------ + All methods have designated structure. Simple conversion possible. + + 14) mpc8xxx_spi.c + ----------------- + All methods have designated structure. Simple conversion possible. + + 15) mpc52xx_spi.c + ----------------- + All methods have designated structure. Simple conversion possible. + + 16) mxc_spi.c + ------------- + All methods have designated structure. Simple conversion possible. + + 17) mxs_spi.c + ------------- + All methods have designated structure. Simple conversion possible. + + 18) oc_tiny_spi.c + ----------------- + Supports more than one bus. Need some minor change. + + 19) omap3_spi.c + --------------- + Supports more than one bus. Need some minor change. + + 20) omap3_spi.h + --------------- + Support file for omap3_spi.c. No conversion is needed. + + 21) sh_spi.c + ------------ + All methods have designated structure. Simple conversion possible. + + 22) sh_spi.h + ------------ + Support file for sh_spi.h. No conversion is needed. + + 23) soft_spi.c + -------------- + Use many board specific method linked from other files. Need careful debugging. + + 24) tegra2_spi.c + ---------------- + Some hardware specific problem when releasing bus. -- cgit v1.1 From 0463574014e28985112d4ea77eaab03d5a340295 Mon Sep 17 00:00:00 2001 From: Pavel Herrmann Date: Wed, 8 Aug 2012 01:42:23 +0000 Subject: dm: Add block device document Signed-off-by: Pavel Herrmann --- doc/driver-model/UDM-block.txt | 279 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 doc/driver-model/UDM-block.txt diff --git a/doc/driver-model/UDM-block.txt b/doc/driver-model/UDM-block.txt new file mode 100644 index 0000000..5d5c776 --- /dev/null +++ b/doc/driver-model/UDM-block.txt @@ -0,0 +1,279 @@ +The U-Boot Driver Model Project +=============================== +Block device subsystem analysis +=============================== + +Pavel Herrmann +2012-03-08 + +I) Overview +----------- + + U-Boot currently implements several distinct APIs for block devices - some + drivers use the SATA API, some drivers use the IDE API, sym53c8xx and + AHCI use the SCSI API, mg_disk has a separate API, and systemace also has a + separate API. There are also MMC and USB APIs used outside of drivers/block, + those will be detailed in their specific documents. + + Block devices are described by block_dev_desc structure, that holds, among + other things, the read/write/erase callbacks. Block device structures are + stored in any way depending on the API, but can be accessed by + + block_dev_desc_t * $api_get_dev(int dev) + + function, as seen in disk/part.c. + + 1) SATA interface + ----------------- + + The SATA interface drivers implement the following functions: + + int init_sata(int dev) + int scan_sata(int dev) + ulong sata_read(int dev, ulong blknr, ulong blkcnt, void *buffer) + ulong sata_write(int dev, ulong blknr, ulong blkcnt, const void *buffer) + + Block devices are kept in sata_dev_desc[], which is prefilled with values + common to all SATA devices in cmd_sata.c, and then modified in init_sata + function in the drivers. Callbacks of the block device use SATA API + directly. The sata_get_dev function is defined in cmd_sata.c. + + 2) SCSI interface + ----------------- + + The SCSI interface drivers implement the following functions: + + void scsi_print_error(ccb *pccb) + int scsi_exec(ccb *pccb) + void scsi_bus_reset(void) + void scsi_low_level_init(int busdevfunc) + + The SCSI API works through the scsi_exec function, the actual operation + requested is found in the ccb structure. + + Block devices are kept in scsi_dev_desc[], which lives only in cmd_scsi.c. + Callbacks of the block device use functions from cmd_scsi.c, which in turn + call scsi_exec of the controller. The scsi_get_dev function is also defined + in cmd_scsi.c. + + 3) mg_disk interface + -------------------- + + The mg_disk interface drivers implement the following functions: + + struct mg_drv_data* mg_get_drv_data (void) + uint mg_disk_init (void) + uint mg_disk_read (u32 addr, u8 *buff, u32 len) + uint mg_disk_write(u32 addr, u8 *buff, u32 len) + uint mg_disk_write_sects(void *buff, u32 sect_num, u32 sect_cnt) + uint mg_disk_read_sects(void *buff, u32 sect_num, u32 sect_cnt) + + The mg_get_drv_data function is to be overridden per-board, but there are no + board in-tree that do this. + + Only one driver for this API exists, and it only supports one block device. + Callbacks for this device are implemented in mg_disk.c and call the mg_disk + API. The mg_disk_get_dev function is defined in mg_disk.c and ignores the + device number, always returning the same device. + + 4) systemace interface + ---------------------- + + The systemace interface does not define any driver API, and has no command + itself. The single defined function is systemace_get_devs() from + systemace.c, which returns a single static structure for the only supported + block device. Callbacks for this device are also implemented in systemace.c. + + 5) IDE interface + ---------------- + + The IDE interface drivers implement the following functions, but only if + CONFIG_IDE_AHB is set: + + uchar ide_read_register(int dev, unsigned int port); + void ide_write_register(int dev, unsigned int port, unsigned char val); + void ide_read_data(int dev, ulong *sect_buf, int words); + void ide_write_data(int dev, ulong *sect_buf, int words); + + The first two functions are called from ide_inb()/ide_outb(), and will + default to direct memory access if CONFIG_IDE_AHB is not set, or + ide_inb()/ide_outb() functions will get overridden by the board altogether. + + The second two functions are called from input_data()/output_data() + functions, and also default to direct memory access, but cannot be + overridden by the board. + + One function shared by IDE drivers (but not defined in ide.h) is + int ide_preinit(void) + This function gets called from ide_init in cmd_ide.c if CONFIG_IDE_PREINIT + is defined, and will do the driver-specific initialization of the device. + + Block devices are kept in ide_dev_desc[], which is filled in cmd_ide.c. + Callbacks of the block device are defined in cmd_ide.c, and use the + ide_inb()/ide_outb()/input_data()/output_data() functions mentioned above. + The ide_get_dev function is defined in cmd_ide.c. + +II) Approach +------------ + + A new block controller core and an associated API will be created to mimic the + current SATA API, its drivers will have the following ops: + + struct block_ctrl_ops { + int scan(instance *i); + int reset(instance *i, int port); + lbaint_t read(instance *i, int port, lbaint_t start, lbatin_t length, + void *buffer); + lbaint_t write(instance *i, int port, lbaint_t start, lbatin_t length, + void*buffer); + } + + The current sata_init() function will be changed into the driver probe() + function. The read() and write() functions should never be called directly, + instead they should be called by block device driver for disks. + + Other block APIs would either be transformed into this API, or be kept as + legacy for old drivers, or be dropped altogether. + + Legacy driver APIs will each have its own driver core that will contain the + shared logic, which is currently located mostly in cmd_* files. Callbacks for + block device drivers will then probably be implemented as a part of the core + logic, and will use the driver ops (which will copy current state of + respective APIs) to do the work. + + All drivers will be cleaned up, most ifdefs should be converted into + platform_data, to enable support for multiple devices with different settings. + + A new block device core will also be created, and will keep track of all + block devices on all interfaces. + + Current block_dev_desc structure will be changed to fit the driver model, all + identification and configuration will be placed in private data, and + a single accessor and modifier will be defined, to accommodate the need for + different sets of options for different interfaces, while keeping the + structure small. The new block device drivers will have the following ops + structure (lbaint_t is either 32bit or 64bit unsigned, depending on + CONFIG_LBA48): + + struct blockdev_ops { + lbaint_t (*block_read)(struct instance *i, lbaint_t start, lbaint_t blkcnt, + void *buffer); + lbaint_t (*block_write)(struct instance *i, lbaint_t start, lbaint_t blkcnt, + void *buffer); + lbaint_t (*block_erase)(struct instance *i, lbaint_t start, lbaint_t blkcnt + ); + int (*get_option)(struct instance *i, enum blockdev_option_code op, + struct option *res); + int (*set_option)(struct instance *i, enum blockdev_option_code op, + struct option *val); + } + + struct option { + uint32_t flags + union data { + uint64_t data_u; + char* data_s; + void* data_p; + } + } + + enum blockdev_option_code { + BLKD_OPT_IFTYPE=0, + BLKD_OPT_TYPE, + BLKD_OPT_BLOCKSIZE, + BLKD_OPT_BLOCKCOUNT, + BLKD_OPT_REMOVABLE, + BLKD_OPT_LBA48, + BLKD_OPT_VENDOR, + BLKD_OPT_PRODICT, + BLKD_OPT_REVISION, + BLKD_OPT_SCSILUN, + BLKD_OPT_SCSITARGET, + BLKD_OPT_OFFSET + } + + Flags in option above will contain the type of returned data (which should be + checked against what is expected, even though the option requested should + specify it), and a flag to indicate whether the returned pointer needs to be + free()'d. + + The block device core will contain the logic now located in disk/part.c and + related files, and will be used to forward requests to block devices. The API + for the block device core will copy the ops of a block device (with a string + identifier instead of instance pointer). This means that partitions will also + be handled by the block device core, and exported as block devices, making + them transparent to the rest of the code. + + Sadly, this will change how file systems can access the devices, and thus will + affect a lot of places. However, these changes should be localized and easy to + implement. + + AHCI driver will be rewritten to fit the new unified block controller API, + making SCSI API easy to merge with sym53c8xx, or remove it once the device + driver has died. + + Optionally, IDE core may be changed into one driver with unified block + controller API, as most of it is already in one place and device drivers are + just sets of hooks. Additionally, mg_disk driver is unused and may be removed + in near future. + + + +III) Analysis of in-tree drivers +-------------------------------- + + 1) ahci.c + --------- + SCSI API, will be rewritten for a different API. + + 2) ata_piix.c + ------------- + SATA API, easy to port. + + 3) fsl_sata.c + ------------- + SATA API, few CONFIG macros, easy to port. + + 4) ftide020.c + ------------- + IDE API, defines CONFIG_IDE_AHB and ide_preinit hook functions. + + 5) mg_disk.c + ------------ + Single driver with mg_disk API, not much to change, easy to port. + + 6) mvsata_ide.c + --------------- + IDE API, only defines ide_preinit hook function. + + 7) mxc_ata.c + ------------ + IDE API, only defines ide_preinit hook function. + + 8) pata_bfin.c + -------------- + SATA API, easy to port. + + 9) sata_dwc.c + ------------- + SATA API, easy to port. + + 10) sata_sil3114.c + ------------------ + SATA API, easy to port. + + 11) sata_sil.c + -------------- + SATA API, easy to port. + + 12) sil680.c + ------------ + IDE API, only defines ide_preinit hook function. + + 13) sym53c8xx.c + --------------- + SCSI API, may be merged with code from cmd_scsi. + + 14) systemace.c + --------------- + Single driver with systemace API, not much to change, easy to port. -- cgit v1.1 From 6246fdb05564410a6fe4ace23a5b4bccd0062cd8 Mon Sep 17 00:00:00 2001 From: Viktor Krivak Date: Wed, 8 Aug 2012 01:42:24 +0000 Subject: dm: Add POWER API transition document Signed-off-by: Viktor Krivak --- doc/driver-model/UDM-power.txt | 88 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 doc/driver-model/UDM-power.txt diff --git a/doc/driver-model/UDM-power.txt b/doc/driver-model/UDM-power.txt new file mode 100644 index 0000000..9ac1a5f --- /dev/null +++ b/doc/driver-model/UDM-power.txt @@ -0,0 +1,88 @@ +The U-Boot Driver Model Project +=============================== +POWER analysis +============== +Viktor Krivak +2012-03-09 + +I) Overview +----------- + + 1) Actual state + --------------- + + At this moment power doesn't contain API. There are many methods for + initialization of some board specific functions but only few does what is + expected. Basically only one file contains something meaningful for this + driver. + + 2) Current implementation + ------------------------- + + In file twl6030.c are methods twl6030_stop_usb_charging() and + twl6030_start_usb_charging() for start and stop charging from USB. There are + also methods to get information about battery state and initialization of + battery charging. Only these methods are used in converted API. + + +II) Approach +------------ + + 1) New API + ---------- + + New API implements only functions specific for managing power. All board + specific init methods are moved to other files. Name of methods are + self-explanatory. + + struct ops { + void (*start_usb_charging)(struct instance *i); + void (*stop_usb_charging)(struct instance *i); + int (*get_battery_current)(struct instance *i); + int (*get_battery_voltage)(struct instance *i); + void (*init_battery_charging)(struct instance *i); + } + + 2) Conversions of other methods + ------------------------------- + + Methods that can't be converted to new API are moved to board file or to + special file for board hacks. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) ftpmu010.c + ------------- + All methods of this file are moved to another location. + void ftpmu010_32768osc_enable(void): Move to boards hacks + void ftpmu010_mfpsr_select_dev(unsigned int dev): Move to board file + arch/nds32/lib/board.c + void ftpmu010_mfpsr_diselect_dev(unsigned int dev): Dead code + void ftpmu010_dlldis_disable(void): Dead code + void ftpmu010_sdram_clk_disable(unsigned int cr0): Move to board file + arch/nds32/lib/board.c + void ftpmu010_sdramhtc_set(unsigned int val): Move to board file + arch/nds32/lib/board.c + + 2) twl4030.c + ------------ + All methods of this file are moved to another location. + void twl4030_power_reset_init(void): Move to board hacks + void twl4030_pmrecv_vsel_cfg(u8 vsel_reg, u8 vsel_val, u8 dev_grp, + u8 dev_grp_sel): Move to board hacks + void twl4030_power_init(void): Move to board hacks + void twl4030_power_mmc_init(void): Move to board hacks + + 3) twl6030.c + ------------ + Some methods are converted to new API and rest are moved to another location. + void twl6030_stop_usb_charging(void): Convert to new API + void twl6030_start_usb_charging(void): Convert to new API + int twl6030_get_battery_current(void): Convert to new API + int twl6030_get_battery_voltage(void): Convert to new API + void twl6030_init_battery_charging(void): Convert to new API + void twl6030_power_mmc_init(): Move to board file + drivers/mmc/omap_hsmmc.c + void twl6030_usb_device_settings(): Move to board file + drivers/usb/musb/omap3.c -- cgit v1.1 From 5df9b142a1d8f3e782f285213b3a57500b043430 Mon Sep 17 00:00:00 2001 From: Tomas Hlavacek Date: Wed, 8 Aug 2012 01:42:25 +0000 Subject: dm: Hwmon UDM subsystem analysis added. Signed-off-by: Tomas Hlavacek --- doc/driver-model/UDM-hwmon.txt | 118 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 doc/driver-model/UDM-hwmon.txt diff --git a/doc/driver-model/UDM-hwmon.txt b/doc/driver-model/UDM-hwmon.txt new file mode 100644 index 0000000..cc5d529 --- /dev/null +++ b/doc/driver-model/UDM-hwmon.txt @@ -0,0 +1,118 @@ +The U-Boot Driver Model Project +=============================== +Hwmon device subsystem analysis +=============================== + +Tomas Hlavacek +2012-03-02 + +I) Overview +----------- + +U-Boot currently implements one API for HW monitoring devices. The +interface is defined in include/dtt.h and comprises of functions: + + void dtt_init(void); + int dtt_init_one(int); + int dtt_read(int sensor, int reg); + int dtt_write(int sensor, int reg, int val); + int dtt_get_temp(int sensor); + +The functions are implemented by a proper device driver in drivers/hwmon +directory and the driver to be compiled in is selected in a Makefile. +Drivers are mutually exclusive. + +Drivers depends on I2O code and naturally on board specific data. There are +few ad-hoc constants put in dtt.h file and driver headers and code. This +has to be consolidated into board specific data or driver headers if those +constants makes sense globally. + + +II) Approach +------------ + + 1) New API + ---------- + In the UDM each hwmon driver would register itself by a function + + int hwmon_device_register(struct instance *i, + struct hwmon_device_ops *o); + + The structure being defined as follows: + + struct hwmon_device_ops { + int (*read)(struct instance *i, int sensor, int reg); + int (*write)(struct instance *i, int sensor, int reg, + int val); + int (*get_temp)(struct instance *i, int sensor); + }; + + + 2) Conversion thougths + ---------------------- + U-Boot hwmon drivers exports virtually the same functions (with exceptions) + and we are considering low number of drivers and code anyway. The interface + is already similar and unified by the interface defined in dtt.h. + Current initialization functions dtt_init() and dtt_init_one() will be + converted into probe() and hwmon_device_register(), so the funcionality will + be kept in more proper places. Besides implementing core registration and + initialization we need to do code cleanup, especially separate + driver-specific and HW specific constants. + + 3) Special consideration due to early initialization + ---------------------------------------------------- + The dtt_init() function call is used during early initialization in + board/gdsys/405ex/io64.c for starting up fans. The dtt code is perfectly + usable in the early stage because it uses only local variables and no heap + memory is required at this level. However the underlying code of I2C has to + keep the same properties with regard to possibility of running in early + initialization stage. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) drivers/hwmon/lm81.c + ----------------------- + The driver is standard dtt. Simple conversion is possible. + + + 2) drivers/hwmon/ds1722.c + ------------------------- + The driver is not standard dtt, but interface is similar to dtt. + The interface has to be changed in order to comply to above mentioned + specification. + + + 3) drivers/hwmon/ds1775.c + ------------------------- + The driver is standard dtt. Simple conversion is possible. + + + 4) drivers/hwmon/lm73.c + ----------------------- + The driver is standard dtt. Simple conversion is possible. + + + 5) drivers/hwmon/lm63.c + ----------------------- + The driver is standard dtt. Simple conversion is possible. + + + 6) drivers/hwmon/adt7460.c + -------------------------- + The driver is standard dtt. Simple conversion is possible. + + + 7) drivers/hwmon/lm75.c + ----------------------- + The driver is standard dtt. Simple conversion is possible. + + + 8) drivers/hwmon/ds1621.c + ------------------------- + The driver is standard dtt. Simple conversion is possible. + + + 9) drivers/hwmon/adm1021.c + -------------------------- + The driver is standard dtt. Simple conversion is possible. -- cgit v1.1 From f07563a7a544c5391a3d0f0d0187381d4ddc90c1 Mon Sep 17 00:00:00 2001 From: Tomas Hlavacek Date: Wed, 8 Aug 2012 01:42:26 +0000 Subject: dm: Driver model analysis document for Watchdog subsystem has been added. Signed-off-by: Tomas Hlavacek --- doc/driver-model/UDM-watchdog.txt | 334 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 doc/driver-model/UDM-watchdog.txt diff --git a/doc/driver-model/UDM-watchdog.txt b/doc/driver-model/UDM-watchdog.txt new file mode 100644 index 0000000..271bd26 --- /dev/null +++ b/doc/driver-model/UDM-watchdog.txt @@ -0,0 +1,334 @@ +The U-Boot Driver Model Project +=============================== +Watchdog device subsystem analysis +================================== + +Tomas Hlavacek +2012-03-09 + +I) Overview +----------- + +U-Boot currently implements an API for HW watchdog devices as explicit drivers +in drivers/watchdog directory. There are also drivers for both hardware and +software watchdog on particular CPUs implemented in arch/*/cpu/*/cpu.c. There +are macros in include/watchdog.h that selects between SW and HW watchdog and +assembly SW implementation. + +The current common interface comprises of one set out of these two possible +variants: + + 1) + void watchdog_reset(void); + int watchdog_disable(void); + int watchdog_init(void); + + 2) + void hw_watchdog_reset(void); + void hw_watchdog_init(void); + +The watchdog implementations are also spread through board/*/*.c that in +some cases. The API and semantics is in most cases same as the above +mentioned common functions. + + +II) Approach +------------ + + 1) New API + ---------- + + In the UDM each watchdog driver would register itself by a function + + int watchdog_device_register(struct instance *i, + const struct watchdog_device_ops *o); + + The structure being defined as follows: + + struct watchdog_device_ops { + int (*disable)(struct instance *i); + void (*reset)(struct instance *i); + }; + + The watchdog_init() function will be dissolved into probe() function. + + 2) Conversion thougths + ---------------------- + + Conversion of watchdog implementations to a new API could be divided + to three subsections: a) HW implementations, which are mostly compliant + to the above mentioned API; b) SW implementations, which are compliant + to the above mentioned API and c) SW implementations that are not compliant + to the API and has to be rectified or partially rewritten. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) drivers/watchdog/at91sam9_wdt.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 2) drivers/watchdog/ftwdt010_wdt.c + ---------------------------------- + The driver is ad-hoc HW watchdog. Conversion has to take into account + driver parts spread in include/faraday/*. Restructuring the driver and + code cleanup has to be considered. + + + 3) arch/arm/cpu/arm1136/mx31/timer.c + ------------------------------------ + The driver is semi-standard ad-hoc HW watchdog. Conversion has to take + into account driver parts spread in the timer.c file. + + + 4) arch/arm/cpu/arm926ejs/davinci/timer.c + ----------------------------------------- + The driver is ad-hoc semi-standard HW watchdog. Conversion has to take + into account driver parts spread in the timer.c file. + + + 5) arch/arm/cpu/armv7/omap-common/hwinit-common.c + ------------------------------------------------- + The driver is non-standard ad-hoc HW watchdog. Conversion is possible + but functions has to be renamed and constants moved to another places. + + + 6) arch/arm/cpu/armv7/omap3/board.c + ----------------------------------- + The driver is non-standard ad-hoc HW watchdog. Conversion is possible + but functions has to be renamed and constants moved to another places. + + + 7) arch/blackfin/cpu/watchdog.c + ------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 8) arch/m68k/cpu/mcf523x/cpu.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 9) arch/m68k/cpu/mcf52x2/cpu.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 10) arch/m68k/cpu/mcf532x/cpu.c + ------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 11) arch/m68k/cpu/mcf547x_8x/cpu.c + ---------------------------------- + The driver is standard HW watchdog (there is slight naming convention + violation that has to be rectified). Simple conversion is possible. + + + 12) arch/powerpc/cpu/74xx_7xx/cpu.c + ----------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 13) arch/powerpc/cpu/mpc512x/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 14) arch/powerpc/cpu/mpc5xx/cpu.c + --------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 15) arch/powerpc/cpu/mpc5xxx/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 16) arch/powerpc/cpu/mpc8260/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 17) arch/powerpc/cpu/mpc83xx/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 18) arch/powerpc/cpu/mpc85xx/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 19) arch/powerpc/cpu/mpc86xx/cpu.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 20) arch/powerpc/cpu/mpc8xx/cpu.c + + The driver is standard HW watchdog. Simple conversion is possible. + + + 21) arch/powerpc/cpu/ppc4xx/cpu.c + --------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 22) arch/sh/cpu/sh2/watchdog.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 23) arch/sh/cpu/sh3/watchdog.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 24) arch/sh/cpu/sh4/watchdog.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 25) board/amcc/luan/luan.c + -------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 26) board/amcc/yosemite/yosemite.c + ---------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 27) board/apollon/apollon.c + --------------------------- + The driver is standard HW watchdog however the watchdog_init() + function is called in early initialization. Simple conversion is possible. + + + 28) board/bmw/m48t59y.c + ----------------------- + Special watchdog driver. Dead code. To be removed. + + + 29) board/davedenx/qong/qong.c + ------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 30) board/dvlhost/watchdog.c + ---------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 31) board/eNET/eNET.c + --------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 32) board/eltec/elppc/elppc.c + ----------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 33) board/enbw/enbw_cmc/enbw_cmc.c + ---------------------------------- + Only function proxy call. Code cleanup needed. + + + 34) board/freescale/mx31pdk/mx31pdk.c + ------------------------------------- + Only function proxy call. Code cleanup needed. + + + 35) board/gth2/gth2.c + --------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 36) board/lwmon5/lwmon5.c + ------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 37) board/manroland/mucmc52/mucmc52.c + ------------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 38) board/manroland/uc101/uc101.c + --------------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 39) board/mousse/m48t59y.c + -------------------------- + Special watchdog driver. Dead code. To be removed. + + + 40) board/mvblue/mvblue.c + ------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 41) board/netphone/netphone.c + ----------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 42) board/netta/netta.c + ----------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 43) board/netta2/netta2.c + ------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 44) board/omicron/calimain/calimain.c + ------------------------------------- + Only function proxy call. Code cleanup needed. + + + 45) board/pcippc2/pcippc2.c + --------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 46) board/pcs440ep/pcs440ep.c + ----------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 47) board/stx/stxxtc/stxxtc.c + ----------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 48) board/ti/omap2420h4/omap2420h4.c + ------------------------------------ + The driver is standard HW watchdog. Simple conversion is possible. + + + 49) board/ttcontrol/vision2/vision2.c + ------------------------------------- + The driver is standard HW watchdog but namespace is polluted by + non-standard macros. Simple conversion is possible, code cleanup + needed. + + + 50) board/v38b/v38b.c + --------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 51) board/ve8313/ve8313.c + ------------------------- + The driver is standard HW watchdog. Simple conversion is possible. + + + 52) board/w7o/watchdog.c + ------------------------ + The driver is standard HW watchdog. Simple conversion is possible. -- cgit v1.1 From a09c649972d132a2998d28c8d402eb625966ffe2 Mon Sep 17 00:00:00 2001 From: Pavel Herrmann Date: Wed, 8 Aug 2012 01:42:27 +0000 Subject: dm: add PCI design document Signed-off-by: Pavel Herrmann --- doc/driver-model/UDM-pci.txt | 265 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 doc/driver-model/UDM-pci.txt diff --git a/doc/driver-model/UDM-pci.txt b/doc/driver-model/UDM-pci.txt new file mode 100644 index 0000000..b65e9ea --- /dev/null +++ b/doc/driver-model/UDM-pci.txt @@ -0,0 +1,265 @@ +The U-Boot Driver Model Project +=============================== +PCI subsystem analysis +====================== + +Pavel Herrmann +2012-03-17 + +I) Overview +----------- + + U-Boot already supports multiple PCI busses, stored in a linked-list of + pci_controller structures. This structure contains generic driver data, bus + interface operations and private data for the driver. + + Bus interface operations for PCI are (names are self-explanatory): + + read_byte() + read_word() + read_dword() + write_byte() + write_word() + write_dword() + + Each driver has to implement dword operations, and either implement word and + byte operations, or use shared $operation_config_$type_via_dword (eg. + read_config_byte_via_dword and similar) function. These functions are used + for config space I/O (read_config_dword and similar functions of the PCI + subsystem), which is used to configure the connected devices for standard MMIO + operations. All data transfers by respective device drivers are then done by + MMIO + + Each driver also defines a separate init function, which has unique symbol + name, and thus more drivers can be compiled in without colliding. This init + function is typically called from pci_init_board(), different for each + particular board. + + Some boards also define a function called fixup_irq, which gets called after + scanning the PCI bus for devices, and should dismiss any interrupts. + + Several drivers are also located in arch/ and should be moved to drivers/pci. + +II) Approach +------------ + + The pci_controller structure needs to be broken down to fit the new driver + model. Due to a large number of members, this will be done through three + distinct accessors, one for memory regions, one for config table and one for + everything else. That will make the pci_ops structure look like this: + + struct pci_ops { + int (*read_byte)(struct instance *bus, pci_dev_t *dev, int addr, + u8 *buf); + int (*read_word)(struct instance *bus, pci_dev_t *dev, int addr, + u16 *buf); + int (*read_dword)(struct instance *bus, pci_dev_t *dev, int addr, + u32 *buf); + int (*write_byte)(struct instance *bus, pci_dev_t *dev, int addr, + u8 val); + int (*write_byte)(struct instance *bus, pci_dev_t *dev, int addr, + u8 val); + int (*write_dword)(struct instance *bus, pci_dev_t *dev, int addr, + u32 val); + void (*fixup_irq)(struct instance *bus, pci_dev_t *dev); + struct pci_region* (*get_region)(struct instance *, uint num); + struct pci_config_table* (*get_cfg_table)(struct instance *bus); + uint (*get_option)(struct instance * bus, enum pci_option_code op); + } + + enum pci_option_code { + PCI_OPT_BUS_NUMBER=0, + PCI_OPT_REGION_COUNT, + PCI_OPT_INDIRECT_TYPE, + PCI_OPT_AUTO_MEM, + PCI_OPT_AUTO_IO, + PCI_OPT_AUTO_PREFETCH, + PCI_OPT_AUTO_FB, + PCI_OPT_CURRENT_BUS, + PCI_OPT_CFG_ADDR, + } + + The return value for get_option will be an unsigned integer value for any + option code. If the option currently is a pointer to pci_region, it will + return an index for get_region function. Special case has to be made for + PCI_OPT_CFG_ADDR, which should be interpreted as a pointer, but it is only + used for equality in find_hose_by_cfg_addr, and thus can be returned as an + uint. Other function using cfg_addr value are read/write functions for + specific drivers (especially ops for indirect bridges), and thus have access + to private_data of the driver instance. + + The config table accessor will return a pointer to a NULL-terminated array of + pci_config_table, which is supplied by the board in platform_data, or NULL if + the board didn't specify one. This table is used to override PnP + auto-initialization, or to specific initialization functions for non-PNP + devices. + + Transparent PCI-PCI bridges will get their own driver, and will forward all + operations to operations of their parent bus. This however makes it + impossible to use instances to identify devices, as not all devices will be + directly visible to the respective bus driver. + + Init functions of controller drivers will be moved to their respective + probe() functions, in accordance to the driver model. + + The PCI core will handle all mapping functions currently found in pci.c, as + well as proxy functions for read/write operations of the drivers. The PCI + core will also handle bus scanning and device configuration. + + The PnP helper functions currently in pci_auto.c will also be a part of PCI + core, but they will be exposed only to PCI controller drivers, not to other + device drivers. + + The PCI API for device drivers will remain largely unchanged, most drivers + will require no changes at all, and all modifications will be limited to + changing the pci_controlle into instance*. + +III) Analysis of in-tree drivers +-------------------------------- + + A) drivers in drivers/pci/ + -------------------------- + + 1) pci_indirect.c + ----------------- + Shared driver for indirect PCI bridges, several CONFIG macros - will + require significant cleanup. + + 2) pci_ixp.c + ------------ + Standard driver, specifies all read/write functions separately. + + 3) pci_sh4.c + ------------ + Shared init function for SH4 drivers, uses dword for read/write ops. + + 4) pci_sh7751.c + --------------- + Standard driver, uses SH4 shared init. + + 5) pci_sh7780.c + --------------- + Standard driver, uses SH4 shared init. + + 6) tsi108_pci.c + --------------- + Standard driver, uses dword for read/write ops. + + 7) fsl_pci_init.c + ----------------- + Driver for PCI and PCI-e, uses indirect functions. + + 8) pci_ftpci100.c + ----------------- + Standard driver, uses indirect functions, has separate scan/setup + functions. + + B) driver in arch/ + ------------------ + + 1) x86/lib/pci_type1.c + ---------------------- + Standard driver, specifies all read/write functions separately. + + 2) m68k/cpu/mcf5445x/pci.c + -------------------------- + Standard driver, specifies all read/write functions separately. + + 3) m68k/cpu/mcf547x_8x/pci.c + ---------------------------- + Standard driver, specifies all read/write functions separately. + + 4) powerpc/cpu/mpc824x/pci.c + ---------------------------- + Standard driver, uses indirect functions, does not setup HW. + + 5) powerpc/cpu/mpc8260/pci.c + ---------------------------- + Standard driver, uses indirect functions. + + 6) powerpc/cpu/ppc4xx/4xx_pci.c + ------------------------------- + Standard driver, uses indirect functions. + + 7) powerpc/cpu/ppc4xx/4xx_pcie.c + -------------------------------- + PCI-e driver, specifies all read/write functions separately. + + 8) powerpc/cpu/mpc83xx/pci.c + ---------------------------- + Standard driver, uses indirect functions. + + 9) powerpc/cpu/mpc83xx/pcie.c + ----------------------------- + PCI-e driver, specifies all read/write functions separately. + + 10) powerpc/cpu/mpc5xxx/pci_mpc5200.c + ------------------------------------- + Standard driver, uses dword for read/write ops. + + 11) powerpc/cpu/mpc512x/pci.c + ----------------------------- + Standard driver, uses indirect functions. + + 12) powerpc/cpu/mpc8220/pci.c + ----------------------------- + Standard driver, specifies all read/write functions separately. + + 13) powerpc/cpu/mpc85xx/pci.c + ----------------------------- + Standard driver, uses indirect functions, has two busses. + + C) drivers in board/ + -------------------- + + 1) eltec/elppc/pci.c + -------------------- + Standard driver, uses indirect functions. + + 2) amirix/ap1000/pci.c + ---------------------- + Standard driver, specifies all read/write functions separately. + + 3) prodrive/p3mx/pci.c + ---------------------- + Standard driver, uses dword for read/write ops, has two busses. + + 4) esd/cpci750/pci.c + -------------------- + Standard driver, uses dword for read/write ops, has two busses. + + 5) esd/common/pci.c + ------------------- + Standard driver, uses dword for read/write ops. + + 6) dave/common/pci.c + -------------------- + Standard driver, uses dword for read/write ops. + + 7) ppmc7xx/pci.c + ---------------- + Standard driver, uses indirect functions. + + 8) pcippc2/cpc710_pci.c + ----------------------- + Standard driver, uses indirect functions, has two busses. + + 9) Marvell/db64360/pci.c + ------------------------ + Standard driver, uses dword for read/write ops, has two busses. + + 10) Marvell/db64460/pci.c + ------------------------- + Standard driver, uses dword for read/write ops, has two busses. + + 11) evb64260/pci.c + ------------------ + Standard driver, uses dword for read/write ops, has two busses. + + 12) armltd/integrator/pci.c + --------------------------- + Standard driver, specifies all read/write functions separately. + + All drivers will be moved to drivers/pci. Several drivers seem + similar/identical, especially those located under board, and may be merged + into one. -- cgit v1.1 From cbcc33e951fc3c16b167f0313823a2fdc295caf6 Mon Sep 17 00:00:00 2001 From: Viktor Krivak Date: Wed, 8 Aug 2012 01:42:28 +0000 Subject: dm: Add pcmcia design document Signed-off-by: Viktor Krivak --- doc/driver-model/UDM-pcmcia.txt | 78 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 doc/driver-model/UDM-pcmcia.txt diff --git a/doc/driver-model/UDM-pcmcia.txt b/doc/driver-model/UDM-pcmcia.txt new file mode 100644 index 0000000..fc31461 --- /dev/null +++ b/doc/driver-model/UDM-pcmcia.txt @@ -0,0 +1,78 @@ +The U-Boot Driver Model Project +=============================== +PCMCIA analysis +=============== +Viktor Krivak +2012-03-17 + +I) Overview +----------- + + U-boot implements only 2 methods to interoperate with pcmcia. One to turn + device on and other to turn device off. Names of these methods are usually + pcmcia_on() and pcmcia_off() without any parameters. Some files in driver + directory implements only internal API. These methods aren't used outside + driver directory and they are not converted to new driver model. + +II) Approach +----------- + + 1) New API + ---------- + + Current API is preserved and all internal methods are hiden. + + struct ops { + void (*pcmcia_on)(struct instance *i); + void (*pcmcia_off)(struct instance *i); + } + + 2) Conversion + ------------- + + In header file pcmcia.h are some other variables which are used for + additional configuration. But all have to be moved to platform data or to + specific driver implementation. + + 3) Platform data + ---------------- + + Many boards have custom implementation of internal API. Pointers to these + methods are stored in platform_data. But the most implementations for Intel + 82365 and compatible PC Card controllers and Yenta-compatible + PCI-to-CardBus controllers implement whole API per board. In these cases + pcmcia_on() and pcmcia_off() behave only as wrappers and call specific + board methods. + +III) Analysis of in-tree drivers +-------------------------------- + + 1) i82365.c + ----------- + Driver methods have different name i82365_init() and i82365_exit but + all functionality is the same. Board files board/atc/ti113x.c and + board/cpc45/pd67290.c use their own implementation of these method. + In this case all methods in driver behave only as wrappers. + + 2) marubun_pcmcia.c + ------------------- + Meets standard API behaviour. Simple conversion. + + 3) mpc8xx_pcmcia.c + ------------------ + Meets standard API behaviour. Simple conversion. + + 4) rpx_pcmcia.c + --------------- + Implements only internal API used in other drivers. Non of methods + implemented here are used outside driver model. + + 5) ti_pci1410a.c + ---------------- + Has different API but methods in this file are never called. Probably + dead code. + + 6)tqm8xx_pcmcia.c + ----------------- + Implements only internal API used in other drivers. Non of methods + implemented here are used outside driver model. -- cgit v1.1 From 0d9e59948a6694ac5f5bb08fd9537732b76bceb3 Mon Sep 17 00:00:00 2001 From: Tomas Hlavacek Date: Wed, 8 Aug 2012 01:42:29 +0000 Subject: dm: RTC subsystem analysis added. Signed-off-by: Tomas Hlavacek --- doc/driver-model/UDM-rtc.txt | 258 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 doc/driver-model/UDM-rtc.txt diff --git a/doc/driver-model/UDM-rtc.txt b/doc/driver-model/UDM-rtc.txt new file mode 100644 index 0000000..5d9fb33 --- /dev/null +++ b/doc/driver-model/UDM-rtc.txt @@ -0,0 +1,258 @@ +============================= +RTC device subsystem analysis +============================= + +Tomas Hlavacek +2012-03-10 + +I) Overview +----------- + +U-Boot currently implements one common API for RTC devices. The interface +is defined in include/rtc.h and comprises of functions and structures: + + struct rtc_time { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + }; + + int rtc_get (struct rtc_time *); + int rtc_set (struct rtc_time *); + void rtc_reset (void); + +The functions are implemented by a proper device driver in drivers/rtc +directory and the driver to be compiled in is selected in a Makefile. +Drivers are mutually exclusive. + +Drivers depends on date code in drivers/rtc/date.c and naturally on board +specific data. + +II) Approach +------------ + + 1) New API + ---------- + In the UDM each rtc driver would register itself by a function + + int rtc_device_register(struct instance *i, + struct rtc_device_ops *o); + + The structure being defined as follows: + + struct rtc_device_ops { + int (*get_time)(struct instance *i, struct rtc_time *t); + int (*set_time)(struct instance *i, struct rtc_time *t); + int (*reset)(struct instance *i); + }; + + + 2) Conversion thougths + ---------------------- + U-Boot RTC drivers exports the same functions and therefore the conversion + of the drivers is straight-forward. There is no initialization needed. + + +III) Analysis of in-tree drivers +-------------------------------- + + 1) drivers/rtc/rv3029.c + ----------------------- + The driver is standard rtc. Simple conversion is possible. + + + 2) drivers/rtc/s3c24x0_rtc.c + ---------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 3) drivers/rtc/pt7c4338.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 4) drivers/rtc/mvrtc.c + ---------------------- + The driver is standard rtc. Simple conversion is possible. + + + 5) drivers/rtc/ftrtc010.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 6) drivers/rtc/mpc5xxx.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 7) drivers/rtc/ds164x.c + ----------------------- + The driver is standard rtc. Simple conversion is possible. + + + 8) drivers/rtc/rs5c372.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 9) drivers/rtc/m41t94.c + ----------------------- + The driver is standard rtc. Simple conversion is possible. + + + 10) drivers/rtc/mc13xxx-rtc.c + ----------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 11) drivers/rtc/mcfrtc.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 12) drivers/rtc/davinci.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 13) drivers/rtc/rx8025.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 14) drivers/rtc/bfin_rtc.c + -------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 15) drivers/rtc/m41t62.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 16) drivers/rtc/ds1306.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 17) drivers/rtc/mpc8xx.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 18) drivers/rtc/ds3231.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 19) drivers/rtc/ds12887.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 20) drivers/rtc/ds1302.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 21) drivers/rtc/ds1374.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 22) drivers/rtc/ds174x.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 23) drivers/rtc/m41t60.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 24) drivers/rtc/m48t35ax.c + -------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 25) drivers/rtc/pl031.c + ----------------------- + The driver is standard rtc. Simple conversion is possible. + + + 26) drivers/rtc/x1205.c + ----------------------- + The driver is standard rtc. Simple conversion is possible. + + + 27) drivers/rtc/m41t11.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 28) drivers/rtc/pcf8563.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 29) drivers/rtc/mk48t59.c + ------------------------- + Macros needs cleanup. Besides that the driver is standard rtc. + Simple conversion is possible. + + + 30) drivers/rtc/mxsrtc.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 31) drivers/rtc/ds1307.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 32) drivers/rtc/ds1556.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 33) drivers/rtc/rtc4543.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 34) drivers/rtc/s3c44b0_rtc.c + ----------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 35) drivers/rtc/ds1337.c + ------------------------ + The driver is standard rtc. Simple conversion is possible. + + + 36) drivers/rtc/isl1208.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 37) drivers/rtc/max6900.c + ------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 38) drivers/rtc/mc146818.c + -------------------------- + The driver is standard rtc. Simple conversion is possible. + + + 39) drivers/rtc/at91sam9_rtt.c + ------------------------------ + The driver is standard rtc. Simple conversion is possible. -- cgit v1.1 From bfae89abf10e3dc52504e7f7f91d5eaf8e320cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hlav=C3=A1=C4=8Dek?= Date: Wed, 8 Aug 2012 13:42:30 +0200 Subject: dm: Add twserial device document Signed-off-by: Tomas Hlavacek --- doc/driver-model/UDM-twserial.txt | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 doc/driver-model/UDM-twserial.txt diff --git a/doc/driver-model/UDM-twserial.txt b/doc/driver-model/UDM-twserial.txt new file mode 100644 index 0000000..289416a --- /dev/null +++ b/doc/driver-model/UDM-twserial.txt @@ -0,0 +1,47 @@ +================================== +TWserial device subsystem analysis +================================== + +Tomas Hlavacek +2012-03-21 + +I) Overview +----------- + +U-Boot currently implements one common API for TWSerial devices. The interface +is defined in include/tws.h and comprises of functions: + + int tws_read(uchar *buffer, int len); + int tws_write(uchar *buffer, int len); + +The functions are implemented by a proper device driver in drivers/twserial +directory and the driver to be compiled in is selected in a Makefile. There is +only one driver present now. + +The driver depends on ad-hoc code in board specific data, namely functions: + + void tws_ce(unsigned bit); + void tws_wr(unsigned bit); + void tws_clk(unsigned bit); + void tws_data(unsigned bit); + unsigned tws_data_read(void); + void tws_data_config_output(unsigned output); + +implemented in include/configs/inka4x0.h . + +II) Approach +------------ + + U-Boot TWserial drivers exports two simple functions and therefore the conversion + of the driver and creating a core for it is not needed. It should be consolidated + with include/configs/inka4x0.h and taken to the misc/ dir. + + +III) Analysis of in-tree drivers +-------------------------------- + + 1) drivers/twserial/soft_tws.c + ------------------------------ + The driver is the only TWserial driver. The ad-hoc part in + include/configs/inka4x0.h and the core soft_tws driver should be consolidated + to one compact driver and moved to misc/ . -- cgit v1.1 From a1ea8e5109362d74f090e1632c92cac9f16fa1b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 15:01:14 +0200 Subject: README: Update ver env var description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 155cb01 replaced the read-only property of the ver env var with an auto-restoring behavior. Update the README file accordingly. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- README | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README b/README index d45eba7..7e52e36 100644 --- a/README +++ b/README @@ -907,7 +907,8 @@ The following options need to be configured: If this variable is defined, an environment variable named "ver" is created by U-Boot showing the U-Boot version as printed by the "version" command. - This variable is readonly. + Any change to this variable will be reverted at the + next reset. - Real-Time Clock: -- cgit v1.1 From f8e754d51cd9573e22eecea8543bcceffe313e95 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 15 Aug 2012 07:23:20 +0000 Subject: README.SPL: Add a small Debugging section Signed-off-by: Tom Rini --- doc/README.SPL | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/README.SPL b/doc/README.SPL index e4a5ac3..bd375a0 100644 --- a/doc/README.SPL +++ b/doc/README.SPL @@ -78,3 +78,10 @@ an SPL CPU in boards.cfg as follows: This this case CPU will be set to "normal_cpu" during the main u-boot build and "spl_cpu" during the SPL build. + + +Debugging +--------- + +When building SPL with DEBUG set you may also need to set CONFIG_PANIC_HANG +as in most cases do_reset is not defined within SPL. -- cgit v1.1 From c3567d808df36d8a9e53f9cc9e6a1ac5d1e23195 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 15 Aug 2012 07:23:21 +0000 Subject: README.SPL: Move the 'Estimating stack usage' from omap3 to here The instructions are generic, so move to the generic doc. Signed-off-by: Tom Rini --- doc/README.SPL | 23 +++++++++++++++++++++++ doc/SPL/README.omap3 | 22 ---------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/doc/README.SPL b/doc/README.SPL index bd375a0..5368586 100644 --- a/doc/README.SPL +++ b/doc/README.SPL @@ -85,3 +85,26 @@ Debugging When building SPL with DEBUG set you may also need to set CONFIG_PANIC_HANG as in most cases do_reset is not defined within SPL. + + +Estimating stack usage +---------------------- + +With gcc 4.6 (and later) and the use of GNU cflow it is possible to estimate +stack usage at various points in run sequence of SPL. The -fstack-usage option +to gcc will produce '.su' files (such as arch/arm/cpu/armv7/syslib.su) that +will give stack usage information and cflow can construct program flow. + +Must have gcc 4.6 or later, which supports -fstack-usage + +1) Build normally +2) Perform the following shell command to generate a list of C files used in +SPL: +$ find spl -name '*.su' | sed -e 's:^spl/::' -e 's:[.]su$:.c:' > used-spl.list +3) Execute cflow: +$ cflow --main=board_init_r `cat used-spl.list` 2>&1 | $PAGER + +cflow will spit out a number of warnings as it does not parse +the config files and picks functions based on #ifdef. Parsing the '.i' +files instead introduces another set of headaches. These warnings are +not usually important to understanding the flow, however. diff --git a/doc/SPL/README.omap3 b/doc/SPL/README.omap3 index a543e65..c77ca43 100644 --- a/doc/SPL/README.omap3 +++ b/doc/SPL/README.omap3 @@ -50,25 +50,3 @@ For the areas that reside within DDR1 they must not be used prior to s_init() completing. Note that CONFIG_SYS_TEXT_BASE must be clear of the areas that SPL uses while running. This is why we have two versions of the memory map that only vary in where the BSS and malloc pool reside. - -Estimating stack usage ----------------------- - -With gcc 4.6 (and later) and the use of GNU cflow it is possible to estimate -stack usage at various points in run sequence of SPL. The -fstack-usage option -to gcc will produce '.su' files (such as arch/arm/cpu/armv7/syslib.su) that -will give stack usage information and cflow can construct program flow. - -Must have gcc 4.6 or later, which supports -fstack-usage - -1) Build normally -2) Perform the following shell command to generate a list of C files used in -SPL: -$ find spl -name '*.su' | sed -e 's:^spl/::' -e 's:[.]su$:.c:' > used-spl.list -3) Execute cflow: -$ cflow --main=board_init_r `cat used-spl.list` 2>&1 | $PAGER - -cflow will spit out a number of warnings as it does not parse -the config files and picks functions based on #ifdef. Parsing the '.i' -files instead introduces another set of headaches. These warnings are -not usually important to understanding the flow, however. -- cgit v1.1 From 923c46f97a7936cbdc6e113d7705cf46a73dc85c Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Thu, 16 Aug 2012 06:20:15 +0000 Subject: README: Cleanup description of supported partitions. README: Cleanup description of supported partitions. Signed-off-by: Karl O. Pinc --- README | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README b/README index 7e52e36..4428205 100644 --- a/README +++ b/README @@ -951,13 +951,20 @@ The following options need to be configured: commands like bootm or iminfo. This option is automatically enabled when you select CONFIG_CMD_DATE . -- Partition Support: - CONFIG_MAC_PARTITION and/or CONFIG_DOS_PARTITION - and/or CONFIG_ISO_PARTITION and/or CONFIG_EFI_PARTITION +- Partition Labels (disklabels) Supported: + Zero or more of the following: + CONFIG_MAC_PARTITION Apple's MacOS partition table. + CONFIG_DOS_PARTITION MS Dos partition table, traditional on the + Intel architecture, USB sticks, etc. + CONFIG_ISO_PARTITION ISO partition table, used on CDROM etc. + CONFIG_EFI_PARTITION GPT partition table, common when EFI is the + bootloader. Note 2TB partition limit; see + disk/part_efi.c + CONFIG_MTD_PARTITIONS Memory Technology Device partition table. If IDE or SCSI support is enabled (CONFIG_CMD_IDE or CONFIG_CMD_SCSI) you must configure support for at - least one partition type as well. + least one non-MTD partition type as well. - IDE Reset method: CONFIG_IDE_RESET_ROUTINE - this is defined in several -- cgit v1.1 From 641b0d374eeea65778bf8cb2107064c2aff195eb Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 10:26:29 +0000 Subject: hush: Add default value substitution support Use standard sh syntax: ${VAR:-default} Use default value: if VAR is set and non-null, expands to $VAR. Otherwise, expands to default. ${VAR:=default} Set default value: if VAR is set and non-null, expands to $VAR. Otherwise, sets hush VAR to default and expands to default. ${VAR:+default} If VAR is set and non-null, expands to the empty string. Otherwise, expands to default. Signed-off-by: Joe Hershberger --- common/hush.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/common/hush.c b/common/hush.c index 1eff182..39cf203 100644 --- a/common/hush.c +++ b/common/hush.c @@ -2743,13 +2743,50 @@ static int parse_group(o_string *dest, struct p_context *ctx, static char *lookup_param(char *src) { char *p; + char *sep; + char *default_val = NULL; + int assign = 0; + int expand_empty = 0; if (!src) return NULL; - p = getenv(src); - if (!p) - p = get_local_var(src); + sep = strchr(src, ':'); + + if (sep) { + *sep = '\0'; + if (*(sep + 1) == '-') + default_val = sep+2; + if (*(sep + 1) == '=') { + default_val = sep+2; + assign = 1; + } + if (*(sep + 1) == '+') { + default_val = sep+2; + expand_empty = 1; + } + } + + p = getenv(src); + if (!p) + p = get_local_var(src); + + if (!p || strlen(p) == 0) { + p = default_val; + if (assign) { + char *var = malloc(strlen(src)+strlen(default_val)+2); + if (var) { + sprintf(var, "%s=%s", src, default_val); + set_local_var(var, 0); + } + free(var); + } + } else if (expand_empty) { + p += strlen(p); + } + + if (sep) + *sep = ':'; return p; } -- cgit v1.1 From a005f19eff946454985785788c344f10616d571e Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 10:26:30 +0000 Subject: hush: Don't parse the contents of a dereferenced var When a variable which contains a user-supplied value is dereferenced (e.g. to be echo'ed), make sure that the value is not further parsed by hush. Set the hush local variable "HUSH_NO_EVAL=1" to enable this behavior. Without this patch, a sequence like this occurs: Panda # env set my_user_string Bob\'s favorite device Panda # print my_user_string my_user_string=Bob's favorite device Panda # echo $my_user_string syntax error hush.c:3007 With this patch, it looks like this: Panda # HUSH_NO_EVAL=1 Panda # env set my_user_string Bob\'s favorite device Panda # print my_user_string my_user_string=Bob's favorite device Panda # echo $my_user_string Bob's favorite device Signed-off-by: Joe Hershberger --- common/hush.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/common/hush.c b/common/hush.c index 39cf203..4c84c2f 100644 --- a/common/hush.c +++ b/common/hush.c @@ -127,6 +127,7 @@ #endif #endif #define SPECIAL_VAR_SYMBOL 03 +#define SUBSTED_VAR_SYMBOL 04 #ifndef __U_BOOT__ #define FLAG_EXIT_FROM_LOOP 1 #define FLAG_PARSE_SEMICOLON (1 << 1) /* symbol ';' is special for parser */ @@ -499,6 +500,7 @@ static void remove_bg_job(struct pipe *pi); /* local variable support */ static char **make_list_in(char **inp, char *name); static char *insert_var_value(char *inp); +static char *insert_var_value_sub(char *inp, int tag_subst); #ifndef __U_BOOT__ /* Table of built-in functions. They can be forked or not, depending on @@ -3088,6 +3090,21 @@ int parse_stream(o_string *dest, struct p_context *ctx, return 1; break; #endif + case SUBSTED_VAR_SYMBOL: + dest->nonnull = 1; + while (ch = b_getch(input), ch != EOF && + ch != SUBSTED_VAR_SYMBOL) { + debug_printf("subst, pass=%d\n", ch); + if (input->__promptme == 0) + return 1; + b_addchr(dest, ch); + } + debug_printf("subst, term=%d\n", ch); + if (ch == EOF) { + syntax(); + return 1; + } + break; default: syntax(); /* this is really an internal logic error */ return 1; @@ -3129,6 +3146,10 @@ void update_ifs_map(void) mapset((uchar *)"\\$'\"`", 3); /* never flow through */ mapset((uchar *)"<>;&|(){}#", 1); /* flow through if quoted */ #else + { + uchar subst[2] = {SUBSTED_VAR_SYMBOL, 0}; + mapset(subst, 3); /* never flow through */ + } mapset((uchar *)"\\$'\"", 3); /* never flow through */ mapset((uchar *)";&|#", 1); /* flow through if quoted */ #endif @@ -3468,25 +3489,57 @@ final_return: static char *insert_var_value(char *inp) { + return insert_var_value_sub(inp, 0); +} + +static char *insert_var_value_sub(char *inp, int tag_subst) +{ int res_str_len = 0; int len; int done = 0; char *p, *p1, *res_str = NULL; while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) { + /* check the beginning of the string for normal charachters */ if (p != inp) { + /* copy any charachters to the result string */ len = p - inp; res_str = xrealloc(res_str, (res_str_len + len)); strncpy((res_str + res_str_len), inp, len); res_str_len += len; } inp = ++p; + /* find the ending marker */ p = strchr(inp, SPECIAL_VAR_SYMBOL); *p = '\0'; + /* look up the value to substitute */ if ((p1 = lookup_param(inp))) { - len = res_str_len + strlen(p1); + if (tag_subst) + len = res_str_len + strlen(p1) + 2; + else + len = res_str_len + strlen(p1); res_str = xrealloc(res_str, (1 + len)); - strcpy((res_str + res_str_len), p1); + if (tag_subst) { + /* + * copy the variable value to the result + * string + */ + strcpy((res_str + res_str_len + 1), p1); + + /* + * mark the replaced text to be accepted as + * is + */ + res_str[res_str_len] = SUBSTED_VAR_SYMBOL; + res_str[res_str_len + 1 + strlen(p1)] = + SUBSTED_VAR_SYMBOL; + } else + /* + * copy the variable value to the result + * string + */ + strcpy((res_str + res_str_len), p1); + res_str_len = len; } *p = SPECIAL_VAR_SYMBOL; @@ -3550,9 +3603,14 @@ static char * make_string(char ** inp) char *str = NULL; int n; int len = 2; + char *noeval_str; + int noeval = 0; + noeval_str = get_local_var("HUSH_NO_EVAL"); + if (noeval_str != NULL && *noeval_str != '0' && *noeval_str != '\0') + noeval = 1; for (n = 0; inp[n]; n++) { - p = insert_var_value(inp[n]); + p = insert_var_value_sub(inp[n], noeval); str = xrealloc(str, (len + strlen(p))); if (n) { strcat(str, " "); -- cgit v1.1 From e5ab702a6c458ad2eb041692aed3db114b5846e1 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Sun, 2 Sep 2012 09:09:00 +0000 Subject: powerpc: re-add bi_ip_addr to bd_t struct Since commit 50a47d0523e8efebe912bef539a77ffd42116451 (net: punt bd->bi_ip_addr) booting old 2.4.x ppc kernels is broken due to changed offsets of the fields in struct bd_t. Offsets of the fields after removed bi_ip_addr are wrong, causing wrong bus clocks and console baudrate configurations and various other issues. Re-add the bi_ip_addr field to preserve backward compatibility with older ppc kernels. Setting bi_ip_addr in board.c is not really needed, grepping in the 2.4 linux tree shows that bi_ip_addr is not accessed there. Adding bi_ip_addr to struct bd_t for other arches isn't needed it seems. bd_t is not used by other arches in the 2.4 linux tree. Signed-off-by: Anatolij Gustschin Acked-by: Wolfgang Denk --- arch/powerpc/include/asm/u-boot.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/include/asm/u-boot.h b/arch/powerpc/include/asm/u-boot.h index 1552054..b2fa2b5 100644 --- a/arch/powerpc/include/asm/u-boot.h +++ b/arch/powerpc/include/asm/u-boot.h @@ -63,6 +63,7 @@ typedef struct bd_info { unsigned long bi_vcofreq; /* VCO Freq, in MHz */ #endif unsigned long bi_bootflags; /* boot / reboot flag (Unused) */ + unsigned long bi_ip_addr; /* IP Address */ unsigned char bi_enetaddr[6]; /* OLD: see README.enetaddr */ unsigned short bi_ethspeed; /* Ethernet speed in Mbps */ unsigned long bi_intfreq; /* Internal Freq, in MHz */ -- cgit v1.1 From 6822a647b94cb05869231251e5a29f9742bb3ce2 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 15:36:40 -0500 Subject: cfi: Check for blank before erase Added an optional check in the CFI driver to evaluate if the sector is already blank before issuing an erase command. Improves erase time by over a factor of 10 if already blank. Signed-off-by: Joe Hershberger Signed-off-by: Stefan Roese --- drivers/mtd/cfi_flash.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index f0f301a..97a4fd7 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -1078,6 +1078,32 @@ int flash_erase (flash_info_t * info, int s_first, int s_last) for (sect = s_first; sect <= s_last; sect++) { if (info->protect[sect] == 0) { /* not protected */ +#ifdef CONFIG_SYS_FLASH_CHECK_BLANK_BEFORE_ERASE + int k; + int size; + int erased; + u32 *flash; + + /* + * Check if whole sector is erased + */ + size = flash_sector_size(info, sect); + erased = 1; + flash = (u32 *)info->start[sect]; + /* divide by 4 for longword access */ + size = size >> 2; + for (k = 0; k < size; k++) { + if (flash_read32(flash++) != 0xffffffff) { + erased = 0; + break; + } + } + if (erased) { + if (flash_verbose) + putc(','); + continue; + } +#endif switch (info->vendor) { case CFI_CMDSET_INTEL_PROG_REGIONS: case CFI_CMDSET_INTEL_STANDARD: -- cgit v1.1 From de15a06aad1f221255366ac07238c80fed146da1 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 15:36:41 -0500 Subject: cfi: Make the flash erase and write operations abortable Check for ctrlc() in operations that take time and loop over the flash addresses. In netconsole, tstc() is expensive. Only check once in a while to not slow down the operation significantly. Signed-off-by: Joe Hershberger Signed-off-by: Stefan Roese --- common/cmd_flash.c | 3 ++- common/flash.c | 3 +++ drivers/mtd/cfi_flash.c | 11 +++++++++++ include/flash.h | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/common/cmd_flash.c b/common/cmd_flash.c index 0e9b2e3..e55d366 100644 --- a/common/cmd_flash.c +++ b/common/cmd_flash.c @@ -443,7 +443,8 @@ int flash_sect_erase (ulong addr_first, ulong addr_last) rcode = flash_erase (info, s_first[bank], s_last[bank]); } } - printf ("Erased %d sectors\n", erased); + if (rcode == 0) + printf("Erased %d sectors\n", erased); } else if (rcode == 0) { puts ("Error: start and/or end address" " not on sector boundary\n"); diff --git a/common/flash.c b/common/flash.c index 781cb9c..8244ba2 100644 --- a/common/flash.c +++ b/common/flash.c @@ -221,6 +221,9 @@ void flash_perror (int err) case ERR_PROG_ERROR: puts ("General Flash Programming Error\n"); break; + case ERR_ABORTED: + puts("Flash Programming Aborted\n"); + break; default: printf ("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err); break; diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 97a4fd7..43140f3 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -1077,6 +1077,11 @@ int flash_erase (flash_info_t * info, int s_first, int s_last) for (sect = s_first; sect <= s_last; sect++) { + if (ctrlc()) { + printf("\n"); + return 1; + } + if (info->protect[sect] == 0) { /* not protected */ #ifdef CONFIG_SYS_FLASH_CHECK_BLANK_BEFORE_ERASE int k; @@ -1379,6 +1384,9 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) src += i; cnt -= i; FLASH_SHOW_PROGRESS(scale, dots, digit, i); + /* Only check every once in a while */ + if ((cnt & 0xFFFF) < buffered_size && ctrlc()) + return ERR_ABORTED; } #else while (cnt >= info->portwidth) { @@ -1391,6 +1399,9 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) wp += info->portwidth; cnt -= info->portwidth; FLASH_SHOW_PROGRESS(scale, dots, digit, info->portwidth); + /* Only check every once in a while */ + if ((cnt & 0xFFFF) < info->portwidth && ctrlc()) + return ERR_ABORTED; } #endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */ diff --git a/include/flash.h b/include/flash.h index e614d07..6d70bdd 100644 --- a/include/flash.h +++ b/include/flash.h @@ -141,6 +141,7 @@ extern flash_info_t *flash_get_info(ulong base); #define ERR_UNKNOWN_FLASH_VENDOR 32 #define ERR_UNKNOWN_FLASH_TYPE 64 #define ERR_PROG_ERROR 128 +#define ERR_ABORTED 256 /*----------------------------------------------------------------------- * Protection Flags for flash_protect(): -- cgit v1.1 From 5d1c88332951d2f58e9f7000a0523543b22d9a90 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 27 Aug 2012 15:39:45 +0200 Subject: ppc4xx: Canyonlands/Glacier: Squeeze NAND image a bit to fit again This patch removes some superfluous SDRAM init calls to fit the NAND_SPL image into 4k again. Signed-off-by: Stefan Roese --- nand_spl/board/amcc/canyonlands/ddr2_fixed.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/nand_spl/board/amcc/canyonlands/ddr2_fixed.c b/nand_spl/board/amcc/canyonlands/ddr2_fixed.c index f71ecfb9..10f62cc 100644 --- a/nand_spl/board/amcc/canyonlands/ddr2_fixed.c +++ b/nand_spl/board/amcc/canyonlands/ddr2_fixed.c @@ -92,14 +92,11 @@ static void ddr_init_common(void) mtsdram(SDRAM_INITPLR11, 0x80000432); mtsdram(SDRAM_INITPLR12, 0x808103C0); mtsdram(SDRAM_INITPLR13, 0x80810040); - mtsdram(SDRAM_INITPLR14, 0x00000000); - mtsdram(SDRAM_INITPLR15, 0x00000000); mtsdram(SDRAM_RDCC, 0x40000000); mtsdram(SDRAM_RQDC, 0x80000038); mtsdram(SDRAM_RFDC, 0x00000257); mtdcr(SDRAM_R0BAS, 0x0000F800); /* MQ0_B0BAS */ - mtdcr(SDRAM_R1BAS, 0x0400F800); /* MQ0_B1BAS */ } phys_size_t initdram(int board_type) -- cgit v1.1 From be73913b91ca1e86c7478c1ab8af7b7ba6f3e4ad Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 28 Aug 2012 14:00:24 +0200 Subject: ubifs: Fix memory leak in ubifs_finddir This patch fixes a memory leak in ubifs_finddir(). Signed-off-by: Stefan Roese Cc: dev.ma.dma@gmail.com --- fs/ubifs/ubifs.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c index 604eb8f..c68802b 100644 --- a/fs/ubifs/ubifs.c +++ b/fs/ubifs/ubifs.c @@ -295,6 +295,7 @@ static int ubifs_finddir(struct super_block *sb, char *dirname, struct file *file; struct dentry *dentry; struct inode *dir; + int ret = 0; file = kzalloc(sizeof(struct file), 0); dentry = kzalloc(sizeof(struct dentry), 0); @@ -336,7 +337,8 @@ static int ubifs_finddir(struct super_block *sb, char *dirname, if ((strncmp(dirname, (char *)dent->name, nm.len) == 0) && (strlen(dirname) == nm.len)) { *inum = le64_to_cpu(dent->inum); - return 1; + ret = 1; + goto out_free; } /* Switch to the next entry */ @@ -355,11 +357,10 @@ static int ubifs_finddir(struct super_block *sb, char *dirname, } out: - if (err != -ENOENT) { + if (err != -ENOENT) ubifs_err("cannot find next direntry, error %d", err); - return err; - } +out_free: if (file->private_data) kfree(file->private_data); if (file) @@ -369,7 +370,7 @@ out: if (dir) free(dir); - return 0; + return ret; } static unsigned long ubifs_findfile(struct super_block *sb, char *filename) -- cgit v1.1 From 6314c84df1155474d0202b51057d1f149ac07db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bie=C3=9Fmann?= Date: Thu, 16 Aug 2012 02:19:19 +0000 Subject: avr32:portmux: fix setup for macb1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use portd_mask instead of portc_mask to setup the pins for port D. Signed-off-by: Andreas Bießmann --- arch/avr32/cpu/at32ap700x/portmux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/avr32/cpu/at32ap700x/portmux.c b/arch/avr32/cpu/at32ap700x/portmux.c index e3e38a2..7eb42de 100644 --- a/arch/avr32/cpu/at32ap700x/portmux.c +++ b/arch/avr32/cpu/at32ap700x/portmux.c @@ -122,7 +122,7 @@ void portmux_enable_macb1(unsigned long flags, unsigned long drive_strength) portd_mask |= (1 << 15);/* SPD */ /* REVISIT: Some pins are probably pure outputs */ - portmux_select_peripheral(PORTMUX_PORT_D, portc_mask, + portmux_select_peripheral(PORTMUX_PORT_D, portd_mask, PORTMUX_FUNC_B, PORTMUX_BUSKEEPER); portmux_select_peripheral(PORTMUX_PORT_C, portc_mask, PORTMUX_FUNC_B, PORTMUX_BUSKEEPER); -- cgit v1.1 From 6ed0e940713d417f24fbc67898cea6f6ece4a0e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bie=C3=9Fmann?= Date: Thu, 16 Aug 2012 01:50:04 +0000 Subject: net:macb: add line break MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this patch we see annoying output like this: ---8<--- U-Boot> dhcp macb1: PHY not foundmacb0: PHY present at 1 macb0: Starting autonegotiation... --->8--- Signed-off-by: Andreas Bießmann cc: Joe Hershberger --- drivers/net/macb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 4578467..ba17277 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -364,7 +364,7 @@ static int macb_phy_find(struct macb_device *macb) } /* PHY isn't up to snuff */ - printf("%s: PHY not found", macb->netdev.name); + printf("%s: PHY not found\n", macb->netdev.name); return 0; } -- cgit v1.1 From d3a555eddb019ae4a0db7ab9c0c2297f0215a12f Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Thu, 9 Aug 2012 00:14:50 +0000 Subject: common lcd: simplify lcd_logo Simplify lcd_logo by extracting bmp unzip into its own function. Signed-off-by: Nikita Kiryanov Signed-off-by: Igor Grinberg --- common/lcd.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index 506a138..8890635 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -842,17 +842,7 @@ static void *lcd_logo(void) } #endif /* CONFIG_SPLASH_SCREEN_ALIGN */ -#ifdef CONFIG_VIDEO_BMP_GZIP - bmp_image_t *bmp = (bmp_image_t *)addr; - unsigned long len; - - if (!((bmp->header.signature[0] == 'B') && - (bmp->header.signature[1] == 'M'))) { - addr = (ulong)gunzip_bmp(addr, &len); - } -#endif - - if (lcd_display_bitmap(addr, x, y) == 0) + if (bmp_display(addr, x, y) == 0) return (void *)lcd_base; } #endif /* CONFIG_SPLASH_SCREEN */ -- cgit v1.1 From 7c7e280aa6766ac34c6dbf4a5a2c6b14554ccc3f Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Thu, 9 Aug 2012 00:14:51 +0000 Subject: common lcd: simplify lcd_display Simplify lcd_display by centralizing code into a funciton Signed-off-by: Nikita Kiryanov Signed-off-by: Igor Grinberg --- common/lcd.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index 8890635..4a5c8d5 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -607,6 +607,22 @@ static inline void bitmap_plot(int x, int y) {} #ifdef CONFIG_SPLASH_SCREEN_ALIGN #define BMP_ALIGN_CENTER 0x7FFF + +static void splash_align_axis(int *axis, unsigned long panel_size, + unsigned long picture_size) +{ + unsigned long panel_picture_delta = panel_size - picture_size; + unsigned long axis_alignment; + + if (*axis == BMP_ALIGN_CENTER) + axis_alignment = panel_picture_delta / 2; + else if (*axis < 0) + axis_alignment = panel_picture_delta + *axis + 1; + else + return; + + *axis = max(0, axis_alignment); +} #endif int lcd_display_bitmap(ulong bmp_image, int x, int y) @@ -722,15 +738,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) padded_line = (width&0x3) ? ((width&~0x3)+4) : (width); #ifdef CONFIG_SPLASH_SCREEN_ALIGN - if (x == BMP_ALIGN_CENTER) - x = max(0, (pwidth - width) / 2); - else if (x < 0) - x = max(0, pwidth - width + x + 1); - - if (y == BMP_ALIGN_CENTER) - y = max(0, (panel_info.vl_row - height) / 2); - else if (y < 0) - y = max(0, panel_info.vl_row - height + y + 1); + splash_align_axis(&x, pwidth, width); + splash_align_axis(&y, panel_info.vl_row, height); #endif /* CONFIG_SPLASH_SCREEN_ALIGN */ if ((x + width) > pwidth) -- cgit v1.1 From 203c37b8c5556aad1901ce4954792afd718c7d42 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Thu, 9 Aug 2012 00:14:52 +0000 Subject: common lcd: simplify core functions Move highly platform dependant code into its own function to reduce the number of #ifdefs in the bigger functions Signed-off-by: Nikita Kiryanov Signed-off-by: Igor Grinberg --- common/lcd.c | 62 +++++++++++++++++++++++++++++------------------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index 4a5c8d5..0f93eae 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -498,23 +498,37 @@ static int lcd_getbgcolor(void) /************************************************************************/ /* ** Chipset depending Bitmap / Logo stuff... */ /************************************************************************/ +static inline ushort *configuration_get_cmap(void) +{ +#if defined CONFIG_CPU_PXA + struct pxafb_info *fbi = &panel_info.pxa; + return (ushort *)fbi->palette; +#elif defined(CONFIG_MPC823) + immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; + cpm8xx_t *cp = &(immr->im_cpm); + return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]); +#elif defined(CONFIG_ATMEL_LCD) + return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); +#else + return (ushort *)panel_info.cmap; +#endif +} + #ifdef CONFIG_LCD_LOGO void bitmap_plot(int x, int y) { #ifdef CONFIG_ATMEL_LCD - uint *cmap; + uint *cmap = (uint *)bmp_logo_palette; #else - ushort *cmap; + ushort *cmap = (ushort *)bmp_logo_palette; #endif ushort i, j; uchar *bmap; uchar *fb; ushort *fb16; -#if defined(CONFIG_CPU_PXA) - struct pxafb_info *fbi = &panel_info.pxa; -#elif defined(CONFIG_MPC823) - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - volatile cpm8xx_t *cp = &(immr->im_cpm); +#if defined(CONFIG_MPC823) + immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; + cpm8xx_t *cp = &(immr->im_cpm); #endif debug("Logo: width %d height %d colors %d cmap %d\n", @@ -525,20 +539,17 @@ void bitmap_plot(int x, int y) fb = (uchar *)(lcd_base + y * lcd_line_length + x); if (NBITS(panel_info.vl_bpix) < 12) { - /* Leave room for default color map */ -#if defined(CONFIG_CPU_PXA) - cmap = (ushort *) fbi->palette; -#elif defined(CONFIG_MPC823) + /* Leave room for default color map + * default case: generic system with no cmap (most likely 16bpp) + * cmap was set to the source palette, so no change is done. + * This avoids even more ifdefs in the next stanza + */ +#if defined(CONFIG_MPC823) cmap = (ushort *) &(cp->lcd_cmap[BMP_LOGO_OFFSET * sizeof(ushort)]); #elif defined(CONFIG_ATMEL_LCD) - cmap = (uint *) (panel_info.mmio + ATMEL_LCDC_LUT(0)); + cmap = (uint *)configuration_get_cmap(); #else - /* - * default case: generic system with no cmap (most likely 16bpp) - * We set cmap to the source palette, so no change is done. - * This avoids even more ifdef in the next stanza - */ - cmap = bmp_logo_palette; + cmap = configuration_get_cmap(); #endif WATCHDOG_RESET(); @@ -639,12 +650,6 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) unsigned long width, height, byte_width; unsigned long pwidth = panel_info.vl_col; unsigned colors, bpix, bmp_bpix; -#if defined(CONFIG_CPU_PXA) - struct pxafb_info *fbi = &panel_info.pxa; -#elif defined(CONFIG_MPC823) - volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - volatile cpm8xx_t *cp = &(immr->im_cpm); -#endif if (!((bmp->header.signature[0] == 'B') && (bmp->header.signature[1] == 'M'))) { @@ -682,14 +687,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) #if !defined(CONFIG_MCC200) /* MCC200 LCD doesn't need CMAP, supports 1bpp b&w only */ if (bmp_bpix == 8) { -#if defined(CONFIG_CPU_PXA) - cmap = (ushort *)fbi->palette; -#elif defined(CONFIG_MPC823) - cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]); -#elif !defined(CONFIG_ATMEL_LCD) && !defined(CONFIG_EXYNOS_FB) - cmap = panel_info.cmap; -#endif - + cmap = configuration_get_cmap(); cmap_base = cmap; /* Set color map */ -- cgit v1.1 From bfdcc65e1163b4891643c2a670570c478b9af2a4 Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Thu, 9 Aug 2012 00:14:53 +0000 Subject: common lcd: simplify lcd_display_bitmap Move highly platform dependant code into its own functions to reduce the number of #ifdefs in lcd_display_bitmap To avoid breaking the mcc200 board which does not #define CONFIG_CMD_BMP, this patch also implements bmp_display() for mcc200. Signed-off-by: Nikita Kiryanov Signed-off-by: Igor Grinberg --- board/mcc200/lcd.c | 20 ++++++++++++++++++++ common/lcd.c | 44 +++++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/board/mcc200/lcd.c b/board/mcc200/lcd.c index d8f754c..893f4b7 100644 --- a/board/mcc200/lcd.c +++ b/board/mcc200/lcd.c @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef CONFIG_LCD @@ -210,4 +211,23 @@ void show_progress (int size, int tot) } #endif + +int bmp_display(ulong addr, int x, int y) +{ + int ret; + bmp_image_t *bmp = (bmp_image_t *)addr; + + if (!bmp) { + printf("There is no valid bmp file at the given address\n"); + return 1; + } + + ret = lcd_display_bitmap((ulong)bmp, x, y); + + if ((unsigned long)bmp != addr) + free(bmp); + + return ret; +} + #endif /* CONFIG_LCD */ diff --git a/common/lcd.c b/common/lcd.c index 0f93eae..88dfa51 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -636,6 +636,29 @@ static void splash_align_axis(int *axis, unsigned long panel_size, } #endif +#if defined CONFIG_CPU_PXA || defined(CONFIG_ATMEL_LCD) +#define FB_PUT_BYTE(fb, from) *(fb)++ = *(from)++ +#elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200) +#define FB_PUT_BYTE(fb, from) *(fb)++ = (255 - *(from)++) +#endif + +#if defined(CONFIG_BMP_16BPP) +#if defined(CONFIG_ATMEL_LCD_BGR555) +static inline void fb_put_word(uchar **fb, uchar **from) +{ + *(*fb)++ = (((*from)[0] & 0x1f) << 2) | ((*from)[1] & 0x03); + *(*fb)++ = ((*from)[0] & 0xe0) | (((*from)[1] & 0x7c) >> 2); + *from += 2; +} +#else +static inline void fb_put_word(uchar **fb, uchar **from) +{ + *(*fb)++ = *(*from)++; + *(*fb)++ = *(*from)++; +} +#endif +#endif /* CONFIG_BMP_16BPP */ + int lcd_display_bitmap(ulong bmp_image, int x, int y) { #if !defined(CONFIG_MCC200) @@ -761,11 +784,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) WATCHDOG_RESET(); for (j = 0; j < width; j++) { if (bpix != 16) { -#if defined(CONFIG_CPU_PXA) || defined(CONFIG_ATMEL_LCD) - *(fb++) = *(bmap++); -#elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200) - *(fb++) = 255 - *(bmap++); -#endif + FB_PUT_BYTE(fb, bmap); } else { *(uint16_t *)fb = cmap_base[*(bmap++)]; fb += sizeof(uint16_t) / sizeof(*fb); @@ -780,18 +799,9 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) case 16: for (i = 0; i < height; ++i) { WATCHDOG_RESET(); - for (j = 0; j < width; j++) { -#if defined(CONFIG_ATMEL_LCD_BGR555) - *(fb++) = ((bmap[0] & 0x1f) << 2) | - (bmap[1] & 0x03); - *(fb++) = (bmap[0] & 0xe0) | - ((bmap[1] & 0x7c) >> 2); - bmap += 2; -#else - *(fb++) = *(bmap++); - *(fb++) = *(bmap++); -#endif - } + for (j = 0; j < width; j++) + fb_put_word(&fb, &bmap); + bmap += (padded_line - width) * 2; fb -= (width * 2 + lcd_line_length); } -- cgit v1.1 From 5b0c942f8919ed962699a44e0abb4f8a599c52c1 Mon Sep 17 00:00:00 2001 From: Jongman Heo Date: Sun, 3 Jun 2012 21:32:13 +0000 Subject: mmc: fix wrong timeout check in mmc_send_status() (!timeout) condition check in mmc_send_status() can never be met, because do-while loop ends up with negative timeout value, -1. Fix the check to handle TIMEOUT case correctly. Signed-off-by: Jongman Heo Signed-off-by: Andy Fleming --- drivers/mmc/mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index fa673cf..89b674bb 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -236,7 +236,7 @@ int mmc_send_status(struct mmc *mmc, int timeout) status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9; printf("CURR STATE:%d\n", status); #endif - if (!timeout) { + if (timeout <= 0) { printf("Timeout waiting card ready\n"); return TIMEOUT; } -- cgit v1.1 From 97a7b9928aceefb6e9024261b86e49e0e77d6bfd Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 7 Jun 2012 16:39:52 +0000 Subject: mmc: sh_mmcif: enable MMC_MODE_HC The controller can control high capacity cards. So, the patch adds the flag. If the flag is not set, "mmcinfo" will fail when a high capacity card is used. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Andy Fleming --- drivers/mmc/sh_mmcif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 2835e24..4588568 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -593,7 +593,7 @@ int mmcif_mmc_init(void) mmc->f_max = CLKDEV_EMMC_DATA; mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT | - MMC_MODE_8BIT; + MMC_MODE_8BIT | MMC_MODE_HC; memcpy(mmc->name, DRIVER_NAME, sizeof(DRIVER_NAME)); mmc->send_cmd = sh_mmcif_request; mmc->set_ios = sh_mmcif_set_ios; -- cgit v1.1 From cdfd1ac6df16f11fa00e30a76e3c37d61c24b7fa Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 7 Jun 2012 19:09:11 +0000 Subject: mmc: fix capacity calculation when EXT_CSD_SEC_CNT is used Since the type of "ext_csd" was array of char, the following calculation might fail when the value of ext_csd[EXT_CSD_SEC_CNT] was minus. capacity = ext_csd[EXT_CSD_SEC_CNT] << 0 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; So, this patch changes the type of "ext_csd" to array of u8. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Andy Fleming --- drivers/mmc/mmc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 89b674bb..3262740 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -658,7 +658,7 @@ int mmc_send_op_cond(struct mmc *mmc) } -int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd) +int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd) { struct mmc_cmd cmd; struct mmc_data data; @@ -669,7 +669,7 @@ int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd) cmd.resp_type = MMC_RSP_R1; cmd.cmdarg = 0; - data.dest = ext_csd; + data.dest = (char *)ext_csd; data.blocks = 1; data.blocksize = 512; data.flags = MMC_DATA_READ; @@ -704,7 +704,7 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value) int mmc_change_freq(struct mmc *mmc) { - ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512); + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); char cardtype; int err; @@ -963,8 +963,8 @@ int mmc_startup(struct mmc *mmc) uint mult, freq; u64 cmult, csize, capacity; struct mmc_cmd cmd; - ALLOC_CACHE_ALIGN_BUFFER(char, ext_csd, 512); - ALLOC_CACHE_ALIGN_BUFFER(char, test_csd, 512); + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); + ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, 512); int timeout = 1000; #ifdef CONFIG_MMC_SPI_CRC_ON -- cgit v1.1 From 122efd43899597e79bbe0a11298279f90ee55a17 Mon Sep 17 00:00:00 2001 From: Mikhail Kshevetskiy Date: Mon, 9 Jul 2012 08:53:38 +0000 Subject: MMC: u-boot-spl may be compiled without partition support Signed-off-by: Mikhail Kshevetskiy Signed-off-by: Andy Fleming --- drivers/mmc/mmc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 3262740..1f666c2 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1232,7 +1232,9 @@ int mmc_startup(struct mmc *mmc) (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff); sprintf(mmc->block_dev.revision, "%d.%d", mmc->cid[2] >> 28, (mmc->cid[2] >> 24) & 0xf); +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT) init_part(&mmc->block_dev); +#endif return 0; } -- cgit v1.1 From 8948ea830275afaa7c91fe7e13dd3c4b894a453f Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 30 Jul 2012 10:55:43 +0000 Subject: mmc: detect boot sectors using EXT_CSD_BOOT_MULT too Some eMMC devices contain boot partitions, but do not set the PART_SUPPORT bit in EXT_CSD_PARTITIONING_SUPPORT. Allow partition selection on such devices, by enabling partition switching when EXT_CSD_BOOT_MULT is set. Note that the Linux kernel enables access to boot partitions solely based on the value of EXT_CSD_BOOT_MULT; EXT_CSD_PARTITIONING_SUPPORT only influences access to "general" partitions. eMMC devices affected by this issue exist on various NVIDIA Tegra platforms (and presumably many others too), such as Harmony (plug-in eMMC), Seaboard, Springbank, and Whistler (plug-in eMMC). Signed-off-by: Stephen Warren Signed-off-by: Andy Fleming --- drivers/mmc/mmc.c | 3 ++- include/mmc.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 1f666c2..64abe5b 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1137,7 +1137,8 @@ int mmc_startup(struct mmc *mmc) } /* store the partition info of emmc */ - if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) + if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) || + ext_csd[EXT_CSD_BOOT_MULT]) mmc->part_config = ext_csd[EXT_CSD_PART_CONF]; } diff --git a/include/mmc.h b/include/mmc.h index 7b094a4..a13e2bd 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -160,6 +160,7 @@ #define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ +#define EXT_CSD_BOOT_MULT 226 /* RO */ /* * EXT_CSD field definitions -- cgit v1.1 From 9404a5fc7cb58bc56152dfd7d355902dfb666f8b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 30 Jul 2012 10:55:44 +0000 Subject: env_mmc: allow environment to be in an eMMC partition eMMC devices may have hardware-level partitions: 2 boot partitions, up to 4 general partitions, plus the user area. This change introduces optional config variable CONFIG_SYS_MMC_ENV_PART to indicate which partition the environment should be stored in: 0=user, 1=boot0, 2=boot1, 4..7=general0..3. This allows the environment to be kept out of the user area, which simplifies the management of OS-/user-level (MBR/GPT) partitions within the user area. Signed-off-by: Stephen Warren Signed-off-by: Andy Fleming --- common/env_mmc.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/common/env_mmc.c b/common/env_mmc.c index be2f2be..a2ff90b 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -75,9 +75,28 @@ static int init_mmc_for_env(struct mmc *mmc) return -1; } +#ifdef CONFIG_SYS_MMC_ENV_PART + if (CONFIG_SYS_MMC_ENV_PART != mmc->part_num) { + if (mmc_switch_part(CONFIG_SYS_MMC_ENV_DEV, + CONFIG_SYS_MMC_ENV_PART)) { + puts("MMC partition switch failed\n"); + return -1; + } + } +#endif + return 0; } +static void fini_mmc_for_env(struct mmc *mmc) +{ +#ifdef CONFIG_SYS_MMC_ENV_PART + if (CONFIG_SYS_MMC_ENV_PART != mmc->part_num) + mmc_switch_part(CONFIG_SYS_MMC_ENV_DEV, + mmc->part_num); +#endif +} + #ifdef CONFIG_CMD_SAVEENV static inline int write_env(struct mmc *mmc, unsigned long size, unsigned long offset, const void *buffer) @@ -100,26 +119,38 @@ int saveenv(void) char *res; struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); u32 offset; + int ret; - if (init_mmc_for_env(mmc) || mmc_get_env_addr(mmc, &offset)) + if (init_mmc_for_env(mmc)) return 1; + if (mmc_get_env_addr(mmc, &offset)) { + ret = 1; + goto fini; + } + res = (char *)&env_new->data; len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL); if (len < 0) { error("Cannot export environment: errno = %d\n", errno); - return 1; + ret = 1; + goto fini; } env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE); printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV); if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) { puts("failed\n"); - return 1; + ret = 1; + goto fini; } puts("done\n"); - return 0; + ret = 0; + +fini: + fini_mmc_for_env(mmc); + return ret; } #endif /* CONFIG_CMD_SAVEENV */ @@ -143,13 +174,30 @@ void env_relocate_spec(void) ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); u32 offset; + int ret; - if (init_mmc_for_env(mmc) || mmc_get_env_addr(mmc, &offset)) - return set_default_env(NULL); + if (init_mmc_for_env(mmc)) { + ret = 1; + goto err; + } - if (read_env(mmc, CONFIG_ENV_SIZE, offset, buf)) - return set_default_env(NULL); + if (mmc_get_env_addr(mmc, &offset)) { + ret = 1; + goto fini; + } + + if (read_env(mmc, CONFIG_ENV_SIZE, offset, buf)) { + ret = 1; + goto fini; + } env_import(buf, 1); + ret = 0; + +fini: + fini_mmc_for_env(mmc); +err: + if (ret) + set_default_env(NULL); #endif } -- cgit v1.1 From 1c1ec3c0b599e3759f5e232a46f5460221941097 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 30 Jul 2012 10:55:45 +0000 Subject: tegra: put eMMC environment into the boot sectors When I set up Tegra's config files to put the environment into eMMC, I assumed that CONFIG_ENV_OFFSET was a linearized address relative to the start of the eMMC device, and spanning HW partitions boot0, boot1, general* and the user area in order. However, it turns out that the offset is actually relative to the beginning of the user area. Hence, the environment block ended up in a different location to expected and documented. Set CONFIG_SYS_MMC_ENV_PART=2 (boot1) to solve this, and adjust CONFIG_ENV_OFFSET to be relative to the start of boot1, not the entire eMMC. Signed-off-by: Stephen Warren Signed-off-by: Andy Fleming --- include/configs/paz00.h | 3 ++- include/configs/seaboard.h | 3 ++- include/configs/ventana.h | 3 ++- include/configs/whistler.h | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/configs/paz00.h b/include/configs/paz00.h index 0eb9f3b..99b8753 100644 --- a/include/configs/paz00.h +++ b/include/configs/paz00.h @@ -51,8 +51,9 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((2 * 1024 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET ((1024 * 1024) - CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_MMC_ENV_PART 2 /* USB Host support */ #define CONFIG_USB_EHCI diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h index afc4a85..8dc6d4b 100644 --- a/include/configs/seaboard.h +++ b/include/configs/seaboard.h @@ -77,8 +77,9 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((2 * 512 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET ((512 * 1024) - CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_MMC_ENV_PART 2 /* USB Host support */ #define CONFIG_USB_EHCI diff --git a/include/configs/ventana.h b/include/configs/ventana.h index 25ec2eb..f5e1bf8 100644 --- a/include/configs/ventana.h +++ b/include/configs/ventana.h @@ -58,8 +58,9 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((2 * 1024 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET ((1024 * 1024) - CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_MMC_ENV_PART 2 /* USB Host support */ #define CONFIG_USB_EHCI diff --git a/include/configs/whistler.h b/include/configs/whistler.h index b747d0e..3235718 100644 --- a/include/configs/whistler.h +++ b/include/configs/whistler.h @@ -72,8 +72,9 @@ * particular card is standard practice as far as I know. */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((2 * 512 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET ((512 * 1024) - CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_MMC_ENV_PART 2 /* USB Host support */ #define CONFIG_USB_EHCI -- cgit v1.1 From 6bb4b4bc3554c87c342ecbe69fd4a79af7e32741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 08:59:12 +0000 Subject: mmc_get_dev: Return error if mmc_init fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau Cc: Andy Fleming Signed-off-by: Andy Fleming --- drivers/mmc/mmc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 64abe5b..a60cfe1 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1286,10 +1286,9 @@ int mmc_register(struct mmc *mmc) block_dev_desc_t *mmc_get_dev(int dev) { struct mmc *mmc = find_mmc_device(dev); - if (!mmc) + if (!mmc || mmc_init(mmc)) return NULL; - mmc_init(mmc); return &mmc->block_dev; } #endif -- cgit v1.1 From d1424ee544a501b4971d491219158bb0f092fc8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 09:07:38 +0000 Subject: mmcinfo: Fix help message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau Cc: Andy Fleming Signed-off-by: Andy Fleming --- common/cmd_mmc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 750509d..79a1088 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -144,8 +144,7 @@ int do_mmcinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( mmcinfo, 1, 0, do_mmcinfo, "display MMC info", - " - device number of the device to dislay info of\n" - "" + "- dislay info of the current MMC device" ); int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -- cgit v1.1 From 073cfd1c040b9cce9289cacf4d4963460322dc2b Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 10:18:54 +0000 Subject: mmc: Fix version check for clock API in sdhci driver When setting up the clocks in the sdhci driver, the "spec version" must be masked off. Otherwise any time the vendor version is not 0, the check will allways assume the interface is version 3. This breaks when the interface is actually version 1 or 2. Signed-off-by: Joe Hershberger Signed-off-by: Andy Fleming --- drivers/mmc/sdhci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 1709643..b07dc00 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -260,7 +260,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) if (clock == 0) return 0; - if (host->version >= SDHCI_SPEC_300) { + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) { /* Version 3.00 divisors must be a multiple of 2. */ if (mmc->f_max <= clock) div = 1; @@ -347,10 +347,10 @@ void sdhci_set_ios(struct mmc *mmc) ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); if (mmc->bus_width == 8) { ctrl &= ~SDHCI_CTRL_4BITBUS; - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) ctrl |= SDHCI_CTRL_8BITBUS; } else { - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) ctrl &= ~SDHCI_CTRL_8BITBUS; if (mmc->bus_width == 4) ctrl |= SDHCI_CTRL_4BITBUS; @@ -421,7 +421,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) if (max_clk) mmc->f_max = max_clk; else { - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) mmc->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT; else @@ -436,7 +436,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) if (min_clk) mmc->f_min = min_clk; else { - if (host->version >= SDHCI_SPEC_300) + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_300; else mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_200; -- cgit v1.1 From 470dcc7511431db4210a79ea4e6b14cf109a24dc Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 10:18:55 +0000 Subject: mmc: Add a SDHCI quirk for boards that have no CD Some boards have no Card Detect wired. In that case, set the CD test bits in the standard interface. Signed-off-by: Joe Hershberger Signed-off-by: Andy Fleming --- drivers/mmc/sdhci.c | 17 +++++++++++++++-- include/sdhci.h | 7 ++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index b07dc00..3bb0ad0 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -381,12 +381,25 @@ int sdhci_init(struct mmc *mmc) } } + sdhci_set_power(host, fls(mmc->voltages) - 1); + + if (host->quirks & SDHCI_QUIRK_NO_CD) { + unsigned int status; + + sdhci_writel(host, SDHCI_CTRL_CD_TEST_INS | SDHCI_CTRL_CD_TEST, + SDHCI_HOST_CONTROL); + + status = sdhci_readl(host, SDHCI_PRESENT_STATE); + while ((!(status & SDHCI_CARD_PRESENT)) || + (!(status & SDHCI_CARD_STATE_STABLE)) || + (!(status & SDHCI_CARD_DETECT_PIN_LEVEL))) + status = sdhci_readl(host, SDHCI_PRESENT_STATE); + } + /* Eable all state */ sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_ENABLE); sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_SIGNAL_ENABLE); - sdhci_set_power(host, fls(mmc->voltages) - 1); - return 0; } diff --git a/include/sdhci.h b/include/sdhci.h index 9d37183..d41287f 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -76,6 +76,8 @@ #define SDHCI_SPACE_AVAILABLE 0x00000400 #define SDHCI_DATA_AVAILABLE 0x00000800 #define SDHCI_CARD_PRESENT 0x00010000 +#define SDHCI_CARD_STATE_STABLE 0x00020000 +#define SDHCI_CARD_DETECT_PIN_LEVEL 0x00040000 #define SDHCI_WRITE_PROTECT 0x00080000 #define SDHCI_HOST_CONTROL 0x28 @@ -87,7 +89,9 @@ #define SDHCI_CTRL_ADMA1 0x08 #define SDHCI_CTRL_ADMA32 0x10 #define SDHCI_CTRL_ADMA64 0x18 -#define SDHCI_CTRL_8BITBUS 0x20 +#define SDHCI_CTRL_8BITBUS 0x20 +#define SDHCI_CTRL_CD_TEST_INS 0x40 +#define SDHCI_CTRL_CD_TEST 0x80 #define SDHCI_POWER_CONTROL 0x29 #define SDHCI_POWER_ON 0x01 @@ -219,6 +223,7 @@ #define SDHCI_QUIRK_BROKEN_R1B (1 << 2) #define SDHCI_QUIRK_NO_HISPD_BIT (1 << 3) #define SDHCI_QUIRK_BROKEN_VOLTAGE (1 << 4) +#define SDHCI_QUIRK_NO_CD (1 << 5) /* to make gcc happy */ struct sdhci_host; -- cgit v1.1 From b268660cedab938f40e64456da1cf72da05bc808 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Thu, 30 Aug 2012 16:24:08 +0000 Subject: mmc: s5p_sdhci: set the SDHCI_QUIRK_BROKEN_R1B Samsung SoC is broken busy waiting for R1b type. And clk delay control value is modified the previosuly value. (that value used at the s5p_mmc.c) Signed-off-by: Jaehoon Chung Signed-off-by: Kyungmin Park Signed-off-by: Andy Fleming --- drivers/mmc/s5p_sdhci.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 1d4481b..6a04bd7 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -54,7 +54,7 @@ static void s5p_sdhci_set_control_reg(struct sdhci_host *host) * 00 = Delay3 (inverter delay) * 10 = Delay4 (inverter delay + 2ns) */ - val = SDHCI_CTRL3_FCSEL3 | SDHCI_CTRL3_FCSEL1; + val = SDHCI_CTRL3_FCSEL0 | SDHCI_CTRL3_FCSEL1; sdhci_writel(host, val, SDHCI_CONTROL3); /* @@ -82,12 +82,10 @@ int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks) host->ioaddr = (void *)regbase; host->quirks = quirks; - host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE; + host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE | + SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR; host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - if (quirks & SDHCI_QUIRK_REG32_RW) - host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16; - else - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); + host->version = sdhci_readw(host, SDHCI_HOST_VERSION); host->set_control_reg = &s5p_sdhci_set_control_reg; -- cgit v1.1 From 8458e0283f041a39c80cae9e2ba67ed3c8ebd73c Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Thu, 30 Aug 2012 16:24:10 +0000 Subject: mmc: s5p_sdhci: fixed wrong function argument Useless code is removed, and get buswidth value. buswidth value will be used to choice the 4bit or 8bit. (Now used 4bit mode in sdhci.c by default) Signed-off-by: Jaehoon Chung Signed-off-by: Kyungmin Park Signed-off-by: Andy Fleming --- arch/arm/include/asm/arch-exynos/mmc.h | 4 ++-- arch/arm/include/asm/arch-s5pc1xx/mmc.h | 4 ++-- drivers/mmc/s5p_sdhci.c | 5 ++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/arm/include/asm/arch-exynos/mmc.h b/arch/arm/include/asm/arch-exynos/mmc.h index 0f701c9..afdfcf0 100644 --- a/arch/arm/include/asm/arch-exynos/mmc.h +++ b/arch/arm/include/asm/arch-exynos/mmc.h @@ -64,11 +64,11 @@ #define SDHCI_CTRL4_DRIVE_MASK(_x) ((_x) << 16) #define SDHCI_CTRL4_DRIVE_SHIFT (16) -int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks); +int s5p_sdhci_init(u32 regbase, int index, int bus_width); static inline unsigned int s5p_mmc_init(int index, int bus_width) { unsigned int base = samsung_get_base_mmc() + (0x10000 * index); - return s5p_sdhci_init(base, 52000000, 400000, index); + return s5p_sdhci_init(base, index, bus_width); } #endif diff --git a/arch/arm/include/asm/arch-s5pc1xx/mmc.h b/arch/arm/include/asm/arch-s5pc1xx/mmc.h index 0f701c9..afdfcf0 100644 --- a/arch/arm/include/asm/arch-s5pc1xx/mmc.h +++ b/arch/arm/include/asm/arch-s5pc1xx/mmc.h @@ -64,11 +64,11 @@ #define SDHCI_CTRL4_DRIVE_MASK(_x) ((_x) << 16) #define SDHCI_CTRL4_DRIVE_SHIFT (16) -int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks); +int s5p_sdhci_init(u32 regbase, int index, int bus_width); static inline unsigned int s5p_mmc_init(int index, int bus_width) { unsigned int base = samsung_get_base_mmc() + (0x10000 * index); - return s5p_sdhci_init(base, 52000000, 400000, index); + return s5p_sdhci_init(base, index, bus_width); } #endif diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 6a04bd7..9378e36 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -69,7 +69,7 @@ static void s5p_sdhci_set_control_reg(struct sdhci_host *host) sdhci_writel(host, ctrl, SDHCI_CONTROL2); } -int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks) +int s5p_sdhci_init(u32 regbase, int index, int bus_width) { struct sdhci_host *host = NULL; host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); @@ -80,7 +80,6 @@ int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks) host->name = S5P_NAME; host->ioaddr = (void *)regbase; - host->quirks = quirks; host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE | SDHCI_QUIRK_BROKEN_R1B | SDHCI_QUIRK_32BIT_DMA_ADDR; @@ -91,6 +90,6 @@ int s5p_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks) host->host_caps = MMC_MODE_HC; - add_sdhci(host, max_clk, min_clk); + add_sdhci(host, 52000000, 400000); return 0; } -- cgit v1.1 From b09ed6e4fe6065851751e7fc381ff40c23fb09f1 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Thu, 30 Aug 2012 16:24:11 +0000 Subject: mmc: s5p_sdhci: add the set_mmc_clk for cmu control Samsung SoC use the cmu control to set clock. Signed-off-by: Jaehoon Chung Signed-off-by: Kyungmin Park Signed-off-by: Andy Fleming --- drivers/mmc/s5p_sdhci.c | 3 +++ drivers/mmc/sdhci.c | 3 +++ include/configs/trats.h | 1 + include/sdhci.h | 2 ++ 4 files changed, 9 insertions(+) diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 9378e36..b978236 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -21,6 +21,7 @@ #include #include #include +#include static char *S5P_NAME = "SAMSUNG SDHCI"; static void s5p_sdhci_set_control_reg(struct sdhci_host *host) @@ -87,6 +88,8 @@ int s5p_sdhci_init(u32 regbase, int index, int bus_width) host->version = sdhci_readw(host, SDHCI_HOST_VERSION); host->set_control_reg = &s5p_sdhci_set_control_reg; + host->set_clock = set_mmc_clk; + host->index = index; host->host_caps = MMC_MODE_HC; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 3bb0ad0..2e3c408 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -279,6 +279,9 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) } div >>= 1; + if (host->set_clock) + host->set_clock(host->index, div); + clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) << SDHCI_DIVIDER_HI_SHIFT; diff --git a/include/configs/trats.h b/include/configs/trats.h index f8da9c01..794b6fb 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -78,6 +78,7 @@ #define CONFIG_MMC #define CONFIG_S5P_SDHCI #define CONFIG_SDHCI +#define CONFIG_MMC_SDMA /* PWM */ #define CONFIG_PWM diff --git a/include/sdhci.h b/include/sdhci.h index d41287f..c0345ed 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -253,8 +253,10 @@ struct sdhci_host { unsigned int clock; struct mmc *mmc; const struct sdhci_ops *ops; + int index; void (*set_control_reg)(struct sdhci_host *host); + void (*set_clock)(int dev_index, unsigned int div); uint voltages; }; -- cgit v1.1 From a532278074f1d1fa7d46b144e0d4b824ae7d3335 Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Wed, 8 Aug 2012 00:57:35 +0000 Subject: omap4 i2c: add support for i2c bus 4 Signed-off-by: Koen Kooi --- arch/arm/include/asm/arch-omap4/cpu.h | 1 + arch/arm/include/asm/arch-omap4/i2c.h | 2 +- drivers/i2c/omap24xx_i2c.c | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/arch-omap4/cpu.h b/arch/arm/include/asm/arch-omap4/cpu.h index a8c4c60..3a0bfbf 100644 --- a/arch/arm/include/asm/arch-omap4/cpu.h +++ b/arch/arm/include/asm/arch-omap4/cpu.h @@ -138,6 +138,7 @@ struct watchdog { #define I2C_BASE1 (OMAP44XX_L4_PER_BASE + 0x70000) #define I2C_BASE2 (OMAP44XX_L4_PER_BASE + 0x72000) #define I2C_BASE3 (OMAP44XX_L4_PER_BASE + 0x60000) +#define I2C_BASE4 (OMAP44XX_L4_PER_BASE + 0x350000) /* MUSB base */ #define MUSB_BASE (OMAP44XX_L4_CORE_BASE + 0xAB000) diff --git a/arch/arm/include/asm/arch-omap4/i2c.h b/arch/arm/include/asm/arch-omap4/i2c.h index a91b4c2..02ee2f8 100644 --- a/arch/arm/include/asm/arch-omap4/i2c.h +++ b/arch/arm/include/asm/arch-omap4/i2c.h @@ -23,7 +23,7 @@ #ifndef _OMAP4_I2C_H_ #define _OMAP4_I2C_H_ -#define I2C_BUS_MAX 3 +#define I2C_BUS_MAX 4 #define I2C_DEFAULT_BASE I2C_BASE1 struct i2c { diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c index 978507b..094305f 100644 --- a/drivers/i2c/omap24xx_i2c.c +++ b/drivers/i2c/omap24xx_i2c.c @@ -442,6 +442,14 @@ int i2c_set_bus_num(unsigned int bus) return -1; } +#if I2C_BUS_MAX == 4 + if (bus == 3) + i2c_base = (struct i2c *)I2C_BASE4; + else + if (bus == 2) + i2c_base = (struct i2c *)I2C_BASE3; + else +#endif #if I2C_BUS_MAX == 3 if (bus == 2) i2c_base = (struct i2c *)I2C_BASE3; -- cgit v1.1 From 95b01c47ed97a7ca8b59308e35fb8c21e8d996a5 Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Thu, 6 Sep 2012 15:23:13 -0500 Subject: mmc: Remove incorrect cmd->flags usage There were a couple of drivers that were actually using the flags field of the cmd structure, despite the fact that no one ever *set* that field. When we removed the field, those drivers failed to compile. Replaced the references with the correct usage of resp_type. Signed-off-by: Andy Fleming --- drivers/mmc/arm_pl180_mmci.c | 2 +- drivers/mmc/pxa_mmc_gen.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index db2c7ab..af1380a 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -52,7 +52,7 @@ static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd) debug("CMD%d time out\n", cmd->cmdidx); return TIMEOUT; } else if ((hoststatus & SDI_STA_CCRCFAIL) && - (cmd->flags & MMC_RSP_CRC)) { + (cmd->resp_type & MMC_RSP_CRC)) { printf("CMD%d CRC error\n", cmd->cmdidx); return -EILSEQ; } diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index 2c5bf17..b3ec441 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -118,7 +118,7 @@ static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd, int ret; /* The card can send a "busy" response */ - if (cmd->flags & MMC_RSP_BUSY) + if (cmd->resp_type & MMC_RSP_BUSY) cmdat |= MMC_CMDAT_BUSY; /* Inform the controller about response type */ @@ -181,9 +181,11 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) /* The command response didn't arrive */ if (stat & MMC_STAT_TIME_OUT_RESPONSE) return -ETIMEDOUT; - else if (stat & MMC_STAT_RES_CRC_ERROR && cmd->flags & MMC_RSP_CRC) { + else if (stat & MMC_STAT_RES_CRC_ERROR + && cmd->resp_type & MMC_RSP_CRC) { #ifdef PXAMMC_CRC_SKIP - if (cmd->flags & MMC_RSP_136 && cmd->response[0] & (1 << 31)) + if (cmd->resp_type & MMC_RSP_136 + && cmd->response[0] & (1 << 31)) printf("Ignoring CRC, this may be dangerous!\n"); else #endif -- cgit v1.1 From 8044c1387f7f8acb2a82f64f1b087848395deb15 Mon Sep 17 00:00:00 2001 From: Veli-Pekka Peltola Date: Wed, 5 Sep 2012 18:05:14 +0300 Subject: ubifs: Fix ubifsload when using ZLIB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using ZLIB compression with UBIFS fails if last data node is not a size of UBIFS_BLOCK_SIZE (4096 bytes). Easiest way to test this is trying to read a file smaller than 4k: => ubifsload 41000000 /etc/fstab Loading file '/etc/fstab' to addr 0x41000000 with size 704 (0x000002c0)... UBIFS error (pid 0): read_block: bad data node (block 0, inode 2506) UBIFS error (pid 0): do_readpage: cannot read page 0 of inode 2506, error -22 Error reading file '/etc/fstab' /etc/fstab not found! exit not allowed from main input shell. => With this patch: => ubifsload 41000000 /etc/fstab Loading file '/etc/fstab' to addr 0x41000000 with size 704 (0x000002c0)... Done => Signed-off-by: Veli-Pekka Peltola Cc: kmpark@infradead.org Tested-by: Andreas Bießmann Signed-off-by: Stefan Roese --- fs/ubifs/ubifs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c index c68802b..44be3f5 100644 --- a/fs/ubifs/ubifs.c +++ b/fs/ubifs/ubifs.c @@ -37,8 +37,8 @@ DECLARE_GLOBAL_DATA_PTR; static int gzip_decompress(const unsigned char *in, size_t in_len, unsigned char *out, size_t *out_len) { - unsigned long len = in_len; - return zunzip(out, *out_len, (unsigned char *)in, &len, 0, 0); + return zunzip(out, *out_len, (unsigned char *)in, + (unsigned long *)out_len, 0, 0); } /* Fake description object for the "none" compressor */ -- cgit v1.1 From 5340a7f1d74ba65c4c63d6d9d0ad606553866ffe Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 4 Jul 2012 12:09:45 +0200 Subject: block: systemace: Simplify base and width initialization Use CONFIG parameters only at one location to simplify the code. Also create ace_readw/writew functions. Signed-off-by: Michal Simek --- drivers/block/systemace.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c index 58402b9..247cf06 100644 --- a/drivers/block/systemace.c +++ b/drivers/block/systemace.c @@ -51,24 +51,36 @@ * to be the base address for the chip, usually in the local * peripheral bus. */ -#if (CONFIG_SYS_SYSTEMACE_WIDTH == 8) + +static u32 base = CONFIG_SYS_SYSTEMACE_BASE; +static u32 width = CONFIG_SYS_SYSTEMACE_WIDTH; + +static void ace_writew(u16 val, unsigned off) +{ + if (width == 8) { #if !defined(__BIG_ENDIAN) -#define ace_readw(off) ((readb(CONFIG_SYS_SYSTEMACE_BASE+off)<<8) | \ - (readb(CONFIG_SYS_SYSTEMACE_BASE+off+1))) -#define ace_writew(val, off) {writeb(val>>8, CONFIG_SYS_SYSTEMACE_BASE+off); \ - writeb(val, CONFIG_SYS_SYSTEMACE_BASE+off+1);} + writeb(val >> 8, base + off); + writeb(val, base + off + 1); #else -#define ace_readw(off) ((readb(CONFIG_SYS_SYSTEMACE_BASE+off)) | \ - (readb(CONFIG_SYS_SYSTEMACE_BASE+off+1)<<8)) -#define ace_writew(val, off) {writeb(val, CONFIG_SYS_SYSTEMACE_BASE+off); \ - writeb(val>>8, CONFIG_SYS_SYSTEMACE_BASE+off+1);} + writeb(val, base + off); + writeb(val >> 8, base + off + 1); #endif + } + out16(base + off, val); +} + +static u16 ace_readw(unsigned off) +{ + if (width == 8) { +#if !defined(__BIG_ENDIAN) + return (readb(base + off) << 8) | readb(base + off + 1); #else -#define ace_readw(off) (in16(CONFIG_SYS_SYSTEMACE_BASE+off)) -#define ace_writew(val, off) (out16(CONFIG_SYS_SYSTEMACE_BASE+off,val)) + return readb(base + off) | (readb(base + off + 1) << 8); #endif + } -/* */ + return in16(base + off); +} static unsigned long systemace_read(int dev, unsigned long start, unsigned long blkcnt, void *buffer); @@ -121,7 +133,7 @@ block_dev_desc_t *systemace_get_dev(int dev) /* * Ensure the correct bus mode (8/16 bits) gets enabled */ - ace_writew(CONFIG_SYS_SYSTEMACE_WIDTH == 8 ? 0 : 0x0001, 0); + ace_writew(width == 8 ? 0 : 0x0001, 0); init_part(&systemace_dev); -- cgit v1.1 From 7636ebe1d27b6cf7bf3b64d695ef8f07b7629178 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 2 Jul 2012 12:38:14 +0200 Subject: serial: Support serial multi for Microblaze enable serial multi for Microblaze. Signed-off-by: Michal Simek Acked-by: Stephan Linz --- include/serial.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/serial.h b/include/serial.h index cbdf8a9..d76d6df 100644 --- a/include/serial.h +++ b/include/serial.h @@ -31,7 +31,8 @@ extern struct serial_device *default_serial_console(void); defined(CONFIG_MB86R0x) || defined(CONFIG_MPC5xxx) || \ defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) || \ defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520) || \ - defined(CONFIG_TEGRA20) || defined(CONFIG_SYS_COREBOOT) + defined(CONFIG_TEGRA20) || defined(CONFIG_SYS_COREBOOT) || \ + defined(CONFIG_MICROBLAZE) extern struct serial_device serial0_device; extern struct serial_device serial1_device; #if defined(CONFIG_SYS_NS16550_SERIAL) -- cgit v1.1 From 25239e12d9059d75c0ac12c26691a00321aad0cc Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 2 Jul 2012 10:32:18 +0200 Subject: serial: uartlite: Init all uartlites for serial multi Initialize all possible uartlites and return the first initialized port. For static configuration is initialization done in userial_ports array. Signed-off-by: Michal Simek Acked-by: Stephan Linz --- drivers/serial/serial_xuartlite.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 3a38f9e..2bdb68b 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -89,11 +89,17 @@ int uartlite_serial_tstc(const int port) return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA; } +static int uartlite_serial_init(const int port) +{ + if (userial_ports[port]) + return 0; + return -1; +} + #if !defined(CONFIG_SERIAL_MULTI) int serial_init(void) { - /* FIXME: Nothing for now. We should initialize fifo, etc */ - return 0; + return uartlite_serial_init(0); } void serial_setbrg(void) @@ -126,7 +132,7 @@ int serial_tstc(void) /* Multi serial device functions */ #define DECLARE_ESERIAL_FUNCTIONS(port) \ int userial##port##_init(void) \ - { return(0); } \ + { return uartlite_serial_init(port); } \ void userial##port##_setbrg(void) {} \ int userial##port##_getc(void) \ { return uartlite_serial_getc(port); } \ @@ -163,17 +169,15 @@ struct serial_device uartlite_serial3_device = __weak struct serial_device *default_serial_console(void) { -# ifdef XILINX_UARTLITE_BASEADDR - return &uartlite_serial0_device; -# endif /* XILINX_UARTLITE_BASEADDR */ -# ifdef XILINX_UARTLITE_BASEADDR1 - return &uartlite_serial1_device; -# endif /* XILINX_UARTLITE_BASEADDR1 */ -# ifdef XILINX_UARTLITE_BASEADDR2 - return &uartlite_serial2_device; -# endif /* XILINX_UARTLITE_BASEADDR2 */ -# ifdef XILINX_UARTLITE_BASEADDR3 - return &uartlite_serial3_device; -# endif /* XILINX_UARTLITE_BASEADDR3 */ + if (userial_ports[0]) + return &uartlite_serial0_device; + if (userial_ports[1]) + return &uartlite_serial1_device; + if (userial_ports[2]) + return &uartlite_serial2_device; + if (userial_ports[3]) + return &uartlite_serial3_device; + + return NULL; } #endif /* CONFIG_SERIAL_MULTI */ -- cgit v1.1 From 03afad2fc90dcff42402b0183f4b4f5119f99a18 Mon Sep 17 00:00:00 2001 From: Stephan Linz Date: Tue, 7 Aug 2012 23:29:39 +0200 Subject: spi: xilinx: Remove unused variable Warning is: xilinx_spi.c: In function 'spi_setup_slave': xilinx_spi.c:81: warning: unused variable 'regs' Signed-off-by: Stephan Linz CC: Michal Simek --- drivers/spi/xilinx_spi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index e563c19..52a4134 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -78,7 +78,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int mode) { struct xilinx_spi_slave *xilspi; - struct xilinx_spi_reg *regs; if (!spi_cs_is_valid(bus, cs)) { printf("XILSPI error: %s: unsupported bus %d / cs %d\n", -- cgit v1.1 From b710d9d6c2921982a448903d3c10a14d6ee22ae3 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 28 Jun 2012 14:34:32 +0200 Subject: microblaze: Add support for device tree driven board configuration This is minimum code required to be able to use device-tree for u-boot initialization. Currently only for device driver initialization. Linker script change ensures DTB to be aligned for both options CONFIG_OF_EMBED and CONFIG_OF_SEPARATE. Signed-off-by: Michal Simek Acked-by: Stephan Linz CC: Simon Glass --- arch/microblaze/config.mk | 2 ++ arch/microblaze/cpu/u-boot.lds | 1 + arch/microblaze/include/asm/global_data.h | 1 + arch/microblaze/lib/board.c | 24 ++++++++++++++++++++++++ 4 files changed, 28 insertions(+) diff --git a/arch/microblaze/config.mk b/arch/microblaze/config.mk index aca79e2..b4935f0 100644 --- a/arch/microblaze/config.mk +++ b/arch/microblaze/config.mk @@ -31,3 +31,5 @@ CONFIG_STANDALONE_LOAD_ADDR ?= 0x80F00000 PLATFORM_CPPFLAGS += -ffixed-r31 -D__microblaze__ LDSCRIPT ?= $(SRCTREE)/$(CPUDIR)/u-boot.lds + +CONFIG_ARCH_DEVICE_TREE := microblaze diff --git a/arch/microblaze/cpu/u-boot.lds b/arch/microblaze/cpu/u-boot.lds index ee41145..d033a28 100644 --- a/arch/microblaze/cpu/u-boot.lds +++ b/arch/microblaze/cpu/u-boot.lds @@ -45,6 +45,7 @@ SECTIONS .data ALIGN(0x4): { __data_start = .; + dts/libdts.o (.data) *(.data) __data_end = .; } diff --git a/arch/microblaze/include/asm/global_data.h b/arch/microblaze/include/asm/global_data.h index 0dc4ce9..de3b8db 100644 --- a/arch/microblaze/include/asm/global_data.h +++ b/arch/microblaze/include/asm/global_data.h @@ -41,6 +41,7 @@ typedef struct global_data { unsigned long precon_buf_idx; /* Pre-Console buffer index */ #endif unsigned long env_addr; /* Address of Environment struct */ + const void *fdt_blob; /* Our device tree, NULL if none */ unsigned long env_valid; /* Checksum of Environment valid? */ unsigned long fb_base; /* base address of frame buffer */ void **jt; /* jump table */ diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c index b80250a..942e18c 100644 --- a/arch/microblaze/lib/board.c +++ b/arch/microblaze/lib/board.c @@ -34,6 +34,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -63,6 +64,9 @@ typedef int (init_fnc_t) (void); init_fnc_t *init_sequence[] = { env_init, +#ifdef CONFIG_OF_CONTROL + fdtdec_check_fdt, +#endif serial_init, console_init_f, #ifdef CONFIG_SYS_GPIO_0 @@ -103,6 +107,17 @@ void board_init (void) monitor_flash_len = __end - __text_start; +#ifdef CONFIG_OF_EMBED + /* Get a pointer to the FDT */ + gd->fdt_blob = _binary_dt_dtb_start; +#elif defined CONFIG_OF_SEPARATE + /* FDT is at end of image */ + gd->fdt_blob = (void *)__end; +#endif + /* Allow the early environment to override the fdt address */ + gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, + (uintptr_t)gd->fdt_blob); + /* * The Malloc area is immediately below the monitor copy in DRAM * aka CONFIG_SYS_MONITOR_BASE - Note there is no need for reloc_off @@ -121,6 +136,15 @@ void board_init (void) } } +#ifdef CONFIG_OF_CONTROL + /* For now, put this check after the console is ready */ + if (fdtdec_prepare_fdt()) { + panic("** CONFIG_OF_CONTROL defined but no FDT - please see " + "doc/README.fdt-control"); + } else + printf("DTB: 0x%x\n", (u32)gd->fdt_blob); +#endif + puts ("SDRAM :\n"); printf ("\t\tIcache:%s\n", icache_status() ? "ON" : "OFF"); printf ("\t\tDcache:%s\n", dcache_status() ? "ON" : "OFF"); -- cgit v1.1 From e35c05baa17fc049f32c675b6ee0aaa109980dcb Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 29 Jun 2012 10:29:46 +0200 Subject: microblaze: board: Remove compilation warning Variable is used when CONFIG_SYS_FLASH_CHECKSUM is used. Warning log: board.c: In function 'board_init': board.c:101: warning: unused variable 's' Signed-off-by: Michal Simek Acked-by: Stephan Linz --- arch/microblaze/lib/board.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c index 942e18c..b5f21d8 100644 --- a/arch/microblaze/lib/board.c +++ b/arch/microblaze/lib/board.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -91,7 +92,7 @@ void board_init (void) gd = (gd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET); bd = (bd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET \ - GENERATED_BD_INFO_SIZE); - char *s; + __maybe_unused char *s; #if defined(CONFIG_CMD_FLASH) ulong flash_size = 0; #endif -- cgit v1.1 From 8706908a2522f7d38f916e38ee13ca91e9f30bc5 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 29 Jun 2012 14:21:52 +0200 Subject: microblaze: intc: Registering interrupt should return value Return value to find out if un/registration was succesful. Signed-off-by: Michal Simek --- arch/microblaze/cpu/interrupts.c | 16 +++++++++------- arch/microblaze/include/asm/microblaze_intc.h | 11 ++++++++++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/arch/microblaze/cpu/interrupts.c b/arch/microblaze/cpu/interrupts.c index ee67082..08f6bad 100644 --- a/arch/microblaze/cpu/interrupts.c +++ b/arch/microblaze/cpu/interrupts.c @@ -91,14 +91,13 @@ static void disable_one_interrupt(int irq) #endif } -/* adding new handler for interrupt */ -void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg) +int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, void *arg) { struct irq_action *act; /* irq out of range */ if ((irq < 0) || (irq > irq_no)) { puts ("IRQ out of range\n"); - return; + return -1; } act = &vecs[irq]; if (hdlr) { /* enable */ @@ -106,11 +105,14 @@ void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg) act->arg = arg; act->count = 0; enable_one_interrupt (irq); - } else { /* disable */ - act->handler = (interrupt_handler_t *) def_hdlr; - act->arg = (void *)irq; - disable_one_interrupt (irq); + return 0; } + + /* Disable */ + act->handler = (interrupt_handler_t *) def_hdlr; + act->arg = (void *)irq; + disable_one_interrupt(irq); + return 1; } /* initialization interrupt controller - hardware */ diff --git a/arch/microblaze/include/asm/microblaze_intc.h b/arch/microblaze/include/asm/microblaze_intc.h index 6142b9c..e9640f5 100644 --- a/arch/microblaze/include/asm/microblaze_intc.h +++ b/arch/microblaze/include/asm/microblaze_intc.h @@ -39,7 +39,16 @@ struct irq_action { int count; /* number of interrupt */ }; -void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, +/** + * Register and unregister interrupt handler rutines + * + * @param irq IRQ number + * @param hdlr Interrupt handler rutine + * @param arg Pointer to argument which is passed to int. handler rutine + * @return 0 if registration pass, 1 if unregistration pass, + * or an error code < 0 otherwise + */ +int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, void *arg); int interrupts_init(void); -- cgit v1.1 From 26e6da854e70be8e3fb0dab7bbe41119b701ebe1 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 29 Jun 2012 13:27:28 +0200 Subject: microblaze: intc: Coding style cleanup Just coding style cleanup. Remove unneeded externs. Signed-off-by: Michal Simek Acked-by: Simon Glass Acked-by: Stephan Linz --- arch/microblaze/cpu/interrupts.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/microblaze/cpu/interrupts.c b/arch/microblaze/cpu/interrupts.c index 08f6bad..7f2ee64 100644 --- a/arch/microblaze/cpu/interrupts.c +++ b/arch/microblaze/cpu/interrupts.c @@ -32,15 +32,12 @@ #undef DEBUG_INT -extern void microblaze_disable_interrupts (void); -extern void microblaze_enable_interrupts (void); - -void enable_interrupts (void) +void enable_interrupts(void) { MSRSET(0x2); } -int disable_interrupts (void) +int disable_interrupts(void) { unsigned int msr; @@ -58,20 +55,21 @@ microblaze_intc_t *intc; /* default handler */ static void def_hdlr(void) { - puts ("def_hdlr\n"); + puts("def_hdlr\n"); } static void enable_one_interrupt(int irq) { int mask; int offset = 1; + offset <<= irq; mask = intc->ier; intc->ier = (mask | offset); #ifdef DEBUG_INT - printf ("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask, + printf("Enable one interrupt irq %x - mask %x,ier %x\n", offset, mask, intc->ier); - printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, intc->iar, intc->mer); #endif } @@ -80,13 +78,14 @@ static void disable_one_interrupt(int irq) { int mask; int offset = 1; + offset <<= irq; mask = intc->ier; intc->ier = (mask & ~offset); #ifdef DEBUG_INT - printf ("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask, + printf("Disable one interrupt irq %x - mask %x,ier %x\n", irq, mask, intc->ier); - printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, intc->iar, intc->mer); #endif } @@ -94,9 +93,10 @@ static void disable_one_interrupt(int irq) int install_interrupt_handler(int irq, interrupt_handler_t *hdlr, void *arg) { struct irq_action *act; + /* irq out of range */ if ((irq < 0) || (irq > irq_no)) { - puts ("IRQ out of range\n"); + puts("IRQ out of range\n"); return -1; } act = &vecs[irq]; @@ -124,7 +124,7 @@ static void intc_init(void) /* XIntc_Start - hw_interrupt enable and all interrupt enable */ intc->mer = 0x3; #ifdef DEBUG_INT - printf ("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, + printf("INTC isr %x, ier %x, iar %x, mer %x\n", intc->isr, intc->ier, intc->iar, intc->mer); #endif } @@ -159,7 +159,7 @@ int interrupts_init(void) return 0; } -void interrupt_handler (void) +void interrupt_handler(void) { int irqs = intc->ivr; /* find active interrupt */ int mask = 1; -- cgit v1.1 From bcbb046bd5cba6acb07aa99cad728726be8359e6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 29 Jun 2012 13:46:54 +0200 Subject: microblaze: timer: Prepare for device-tree initialization Fix CONFIG_SYS_HZ usage in board config. Do not use hardcoded value. Use CONFIG_SYS_HZ instead. Separate static configuration to single block. Signed-off-by: Michal Simek --- arch/microblaze/cpu/timer.c | 69 ++++++++++++++------------ arch/microblaze/include/asm/microblaze_timer.h | 3 ++ arch/microblaze/lib/board.c | 5 -- include/configs/microblaze-generic.h | 12 +---- 4 files changed, 41 insertions(+), 48 deletions(-) diff --git a/arch/microblaze/cpu/timer.c b/arch/microblaze/cpu/timer.c index cc6b897..1330401 100644 --- a/arch/microblaze/cpu/timer.c +++ b/arch/microblaze/cpu/timer.c @@ -27,42 +27,30 @@ #include volatile int timestamp = 0; +microblaze_timer_t *tmr; -#ifdef CONFIG_SYS_TIMER_0 ulong get_timer (ulong base) { - return (timestamp - base); + if (tmr) + return timestamp - base; + return timestamp++ - base; } -#else -ulong get_timer (ulong base) -{ - return (timestamp++ - base); -} -#endif -#ifdef CONFIG_SYS_TIMER_0 void __udelay(unsigned long usec) { - int i; + u32 i; - i = get_timer(0); - while ((get_timer(0) - i) < (usec / 1000)) - ; + if (tmr) { + i = get_timer(0); + while ((get_timer(0) - i) < (usec / 1000)) + ; + } else { + for (i = 0; i < (usec * XILINX_CLOCK_FREQ / 10000000); i++) + ; + } } -#else -void __udelay(unsigned long usec) -{ - unsigned int i; - for (i = 0; i < (usec * CONFIG_XILINX_CLOCK_FREQ / 10000000); i++) - ; -} -#endif - -#ifdef CONFIG_SYS_TIMER_0 -microblaze_timer_t *tmr = (microblaze_timer_t *) (CONFIG_SYS_TIMER_0_ADDR); - -void timer_isr (void *arg) +static void timer_isr(void *arg) { timestamp++; tmr->control = tmr->control | TIMER_INTERRUPT; @@ -70,15 +58,30 @@ void timer_isr (void *arg) int timer_init (void) { - tmr->loadreg = CONFIG_SYS_TIMER_0_PRELOAD; - tmr->control = TIMER_INTERRUPT | TIMER_RESET; - tmr->control = - TIMER_ENABLE | TIMER_ENABLE_INTR | TIMER_RELOAD | TIMER_DOWN_COUNT; - timestamp = 0; - install_interrupt_handler (CONFIG_SYS_TIMER_0_IRQ, timer_isr, (void *)tmr); + int irq = -1; + u32 preload = 0; + u32 ret = 0; + +#if defined(CONFIG_SYS_TIMER_0_ADDR) && defined(CONFIG_SYS_INTC_0_NUM) + preload = XILINX_CLOCK_FREQ / CONFIG_SYS_HZ; + irq = CONFIG_SYS_TIMER_0_IRQ; + tmr = (microblaze_timer_t *) (CONFIG_SYS_TIMER_0_ADDR); +#endif + + if (tmr && preload && irq >= 0) { + tmr->loadreg = preload; + tmr->control = TIMER_INTERRUPT | TIMER_RESET; + tmr->control = TIMER_ENABLE | TIMER_ENABLE_INTR |\ + TIMER_RELOAD | TIMER_DOWN_COUNT; + timestamp = 0; + ret = install_interrupt_handler (irq, timer_isr, (void *)tmr); + if (ret) + tmr = NULL; + } + + /* No problem if timer is not found/initialized */ return 0; } -#endif /* * This function is derived from PowerPC code (read timebase as long long). diff --git a/arch/microblaze/include/asm/microblaze_timer.h b/arch/microblaze/include/asm/microblaze_timer.h index 844c8db..28e8b02 100644 --- a/arch/microblaze/include/asm/microblaze_timer.h +++ b/arch/microblaze/include/asm/microblaze_timer.h @@ -39,3 +39,6 @@ typedef volatile struct microblaze_timer_t { int loadreg; /* load register TLR */ int counter; /* timer/counter register */ } microblaze_timer_t; + +int timer_init(void); + diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c index b5f21d8..fde109f 100644 --- a/arch/microblaze/lib/board.c +++ b/arch/microblaze/lib/board.c @@ -42,9 +42,6 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_SYS_GPIO_0 extern int gpio_init (void); #endif -#ifdef CONFIG_SYS_TIMER_0 -extern int timer_init (void); -#endif #ifdef CONFIG_SYS_FSL_2 extern void fsl_init2 (void); #endif @@ -74,9 +71,7 @@ init_fnc_t *init_sequence[] = { gpio_init, #endif interrupts_init, -#ifdef CONFIG_SYS_TIMER_0 timer_init, -#endif #ifdef CONFIG_SYS_FSL_2 fsl_init2, #endif diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 1266cf7..721cd90 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -115,19 +115,11 @@ #endif /* timer */ -#ifdef XILINX_TIMER_BASEADDR -# if (XILINX_TIMER_IRQ != -1) -# define CONFIG_SYS_TIMER_0 1 +#if defined(XILINX_TIMER_BASEADDR) && defined(XILINX_TIMER_IRQ) # define CONFIG_SYS_TIMER_0_ADDR XILINX_TIMER_BASEADDR # define CONFIG_SYS_TIMER_0_IRQ XILINX_TIMER_IRQ -# define FREQUENCE XILINX_CLOCK_FREQ -# define CONFIG_SYS_TIMER_0_PRELOAD ( FREQUENCE/1000 ) -# endif -#elif XILINX_CLOCK_FREQ -# define CONFIG_XILINX_CLOCK_FREQ XILINX_CLOCK_FREQ -#else -# error BAD CLOCK FREQ #endif + /* FSL */ /* #define CONFIG_SYS_FSL_2 */ /* #define FSL_INTR_2 1 */ -- cgit v1.1 From 2380b8f529ae95cc51fa475e83101e40f4191a43 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 4 Jul 2012 13:12:37 +0200 Subject: microblaze: Clean microblaze initialization Move board specific function to board_init function in board/ folder Remove externs from generic board.c Use board_init_f function in board.c file. Signed-off-by: Michal Simek Acked-by: Stephan Linz --- arch/microblaze/cpu/start.S | 2 +- arch/microblaze/include/asm/processor.h | 3 +++ arch/microblaze/lib/board.c | 17 +++-------------- board/xilinx/microblaze-generic/microblaze-generic.c | 9 +++++++++ 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 8a2f634..8564c4e 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -149,7 +149,7 @@ clear_bss: cmp r6, r5, r4 /* check if we have reach the end */ bnei r6, 2b 3: /* jumping to board_init */ - brai board_init + brai board_init_f 1: bri 1b /* diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h index 2295d0a..2c4d5ff 100644 --- a/arch/microblaze/include/asm/processor.h +++ b/arch/microblaze/include/asm/processor.h @@ -28,4 +28,7 @@ extern char __end[]; extern char __text_start[]; +/* Microblaze board initialization function */ +void board_init(void); + #endif /* __ASM_MICROBLAZE_PROCESSOR_H */ diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c index fde109f..b450367 100644 --- a/arch/microblaze/lib/board.c +++ b/arch/microblaze/lib/board.c @@ -39,13 +39,6 @@ DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_SYS_GPIO_0 -extern int gpio_init (void); -#endif -#ifdef CONFIG_SYS_FSL_2 -extern void fsl_init2 (void); -#endif - /* * All attempts to come up with a "common" initialization sequence * that works for all boards and architectures failed: some of the @@ -67,20 +60,14 @@ init_fnc_t *init_sequence[] = { #endif serial_init, console_init_f, -#ifdef CONFIG_SYS_GPIO_0 - gpio_init, -#endif interrupts_init, timer_init, -#ifdef CONFIG_SYS_FSL_2 - fsl_init2, -#endif NULL, }; unsigned long monitor_flash_len; -void board_init (void) +void board_init_f(ulong not_used) { bd_t *bd; init_fnc_t **init_fnc_ptr; @@ -189,6 +176,8 @@ void board_init (void) /* Initialize the console (after the relocation and devices init) */ console_init_r(); + board_init(); + /* Initialize from environment */ load_addr = getenv_ulong("loadaddr", 16, load_addr); diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index a1e2bfe..b75e62c 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -69,6 +70,14 @@ int fsl_init2 (void) { } #endif +void board_init(void) +{ + gpio_init(); +#ifdef CONFIG_SYS_FSL_2 + fsl_init2(); +#endif +} + int board_eth_init(bd_t *bis) { int ret = 0; -- cgit v1.1 From c60a57912a3efcdcc087422a1e9ce2dc1b61e39d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 10 Jul 2012 10:21:25 +0200 Subject: microblaze: board: Use bi_flashstart instead of CONFIG_SYS_FLASH_BASE Prepare for device-tree driven configuration. Signed-off-by: Michal Simek Acked-by: Stephan Linz --- arch/microblaze/lib/board.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c index b450367..674b573 100644 --- a/arch/microblaze/lib/board.c +++ b/arch/microblaze/lib/board.c @@ -136,9 +136,8 @@ void board_init_f(ulong not_used) #if defined(CONFIG_CMD_FLASH) puts ("Flash: "); bd->bi_flashstart = CONFIG_SYS_FLASH_BASE; - if (0 < (flash_size = flash_init ())) { - bd->bi_flashsize = flash_size; - bd->bi_flashoffset = CONFIG_SYS_FLASH_BASE + flash_size; + flash_size = flash_init(); + if (bd->bi_flashstart && flash_size > 0) { # ifdef CONFIG_SYS_FLASH_CHECKSUM print_size (flash_size, ""); /* @@ -149,13 +148,16 @@ void board_init_f(ulong not_used) s = getenv ("flashchecksum"); if (s && (*s == 'y')) { printf (" CRC: %08X", - crc32 (0, (const unsigned char *) CONFIG_SYS_FLASH_BASE, flash_size) + crc32(0, (const u8 *)bd->bi_flashstart, + flash_size) ); } putc ('\n'); # else /* !CONFIG_SYS_FLASH_CHECKSUM */ print_size (flash_size, "\n"); # endif /* CONFIG_SYS_FLASH_CHECKSUM */ + bd->bi_flashsize = flash_size; + bd->bi_flashoffset = bd->bi_flashstart + flash_size; } else { puts ("Flash init FAILED"); bd->bi_flashstart = 0; -- cgit v1.1 From 93691842e8dc86e6b2cb148c7c60a168654bbc34 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 4 Sep 2012 11:31:07 +0000 Subject: Fix strict-aliasing warning in dlmalloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the following warnings in dlmalloc seen with my gcc 4.6. dlmalloc.c: In function 'malloc_bin_reloc': dlmalloc.c:1493: warning: dereferencing pointer 'p' does break strict-aliasing rules dlmalloc.c:1493: warning: dereferencing pointer 'p' does break strict-aliasing rules dlmalloc.c:1490: note: initialized from here dlmalloc.c:1493: note: initialized from here This version is tested on avr32 arch boards. Signed-off-by: Simon Glass Signed-off-by: Andreas Bießmann --- common/dlmalloc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/dlmalloc.c b/common/dlmalloc.c index c645d73..1d7e527 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -1487,11 +1487,11 @@ static mbinptr av_[NAV * 2 + 2] = { #ifdef CONFIG_NEEDS_MANUAL_RELOC void malloc_bin_reloc (void) { - unsigned long *p = (unsigned long *)(&av_[2]); - int i; - for (i=2; i<(sizeof(av_)/sizeof(mbinptr)); ++i) { - *p++ += gd->reloc_off; - } + mbinptr *p = &av_[2]; + size_t i; + + for (i = 2; i < ARRAY_SIZE(av_); ++i, ++p) + *p = (mbinptr)((ulong)*p + gd->reloc_off); } #endif -- cgit v1.1 From a420dfe2b017db321ad9b4058d38e216b756465f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bie=C3=9Fmann?= Date: Tue, 4 Sep 2012 11:33:29 +0000 Subject: avr32: add atngw100mkii board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch is derived from an older patch provided by atmel in its buildroot-avr32-v3.0.0.tar.bz2 Signed-off-by: Andreas Bießmann cc: Hans-Christian Egtvedt Acked-by: Hans-Christian Egtvedt --- MAINTAINERS | 1 + board/atmel/atngw100mkii/Makefile | 40 ++++++ board/atmel/atngw100mkii/atngw100mkii.c | 156 ++++++++++++++++++++++++ boards.cfg | 1 + include/configs/atngw100mkii.h | 209 ++++++++++++++++++++++++++++++++ 5 files changed, 407 insertions(+) create mode 100644 board/atmel/atngw100mkii/Makefile create mode 100644 board/atmel/atngw100mkii/atngw100mkii.c create mode 100644 include/configs/atngw100mkii.h diff --git a/MAINTAINERS b/MAINTAINERS index 4aabcff..cd18732 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1112,6 +1112,7 @@ Wolfgang Wegner Andreas Bießmann grasshopper AT32AP7000 + atngw100mkii AT32AP7000 Hans-Christian Egtvedt diff --git a/board/atmel/atngw100mkii/Makefile b/board/atmel/atngw100mkii/Makefile new file mode 100644 index 0000000..7fbd20d --- /dev/null +++ b/board/atmel/atngw100mkii/Makefile @@ -0,0 +1,40 @@ +# +# Copyright (C) 2005-2006 Atmel Corporation +# +# See file CREDITS for list of people who contributed to this project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA + +include $(TOPDIR)/config.mk + +LIB := $(obj)lib$(BOARD).o + +COBJS := $(BOARD).o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/atmel/atngw100mkii/atngw100mkii.c b/board/atmel/atngw100mkii/atngw100mkii.c new file mode 100644 index 0000000..f4023b3 --- /dev/null +++ b/board/atmel/atngw100mkii/atngw100mkii.c @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2010 Atmel Corporation + * + * Copyright (C) 2012 Andreas Bießmann + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct mmu_vm_range mmu_vmr_table[CONFIG_SYS_NR_VM_REGIONS] = { + { + /* Atmel AT49BV640D 8 MiB x16 NOR flash on NCS0 */ + .virt_pgno = CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT, + .nr_pages = CONFIG_SYS_FLASH_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_FLASH_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_NONE, + }, { + /* Micron MT29F2G16AAD 256 MiB x16 NAND flash on NCS3 */ + .virt_pgno = EBI_SRAM_CS3_BASE >> PAGE_SHIFT, + .nr_pages = EBI_SRAM_CS3_SIZE >> PAGE_SHIFT, + .phys = (EBI_SRAM_CS3_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_NONE, + }, { + /* 2x16-bit ISSI IS42S16320B 64 MiB SDRAM (128 MiB total) */ + .virt_pgno = CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT, + .nr_pages = EBI_SDRAM_SIZE >> PAGE_SHIFT, + .phys = (CONFIG_SYS_SDRAM_BASE >> PAGE_SHIFT) + | MMU_VMR_CACHE_WRBACK, + }, +}; + +static const struct sdram_config sdram_config = { + .data_bits = SDRAM_DATA_32BIT, + .row_bits = 13, + .col_bits = 10, + .bank_bits = 2, + .cas = 3, + .twr = 2, + .trc = 7, + .trp = 2, + .trcd = 2, + .tras = 5, + .txsr = 6, + /* 7.81 us */ + .refresh_period = (781 * (SDRAMC_BUS_HZ / 1000)) / 100000, +}; + +int board_early_init_f(void) +{ + /* Enable SDRAM in the EBI mux */ + hmatrix_slave_write(EBI, SFR, HMATRIX_BIT(EBI_SDRAM_ENABLE) + | HMATRIX_BIT(EBI_NAND_ENABLE)); + + portmux_enable_ebi(32, 23, PORTMUX_EBI_NAND, + PORTMUX_DRIVE_HIGH); + portmux_select_gpio(PORTMUX_PORT_E, 1 << 23, + PORTMUX_DIR_OUTPUT | PORTMUX_INIT_HIGH + | PORTMUX_DRIVE_MIN); + portmux_enable_usart1(PORTMUX_DRIVE_MIN); + +#if defined(CONFIG_MACB) + portmux_enable_macb0(PORTMUX_MACB_MII, PORTMUX_DRIVE_HIGH); + portmux_enable_macb1(PORTMUX_MACB_MII, PORTMUX_DRIVE_HIGH); +#endif +#if defined(CONFIG_MMC) + portmux_enable_mmci(0, PORTMUX_MMCI_4BIT, PORTMUX_DRIVE_LOW); +#endif +#if defined(CONFIG_ATMEL_SPI) + portmux_enable_spi0(1 << 0, PORTMUX_DRIVE_LOW); +#endif + + return 0; +} + +phys_size_t initdram(int board_type) +{ + unsigned long expected_size; + unsigned long actual_size; + void *sdram_base; + + sdram_base = uncached(EBI_SDRAM_BASE); + + expected_size = sdram_init(sdram_base, &sdram_config); + actual_size = get_ram_size(sdram_base, expected_size); + + if (expected_size != actual_size) + printf("Warning: Only %lu of %lu MiB SDRAM is working\n", + actual_size >> 20, expected_size >> 20); + + return actual_size; +} + +int board_early_init_r(void) +{ + gd->bd->bi_phy_id[0] = 0x01; + gd->bd->bi_phy_id[1] = 0x03; + return 0; +} + +#ifdef CONFIG_CMD_NET +int board_eth_init(bd_t *bi) +{ + macb_eth_initialize(0, (void *)ATMEL_BASE_MACB0, bi->bi_phy_id[0]); + macb_eth_initialize(1, (void *)ATMEL_BASE_MACB1, bi->bi_phy_id[1]); + return 0; +} +#endif + +/* SPI chip select control */ +#ifdef CONFIG_ATMEL_SPI +#define ATNGW100_DATAFLASH_CS_PIN GPIO_PIN_PA(3) + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return bus == 0 && cs == 0; +} + +void spi_cs_activate(struct spi_slave *slave) +{ + gpio_set_value(ATNGW100_DATAFLASH_CS_PIN, 0); +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + gpio_set_value(ATNGW100_DATAFLASH_CS_PIN, 1); +} +#endif /* CONFIG_ATMEL_SPI */ diff --git a/boards.cfg b/boards.cfg index 72e7803..e123904 100644 --- a/boards.cfg +++ b/boards.cfg @@ -302,6 +302,7 @@ tec arm armv7:arm720t tec avionic paz00 arm armv7:arm720t paz00 compal tegra20 trimslice arm armv7:arm720t trimslice compulab tegra20 atngw100 avr32 at32ap - atmel at32ap700x +atngw100mkii avr32 at32ap - atmel at32ap700x atstk1002 avr32 at32ap atstk1000 atmel at32ap700x atstk1003 avr32 at32ap atstk1000 atmel at32ap700x atstk1004 avr32 at32ap atstk1000 atmel at32ap700x diff --git a/include/configs/atngw100mkii.h b/include/configs/atngw100mkii.h new file mode 100644 index 0000000..f85374f --- /dev/null +++ b/include/configs/atngw100mkii.h @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2006 Atmel Corporation + * + * Copyright (C) 2012 Andreas Bießmann + * + * Configuration settings for the AVR32 Network Gateway + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#define CONFIG_AVR32 +#define CONFIG_AT32AP +#define CONFIG_AT32AP7000 +#define CONFIG_ATNGW100MKII + +/* + * Timer clock frequency. We're using the CPU-internal COUNT register + * for this, so this is equivalent to the CPU core clock frequency + */ +#define CONFIG_SYS_HZ 1000 + +/* + * Set up the PLL to run at 140 MHz, the CPU to run at the PLL + * frequency, the HSB and PBB busses to run at 1/2 the PLL frequency + * and the PBA bus to run at 1/4 the PLL frequency. + */ +#define CONFIG_PLL +#define CONFIG_SYS_POWER_MANAGER +#define CONFIG_SYS_OSC0_HZ 20000000 +#define CONFIG_SYS_PLL0_DIV 1 +#define CONFIG_SYS_PLL0_MUL 7 +#define CONFIG_SYS_PLL0_SUPPRESS_CYCLES 16 +/* + * Set the CPU running at: + * PLL / (2^CONFIG_SYS_CLKDIV_CPU) = CPU MHz + */ +#define CONFIG_SYS_CLKDIV_CPU 0 +/* + * Set the HSB running at: + * PLL / (2^CONFIG_SYS_CLKDIV_HSB) = HSB MHz + */ +#define CONFIG_SYS_CLKDIV_HSB 1 +/* + * Set the PBA running at: + * PLL / (2^CONFIG_SYS_CLKDIV_PBA) = PBA MHz + */ +#define CONFIG_SYS_CLKDIV_PBA 2 +/* + * Set the PBB running at: + * PLL / (2^CONFIG_SYS_CLKDIV_PBB) = PBB MHz + */ +#define CONFIG_SYS_CLKDIV_PBB 1 + +/* Reserve VM regions for NOR flash, NAND flash and SDRAM */ +#define CONFIG_SYS_NR_VM_REGIONS 3 + +/* + * The PLLOPT register controls the PLL like this: + * icp = PLLOPT<2> + * ivco = PLLOPT<1:0> + * + * We want icp=1 (default) and ivco=0 (80-160 MHz) or ivco=2 (150-240MHz). + */ +#define CONFIG_SYS_PLL0_OPT 0x04 + +#define CONFIG_USART_BASE ATMEL_BASE_USART1 +#define CONFIG_USART_ID 1 + +/* User serviceable stuff */ +#define CONFIG_DOS_PARTITION + +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG + +#define CONFIG_STACKSIZE (2048) + +#define CONFIG_BAUDRATE 115200 +#define CONFIG_BOOTARGS \ + "root=mtd:main rootfstype=jffs2" +#define CONFIG_BOOTCOMMAND \ + "fsload 0x10400000 /uImage; bootm" + +/* + * Only interrupt autoboot if is pressed. Otherwise, garbage + * data on the serial line may interrupt the boot sequence. + */ +#define CONFIG_BOOTDELAY 1 +#define CONFIG_AUTOBOOT +#define CONFIG_AUTOBOOT_KEYED +#define CONFIG_AUTOBOOT_PROMPT \ + "Press SPACE to abort autoboot in %d seconds\n", bootdelay +#define CONFIG_AUTOBOOT_DELAY_STR "d" +#define CONFIG_AUTOBOOT_STOP_STR " " + +/* + * After booting the board for the first time, new ethernet addresses + * should be generated and assigned to the environment variables + * "ethaddr" and "eth1addr". This is normally done during production. + */ +#define CONFIG_OVERWRITE_ETHADDR_ONCE +#define CONFIG_NET_MULTI + +/* + * BOOTP/DHCP options + */ +#define CONFIG_BOOTP_SUBNETMASK +#define CONFIG_BOOTP_GATEWAY + +/* + * Command line configuration. + */ +#include + +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_JFFS2 +#define CONFIG_CMD_MMC +#define CONFIG_CMD_SF +#define CONFIG_CMD_SPI +#define CONFIG_CMD_MII + +#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_SETGETDCR +#undef CONFIG_CMD_XIMG + +#define CONFIG_ATMEL_USART +#define CONFIG_MACB +#define CONFIG_PORTMUX_PIO +#define CONFIG_SYS_NR_PIOS 5 +#define CONFIG_SYS_HSDRAMC +#define CONFIG_MMC +#define CONFIG_GENERIC_ATMEL_MCI +#define CONFIG_GENERIC_MMC +#define CONFIG_SYS_MMC_MAX_BLK_COUNT 1 +#define CONFIG_ATMEL_SPI + +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_ATMEL + +#define CONFIG_SYS_DCACHE_LINESZ 32 +#define CONFIG_SYS_ICACHE_LINESZ 32 + +#define CONFIG_NR_DRAM_BANKS 1 + +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_PROTECTION + +#define CONFIG_SYS_FLASH_BASE 0x00000000 +#define CONFIG_SYS_FLASH_SIZE 0x800000 +#define CONFIG_SYS_MAX_FLASH_BANKS 1 +#define CONFIG_SYS_MAX_FLASH_SECT 135 + +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE + +#define CONFIG_SYS_INTRAM_BASE INTERNAL_SRAM_BASE +#define CONFIG_SYS_INTRAM_SIZE INTERNAL_SRAM_SIZE +#define CONFIG_SYS_SDRAM_BASE EBI_SDRAM_BASE + +#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_SIZE 65536 +#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_SYS_FLASH_SIZE - CONFIG_ENV_SIZE) + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INTRAM_BASE + CONFIG_SYS_INTRAM_SIZE) + +#define CONFIG_SYS_MALLOC_LEN (256*1024) +#define CONFIG_SYS_DMA_ALLOC_LEN (16384) + +/* Allow 4MB for the kernel run-time image */ +#define CONFIG_SYS_LOAD_ADDR (EBI_SDRAM_BASE + 0x00400000) +#define CONFIG_SYS_BOOTPARAMS_LEN (16 * 1024) + +/* Other configuration settings that shouldn't have to change all that often */ +#define CONFIG_SYS_PROMPT "U-Boot> " +#define CONFIG_SYS_CBSIZE 256 +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_LONGHELP + +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x1f00000) + +#define CONFIG_MTD_DEVICE +#define CONFIG_MTD_PARTITIONS + +#endif /* __CONFIG_H */ -- cgit v1.1 From e02c9458748a59e5d80649deb5e40f96ed992bb5 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 5 Sep 2012 08:34:44 +0200 Subject: fdt: Check if the FDT address is configured In case the "fdt addr" command wasn't ran yet and any other "fdt" subcommand was issued, the system crashed due to NULL pointer being used. This is caused by "fdt addr" command setting up a pointer to the FDT memory location. Prior issuing "fdt addr", the pointer is NULL so calling any other subcommands crashed the u-boot. Signed-off-by: Marek Vasut Cc: Simon Glass --- common/cmd_fdt.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 9a5c53e..e2225c4 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -114,10 +114,21 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) } } + return CMD_RET_SUCCESS; + } + + if (!working_fdt) { + puts( + "No FDT memory address configured. Please configure\n" + "the FDT address via \"fdt addr
\" command.\n" + "Aborting!\n"); + return CMD_RET_FAILURE; + } + /* * Move the working_fdt */ - } else if (strncmp(argv[1], "mo", 2) == 0) { + if (strncmp(argv[1], "mo", 2) == 0) { struct fdt_header *newaddr; int len; int err; -- cgit v1.1 From 7ca8f73a0ad9176e6e45190a3490bbeb3d80e018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Majewski?= Date: Tue, 4 Sep 2012 23:15:20 +0000 Subject: i2c:soft:multi: Support for multiple soft I2C buses at Samsung boards Support for multiple soft I2C buses. Multibus I2C support is achieved by defining get_multi_{sda|scl}_pin functions to switch between multiple "soft" I2C buses. Common definition of I2C_X I2C buses is provided at . TEST HW: Samsung's Exynos4210 evt.0.1 - Trats development board Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Cc: Heiko Schocher Cc: Minkyu Kang Acked-by: Heiko Schocher --- board/samsung/common/Makefile | 43 ++++++++++++++++++++++++++ board/samsung/common/multi_i2c.c | 65 ++++++++++++++++++++++++++++++++++++++++ include/i2c.h | 12 ++++++++ 3 files changed, 120 insertions(+) create mode 100644 board/samsung/common/Makefile create mode 100644 board/samsung/common/multi_i2c.c diff --git a/board/samsung/common/Makefile b/board/samsung/common/Makefile new file mode 100644 index 0000000..0bcd594 --- /dev/null +++ b/board/samsung/common/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (C) 2012 Samsung Electronics +# Lukasz Majewski +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)libsamsung.o + +COBJS-$(CONFIG_SOFT_I2C_MULTI_BUS) += multi_i2c.o + +SRCS := $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/samsung/common/multi_i2c.c b/board/samsung/common/multi_i2c.c new file mode 100644 index 0000000..d6c3d37 --- /dev/null +++ b/board/samsung/common/multi_i2c.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 Samsung Electronics + * Lukasz Majewski + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* Handle multiple I2C buses instances */ +int get_multi_scl_pin(void) +{ + unsigned int bus = I2C_GET_BUS(); + + switch (bus) { + case I2C_0: /* I2C_0 definition - compatibility layer */ + case I2C_5: + return CONFIG_SOFT_I2C_I2C5_SCL; + case I2C_9: + return CONFIG_SOFT_I2C_I2C9_SCL; + default: + printf("I2C_%d not supported!\n", bus); + }; + + return 0; +} + +int get_multi_sda_pin(void) +{ + unsigned int bus = I2C_GET_BUS(); + + switch (bus) { + case I2C_0: /* I2C_0 definition - compatibility layer */ + case I2C_5: + return CONFIG_SOFT_I2C_I2C5_SDA; + case I2C_9: + return CONFIG_SOFT_I2C_I2C9_SDA; + default: + printf("I2C_%d not supported!\n", bus); + }; + + return 0; +} + +int multi_i2c_init(void) +{ + return 0; +} diff --git a/include/i2c.h b/include/i2c.h index 1f35acf..16f099d 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -250,4 +250,16 @@ static inline void I2C_SET_BUS(unsigned int bus) i2c_set_bus_num(bus); } +/* Multi I2C definitions */ +enum { + I2C_0, I2C_1, I2C_2, I2C_3, I2C_4, I2C_5, I2C_6, I2C_7, + I2C_8, I2C_9, I2C_10, +}; + +/* Multi I2C busses handling */ +#ifdef CONFIG_SOFT_I2C_MULTI_BUS +extern int get_multi_scl_pin(void); +extern int get_multi_sda_pin(void); +extern int multi_i2c_init(void); +#endif #endif /* _I2C_H_ */ -- cgit v1.1 From fd8dca83ed4b9d960d3b9a0450da12bb32f512f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Majewski?= Date: Tue, 4 Sep 2012 23:15:21 +0000 Subject: i2c:soft:multi: Enable soft I2C multibus at Trats development board This commit enables multibus handling at Samsung's Trats development board. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Cc: Minkyu Kang Acked-by: Heiko Schocher --- board/samsung/trats/trats.c | 15 +++++++++++++++ include/configs/trats.h | 24 +++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c index 4f9cb5a..e11a892 100644 --- a/board/samsung/trats/trats.c +++ b/board/samsung/trats/trats.c @@ -75,6 +75,21 @@ int board_init(void) return 0; } +void i2c_init_board(void) +{ + struct exynos4_gpio_part1 *gpio1 = + (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1(); + struct exynos4_gpio_part2 *gpio2 = + (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2(); + + /* I2C_5 -> PMIC */ + s5p_gpio_direction_output(&gpio1->b, 7, 1); + s5p_gpio_direction_output(&gpio1->b, 6, 1); + /* I2C_9 -> FG */ + s5p_gpio_direction_output(&gpio2->y4, 0, 1); + s5p_gpio_direction_output(&gpio2->y4, 1, 1); +} + int dram_init(void) { gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE) + diff --git a/include/configs/trats.h b/include/configs/trats.h index f8da9c01..66ef377 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -211,18 +211,28 @@ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - GENERATED_GBL_DATA_SIZE) #define CONFIG_SYS_CACHELINE_SIZE 32 -#include -/* - * I2C Settings - */ -#define CONFIG_SOFT_I2C_GPIO_SCL exynos4_gpio_part1_get_nr(b, 7) -#define CONFIG_SOFT_I2C_GPIO_SDA exynos4_gpio_part1_get_nr(b, 6) #define CONFIG_SOFT_I2C #define CONFIG_SOFT_I2C_READ_REPEATED_START +#define CONFIG_SYS_I2C_INIT_BOARD #define CONFIG_SYS_I2C_SPEED 50000 #define CONFIG_I2C_MULTI_BUS -#define CONFIG_SYS_MAX_I2C_BUS 7 +#define CONFIG_SOFT_I2C_MULTI_BUS +#define CONFIG_SYS_MAX_I2C_BUS 15 + +#include + +/* I2C PMIC */ +#define CONFIG_SOFT_I2C_I2C5_SCL exynos4_gpio_part1_get_nr(b, 7) +#define CONFIG_SOFT_I2C_I2C5_SDA exynos4_gpio_part1_get_nr(b, 6) + +/* I2C FG */ +#define CONFIG_SOFT_I2C_I2C9_SCL exynos4_gpio_part2_get_nr(y4, 1) +#define CONFIG_SOFT_I2C_I2C9_SDA exynos4_gpio_part2_get_nr(y4, 0) + +#define CONFIG_SOFT_I2C_GPIO_SCL get_multi_scl_pin() +#define CONFIG_SOFT_I2C_GPIO_SDA get_multi_sda_pin() +#define I2C_INIT multi_i2c_init() #define CONFIG_PMIC #define CONFIG_PMIC_I2C -- cgit v1.1 From d62e9caaaf7e6f5c7d86c9ea19170bfa5adda8be Mon Sep 17 00:00:00 2001 From: Matthieu CASTET Date: Mon, 19 Mar 2012 15:35:25 +0100 Subject: mtd: support ONFI multi lun NAND With onfi a flash is organized into one or more logical units (LUNs). A logical unit (LUN) is the minimum unit that can independently execute commands and report status. Mtd does not exploit LUN, so make it see a big single flash where size is lun_size * number_of_lun. Without this patch MT29F8G08ADBDAH4 size is 512MiB instead of 1GiB. Artem: split long line on 2 shorter ones. This is commit 637957551c0ac80de8dfc7650d320c5a98c2c0c0 from Linux Signed-off-by: Matthieu Castet Acked-by: Florian Fainelli Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse [scottwood@freescale.com: picked from Linux into U-Boot] Reported-by: Rafael Beims Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_base.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index bfd668f..50bfb65 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2573,7 +2573,8 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, mtd->writesize = le32_to_cpu(p->byte_per_page); mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize; mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); - chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize; + chip->chipsize = le32_to_cpu(p->blocks_per_lun); + chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count; *busw = 0; if (le16_to_cpu(p->features) & 1) *busw = NAND_BUSWIDTH_16; -- cgit v1.1 From eee623a5049963d0c085be37128bbd22bee1ba1e Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 22 Aug 2012 16:49:42 -0500 Subject: nand: Add support for unlock.invert NAND unlock command allows an invert bit to be set to unlock all but the selected page range. Signed-off-by: Joe Hershberger [scottwood@freescale.com: updated docs and added comment about invert bit] Signed-off-by: Scott Wood --- common/cmd_nand.c | 13 ++++++++++--- doc/README.nand | 2 ++ drivers/mtd/nand/nand_util.c | 17 ++++++++++++++--- include/nand.h | 4 ++-- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/common/cmd_nand.c b/common/cmd_nand.c index a91ccf4..f737c06 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -749,11 +749,18 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) return 0; } - if (strcmp(cmd, "unlock") == 0) { + if (strncmp(cmd, "unlock", 5) == 0) { + int allexcept = 0; + + s = strchr(cmd, '.'); + + if (s && !strcmp(s, ".allexcept")) + allexcept = 1; + if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size) < 0) return 1; - if (!nand_unlock(&nand_info[dev], off, size)) { + if (!nand_unlock(&nand_info[dev], off, size, allexcept)) { puts("NAND flash successfully unlocked\n"); } else { puts("Error unlocking NAND flash, " @@ -807,7 +814,7 @@ U_BOOT_CMD( "\n" "nand lock [tight] [status]\n" " bring nand to lock state or display locked pages\n" - "nand unlock [offset] [size] - unlock section" + "nand unlock[.allexcept] [offset] [size] - unlock section" #endif #ifdef CONFIG_ENV_OFFSET_OOB "\n" diff --git a/doc/README.nand b/doc/README.nand index 1602b5e..c130189 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -228,6 +228,8 @@ NAND locking command (for chips with active LOCKPRE pin) "nand unlock [offset] [size]" unlock consecutive area (can be called multiple times for different areas) + "nand unlock.allexcept [offset] [size]" + unlock all except specified consecutive area I have tested the code with board containing 128MiB NAND large page chips and 32MiB small page chips. diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 7ed8b18..c66eeef 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -317,18 +317,20 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) * @param start start byte address * @param length number of bytes to unlock (must be a multiple of * page size nand->writesize) + * @param allexcept if set, unlock everything not selected * * @return 0 on success, -1 in case of error */ -int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) +int nand_unlock(struct mtd_info *mtd, ulong start, ulong length, int allexcept) { int ret = 0; int chipnr; int status; int page; struct nand_chip *chip = mtd->priv; - printf ("nand_unlock: start: %08x, length: %d!\n", - (int)start, (int)length); + + debug("nand_unlock%s: start: %08x, length: %d!\n", + allexcept ? " (allexcept)" : "", start, length); /* select the NAND device */ chipnr = (int)(start >> chip->chip_shift); @@ -368,6 +370,15 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) /* submit ADDRESS of LAST page to unlock */ page += (int)(length >> chip->page_shift); + + /* + * Page addresses for unlocking are supposed to be block-aligned. + * At least some NAND chips use the low bit to indicate that the + * page range should be inverted. + */ + if (allexcept) + page |= 1; + chip->cmdfunc(mtd, NAND_CMD_UNLOCK2, -1, page & chip->pagemask); /* call wait ready function */ diff --git a/include/nand.h b/include/nand.h index c554c55..e9b47f1 100644 --- a/include/nand.h +++ b/include/nand.h @@ -144,8 +144,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); #define NAND_LOCK_STATUS_LOCK 0x02 #define NAND_LOCK_STATUS_UNLOCK 0x04 -int nand_lock( nand_info_t *meminfo, int tight ); -int nand_unlock( nand_info_t *meminfo, ulong start, ulong length ); +int nand_lock(nand_info_t *meminfo, int tight); +int nand_unlock(nand_info_t *meminfo, ulong start, ulong length, int allexcept); int nand_get_lock_status(nand_info_t *meminfo, loff_t offset); int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst); -- cgit v1.1 From e331ab2ee9b141f1de2a8fb0bfaf52f6273022f9 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 22 Aug 2012 16:49:43 -0500 Subject: nand: Change ulong to loff_t and size_t Missed in previous cleanup. Signed-off-by: Joe Hershberger Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_util.c | 5 +++-- include/nand.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index c66eeef..5ef7df7 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -321,7 +321,8 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) * * @return 0 on success, -1 in case of error */ -int nand_unlock(struct mtd_info *mtd, ulong start, ulong length, int allexcept) +int nand_unlock(struct mtd_info *mtd, loff_t start, size_t length, + int allexcept) { int ret = 0; int chipnr; @@ -329,7 +330,7 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length, int allexcept) int page; struct nand_chip *chip = mtd->priv; - debug("nand_unlock%s: start: %08x, length: %d!\n", + debug("nand_unlock%s: start: %08llx, length: %d!\n", allexcept ? " (allexcept)" : "", start, length); /* select the NAND device */ diff --git a/include/nand.h b/include/nand.h index e9b47f1..ff061c0 100644 --- a/include/nand.h +++ b/include/nand.h @@ -145,7 +145,8 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); #define NAND_LOCK_STATUS_UNLOCK 0x04 int nand_lock(nand_info_t *meminfo, int tight); -int nand_unlock(nand_info_t *meminfo, ulong start, ulong length, int allexcept); +int nand_unlock(nand_info_t *meminfo, loff_t start, size_t length, + int allexcept); int nand_get_lock_status(nand_info_t *meminfo, loff_t offset); int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst); -- cgit v1.1 From 33b1d5cae3defdbeb30333ffac41bcbff85c5019 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 22 Aug 2012 16:49:44 -0500 Subject: nand: consolidate duplicated constants NAND_CMD_ constants for lock/unlock should be in the header Signed-off-by: Joe Hershberger Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_util.c | 6 ------ include/linux/mtd/nand.h | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 5ef7df7..ffcb4f6 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -207,12 +207,6 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) * Support for locking / unlocking operations of some NAND devices *****************************************************************************/ -#define NAND_CMD_LOCK 0x2a -#define NAND_CMD_LOCK_TIGHT 0x2c -#define NAND_CMD_UNLOCK1 0x23 -#define NAND_CMD_UNLOCK2 0x24 -#define NAND_CMD_LOCK_STATUS 0x7a - /** * nand_lock: Set all pages of NAND flash chip to the LOCK or LOCK-TIGHT * state diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 82704de..6c40531 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -85,8 +85,10 @@ extern void nand_wait_ready(struct mtd_info *mtd); #define NAND_CMD_RESET 0xff #define NAND_CMD_LOCK 0x2a +#define NAND_CMD_LOCK_TIGHT 0x2c #define NAND_CMD_UNLOCK1 0x23 #define NAND_CMD_UNLOCK2 0x24 +#define NAND_CMD_LOCK_STATUS 0x7a /* Extended commands for large page devices */ #define NAND_CMD_READSTART 0x30 -- cgit v1.1 From e70bfa2986f9c028e3c21e0995285047a9baec27 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Wed, 22 Aug 2012 16:49:45 -0500 Subject: nand: Make NAND lock status compatible with Micron Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is not the same as others. Instead of bit 1 being lock, it is #lock_tight. To make the driver support either format, ignore bit 1 and use only bit 0 and bit 2. Signed-off-by: Joe Hershberger Signed-off-by: Scott Wood --- common/cmd_nand.c | 8 +++++++- drivers/mtd/nand/nand_util.c | 2 -- include/nand.h | 1 - 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/common/cmd_nand.c b/common/cmd_nand.c index f737c06..9c6dabe 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -231,12 +231,18 @@ print: #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK static void print_status(ulong start, ulong end, ulong erasesize, int status) { + /* + * Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is + * not the same as others. Instead of bit 1 being lock, it is + * #lock_tight. To make the driver support either format, ignore bit 1 + * and use only bit 0 and bit 2. + */ printf("%08lx - %08lx: %08lx blocks %s%s%s\n", start, end - 1, (end - start) / erasesize, ((status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), - ((status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), + (!(status & NAND_LOCK_STATUS_UNLOCK) ? "LOCK " : ""), ((status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); } diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index ffcb4f6..c4752a7 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -265,7 +265,6 @@ int nand_lock(struct mtd_info *mtd, int tight) * >0 lock status: * bitfield with the following combinations: * NAND_LOCK_STATUS_TIGHT: page in tight state - * NAND_LOCK_STATUS_LOCK: page locked * NAND_LOCK_STATUS_UNLOCK: page unlocked * */ @@ -294,7 +293,6 @@ int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) chip->cmdfunc(mtd, NAND_CMD_LOCK_STATUS, -1, page & chip->pagemask); ret = chip->read_byte(mtd) & (NAND_LOCK_STATUS_TIGHT - | NAND_LOCK_STATUS_LOCK | NAND_LOCK_STATUS_UNLOCK); out: diff --git a/include/nand.h b/include/nand.h index ff061c0..bbe28b2 100644 --- a/include/nand.h +++ b/include/nand.h @@ -141,7 +141,6 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); #define NAND_LOCK_STATUS_TIGHT 0x01 -#define NAND_LOCK_STATUS_LOCK 0x02 #define NAND_LOCK_STATUS_UNLOCK 0x04 int nand_lock(nand_info_t *meminfo, int tight); -- cgit v1.1 From 9c790a748f6b61e36f7aaf0c8d5ed35c9b09f454 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 30 Aug 2012 13:39:38 +0000 Subject: mtd: nand: allow NAND_NO_SUBPAGE_WRITE to be set from driver This is based on Linux kernel -next: commit 14f44abf1dafc20ba42ce8616a8fc8fbd1b3712b Author: Brian Norris Date: Fri Jul 13 09:28:24 2012 -0700 mtd: nand: allow NAND_NO_SUBPAGE_WRITE to be set from driver The NAND_CHIPOPTIONS_MSK has limited utility and is causing real bugs. It silently masks off at least one flag that might be set by the driver (NAND_NO_SUBPAGE_WRITE). This breaks the GPMI NAND driver and possibly others. Really, as long as driver writers exercise a small amount of care with NAND_* options, this mask is not necessary at all; it was only here to prevent certain options from accidentally being set by the driver. But the original thought turns out to be a bad idea occasionally. Thus, kill it. Note, this patch fixes some major gpmi-nand breakage. Signed-off-by: Marek Vasut Cc: Brian Norris Cc: Eric Nelson Cc: Fabio Estevam Cc: Otavio Salvador Cc: Scott Wood Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_base.c | 7 ++----- include/linux/mtd/nand.h | 3 --- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 50bfb65..390ff90 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2579,9 +2579,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, if (le16_to_cpu(p->features) & 1) *busw = NAND_BUSWIDTH_16; - chip->options &= ~NAND_CHIPOPTIONS_MSK; - chip->options |= (NAND_NO_READRDY | - NAND_NO_AUTOINCR) & NAND_CHIPOPTIONS_MSK; + chip->options |= NAND_NO_READRDY | NAND_NO_AUTOINCR; return 1; } @@ -2753,8 +2751,7 @@ static const struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, } } /* Get chip options, preserve non chip based options */ - chip->options &= ~NAND_CHIPOPTIONS_MSK; - chip->options |= type->options & NAND_CHIPOPTIONS_MSK; + chip->options |= type->options; /* Check if chip is a not a samsung device. Do not clear the * options for chips which are not having an extended id. diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 6c40531..c06866b 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -207,9 +207,6 @@ typedef enum { #define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \ && (chip->page_shift > 9)) -/* Mask to zero out the chip options, which come from the id table */ -#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR) - /* Non chip related options */ /* * Use a flash based bad block table. OOB identifier is saved in OOB area. -- cgit v1.1 From 80c8ab7b25579529809792eef51fe660308fecb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:48:12 +0200 Subject: mxc nand: Merge mtd and spl register definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patches fixes the TODO to use same register definitions in mtd mxc_nand and nand_spl fsl nfc drivers. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 247 +++++++++---------------------------------- include/fsl_nfc.h | 97 +++++++++-------- nand_spl/nand_boot_fsl_nfc.c | 58 +++++----- 3 files changed, 128 insertions(+), 274 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 936186f..9a9260c 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -25,168 +25,23 @@ #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35) #include #endif +#include #define DRIVER_NAME "mxc_nand" -/* - * TODO: Use same register defs here as nand_spl mxc nand driver. - */ -/* - * Register map and bit definitions for the Freescale NAND Flash Controller - * present in various i.MX devices. - * - * MX31 and MX27 have version 1 which has - * 4 512 byte main buffers and - * 4 16 byte spare buffers - * to support up to 2K byte pagesize nand. - * Reading or writing a 2K page requires 4 FDI/FDO cycles. - * - * MX25 has version 1.1 which has - * 8 512 byte main buffers and - * 8 64 byte spare buffers - * to support up to 4K byte pagesize nand. - * Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle. - * Also some of registers are moved and/or changed meaning as seen below. - */ -#if defined(CONFIG_MX31) || defined(CONFIG_MX27) -#define MXC_NFC_V1 -#elif defined(CONFIG_MX25) || defined(CONFIG_MX35) -#define MXC_NFC_V1_1 -#else -#warning "MXC NFC version not defined" -#endif - -#if defined(MXC_NFC_V1) -#define NAND_MXC_NR_BUFS 4 -#define NAND_MXC_SPARE_BUF_SIZE 16 -#define NAND_MXC_REG_OFFSET 0xe00 -#define is_mxc_nfc_11() 0 -#elif defined(MXC_NFC_V1_1) -#define NAND_MXC_NR_BUFS 8 -#define NAND_MXC_SPARE_BUF_SIZE 64 -#define NAND_MXC_REG_OFFSET 0x1e00 -#define is_mxc_nfc_11() 1 -#else -#error "define CONFIG_NAND_MXC_VXXX to use mtd mxc nand driver" -#endif -struct nfc_regs { - uint8_t main_area[NAND_MXC_NR_BUFS][0x200]; - uint8_t spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE]; - /* - * reserved size is offset of nfc registers - * minus total main and spare sizes - */ - uint8_t reserved1[NAND_MXC_REG_OFFSET - - NAND_MXC_NR_BUFS * (512 + NAND_MXC_SPARE_BUF_SIZE)]; -#if defined(MXC_NFC_V1) - uint16_t nfc_buf_size; - uint16_t reserved2; - uint16_t nfc_buf_addr; - uint16_t nfc_flash_addr; - uint16_t nfc_flash_cmd; - uint16_t nfc_config; - uint16_t nfc_ecc_status_result; - uint16_t nfc_rsltmain_area; - uint16_t nfc_rsltspare_area; - uint16_t nfc_wrprot; - uint16_t nfc_unlockstart_blkaddr; - uint16_t nfc_unlockend_blkaddr; - uint16_t nfc_nf_wrprst; - uint16_t nfc_config1; - uint16_t nfc_config2; -#elif defined(MXC_NFC_V1_1) - uint16_t reserved2[2]; - uint16_t nfc_buf_addr; - uint16_t nfc_flash_addr; - uint16_t nfc_flash_cmd; - uint16_t nfc_config; - uint16_t nfc_ecc_status_result; - uint16_t nfc_ecc_status_result2; - uint16_t nfc_spare_area_size; - uint16_t nfc_wrprot; - uint16_t reserved3[2]; - uint16_t nfc_nf_wrprst; - uint16_t nfc_config1; - uint16_t nfc_config2; - uint16_t reserved4; - uint16_t nfc_unlockstart_blkaddr; - uint16_t nfc_unlockend_blkaddr; - uint16_t nfc_unlockstart_blkaddr1; - uint16_t nfc_unlockend_blkaddr1; - uint16_t nfc_unlockstart_blkaddr2; - uint16_t nfc_unlockend_blkaddr2; - uint16_t nfc_unlockstart_blkaddr3; - uint16_t nfc_unlockend_blkaddr3; -#endif -}; - -/* - * Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register - * for Command operation - */ -#define NFC_CMD 0x1 - -/* - * Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register - * for Address operation - */ -#define NFC_ADDR 0x2 - -/* - * Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register - * for Input operation - */ -#define NFC_INPUT 0x4 - -/* - * Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register - * for Data Output operation - */ -#define NFC_OUTPUT 0x8 - -/* - * Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register - * for Read ID operation - */ -#define NFC_ID 0x10 - -/* - * Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register - * for Read Status operation - */ -#define NFC_STATUS 0x20 - -/* - * Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read - * Status operation - */ -#define NFC_INT 0x8000 - -#ifdef MXC_NFC_V1_1 -#define NFC_4_8N_ECC (1 << 0) -#else -#define NFC_4_8N_ECC 0 -#endif -#define NFC_SP_EN (1 << 2) -#define NFC_ECC_EN (1 << 3) -#define NFC_BIG (1 << 5) -#define NFC_RST (1 << 6) -#define NFC_CE (1 << 7) -#define NFC_ONE_CYCLE (1 << 8) - typedef enum {false, true} bool; struct mxc_nand_host { - struct mtd_info mtd; - struct nand_chip *nand; - - struct nfc_regs __iomem *regs; - int spare_only; - int status_request; - int pagesize_2k; - int clk_act; - uint16_t col_addr; - unsigned int page_addr; + struct mtd_info mtd; + struct nand_chip *nand; + + struct fsl_nfc_regs __iomem *regs; + int spare_only; + int status_request; + int pagesize_2k; + int clk_act; + uint16_t col_addr; + unsigned int page_addr; }; static struct mxc_nand_host mxc_host; @@ -304,10 +159,10 @@ static void wait_op_done(struct mxc_nand_host *host, int max_retries, uint32_t tmp; while (max_retries-- > 0) { - if (readw(&host->regs->nfc_config2) & NFC_INT) { - tmp = readw(&host->regs->nfc_config2); + if (readw(&host->regs->config2) & NFC_INT) { + tmp = readw(&host->regs->config2); tmp &= ~NFC_INT; - writew(tmp, &host->regs->nfc_config2); + writew(tmp, &host->regs->config2); break; } udelay(1); @@ -326,8 +181,8 @@ static void send_cmd(struct mxc_nand_host *host, uint16_t cmd) { MTDDEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x)\n", cmd); - writew(cmd, &host->regs->nfc_flash_cmd); - writew(NFC_CMD, &host->regs->nfc_config2); + writew(cmd, &host->regs->flash_cmd); + writew(NFC_CMD, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, cmd); @@ -342,8 +197,8 @@ static void send_addr(struct mxc_nand_host *host, uint16_t addr) { MTDDEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x)\n", addr); - writew(addr, &host->regs->nfc_flash_addr); - writew(NFC_ADDR, &host->regs->nfc_config2); + writew(addr, &host->regs->flash_addr); + writew(NFC_ADDR, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, addr); @@ -375,19 +230,19 @@ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, } } - writew(buf_id, &host->regs->nfc_buf_addr); + writew(buf_id, &host->regs->buf_addr); /* Configure spare or page+spare access */ if (!host->pagesize_2k) { - uint16_t config1 = readw(&host->regs->nfc_config1); + uint16_t config1 = readw(&host->regs->config1); if (spare_only) config1 |= NFC_SP_EN; else config1 &= ~(NFC_SP_EN); - writew(config1, &host->regs->nfc_config1); + writew(config1, &host->regs->config1); } - writew(NFC_INPUT, &host->regs->nfc_config2); + writew(NFC_INPUT, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, spare_only); @@ -402,19 +257,19 @@ static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id, { MTDDEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only); - writew(buf_id, &host->regs->nfc_buf_addr); + writew(buf_id, &host->regs->buf_addr); /* Configure spare or page+spare access */ if (!host->pagesize_2k) { - uint32_t config1 = readw(&host->regs->nfc_config1); + uint32_t config1 = readw(&host->regs->config1); if (spare_only) config1 |= NFC_SP_EN; else config1 &= ~NFC_SP_EN; - writew(config1, &host->regs->nfc_config1); + writew(config1, &host->regs->config1); } - writew(NFC_OUTPUT, &host->regs->nfc_config2); + writew(NFC_OUTPUT, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, spare_only); @@ -442,14 +297,14 @@ static void send_read_id(struct mxc_nand_host *host) uint16_t tmp; /* NANDFC buffer 0 is used for device ID output */ - writew(0x0, &host->regs->nfc_buf_addr); + writew(0x0, &host->regs->buf_addr); /* Read ID into main buffer */ - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp &= ~NFC_SP_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); - writew(NFC_ID, &host->regs->nfc_config2); + writew(NFC_ID, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, 0); @@ -469,14 +324,14 @@ static uint16_t get_dev_status(struct mxc_nand_host *host) /* store the main area1 first word, later do recovery */ store = readl(main_buf); /* NANDFC buffer 1 is used for device status */ - writew(1, &host->regs->nfc_buf_addr); + writew(1, &host->regs->buf_addr); /* Read status into main buffer */ - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp &= ~NFC_SP_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); - writew(NFC_STATUS, &host->regs->nfc_config2); + writew(NFC_STATUS, &host->regs->config2); /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, 0); @@ -515,13 +370,13 @@ static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on) { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - uint16_t tmp = readw(&host->regs->nfc_config1); + uint16_t tmp = readw(&host->regs->config1); if (on) tmp |= NFC_ECC_EN; else tmp &= ~NFC_ECC_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); } static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd, @@ -799,7 +654,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - uint16_t ecc_status = readw(&host->regs->nfc_ecc_status_result); + uint16_t ecc_status = readw(&host->regs->ecc_status_result); int subpages = mtd->writesize / nand_chip->subpagesize; int pg2blk_shift = nand_chip->phys_erase_shift - nand_chip->page_shift; @@ -845,7 +700,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, * additional correction. 2-Bit errors cannot be corrected by * HW ECC, so we need to return failure */ - uint16_t ecc_status = readw(&host->regs->nfc_ecc_status_result); + uint16_t ecc_status = readw(&host->regs->ecc_status_result); if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { MTDDEBUG(MTD_DEBUG_LEVEL0, @@ -1289,14 +1144,14 @@ static void mxc_setup_config1(void) { uint16_t tmp; - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp |= NFC_ONE_CYCLE; tmp |= NFC_4_8N_ECC; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); if (host->pagesize_2k) - writew(64/2, &host->regs->nfc_spare_area_size); + writew(64/2, &host->regs->spare_area_size); else - writew(16/2, &host->regs->nfc_spare_area_size); + writew(16/2, &host->regs->spare_area_size); } #else #define mxc_setup_config1() @@ -1359,7 +1214,7 @@ int board_nand_init(struct nand_chip *this) this->read_buf = mxc_nand_read_buf; this->verify_buf = mxc_nand_verify_buf; - host->regs = (struct nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE; + host->regs = (struct fsl_nfc_regs __iomem *)CONFIG_MXC_NAND_REGS_BASE; host->clk_act = 1; #ifdef CONFIG_MXC_NAND_HWECC @@ -1383,15 +1238,15 @@ int board_nand_init(struct nand_chip *this) host->pagesize_2k = 0; this->ecc.size = 512; - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp |= NFC_ECC_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); #else this->ecc.layout = &nand_soft_eccoob; this->ecc.mode = NAND_ECC_SOFT; - tmp = readw(&host->regs->nfc_config1); + tmp = readw(&host->regs->config1); tmp &= ~NFC_ECC_EN; - writew(tmp, &host->regs->nfc_config1); + writew(tmp, &host->regs->config1); #endif /* Reset NAND */ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); @@ -1400,10 +1255,10 @@ int board_nand_init(struct nand_chip *this) * preset operation * Unlock the internal RAM Buffer */ - writew(0x2, &host->regs->nfc_config); + writew(0x2, &host->regs->config); /* Blocks to be unlocked */ - writew(0x0, &host->regs->nfc_unlockstart_blkaddr); + writew(0x0, &host->regs->unlockstart_blkaddr); /* Originally (Freescale LTIB 2.6.21) 0x4000 was written to the * unlockend_blkaddr, but the magic 0x4000 does not always work * when writing more than some 32 megabytes (on 2k page nands) @@ -1415,10 +1270,10 @@ int board_nand_init(struct nand_chip *this) * This might be NAND chip specific and the i.MX31 datasheet is * extremely vague about the semantics of this register. */ - writew(0xFFFF, &host->regs->nfc_unlockend_blkaddr); + writew(0xFFFF, &host->regs->unlockend_blkaddr); /* Unlock Block Command for given address range */ - writew(0x4, &host->regs->nfc_wrprot); + writew(0x4, &host->regs->wrprot); /* NAND bus width determines access functions used by upper layer */ if (is_16bit_nand()) diff --git a/include/fsl_nfc.h b/include/fsl_nfc.h index 279aaa5..6691e41 100644 --- a/include/fsl_nfc.h +++ b/include/fsl_nfc.h @@ -24,28 +24,25 @@ #define __FSL_NFC_H /* - * TODO: Use same register defs for nand_spl mxc nand driver - * and mtd mxc nand driver. + * Register map and bit definitions for the Freescale NAND Flash Controller + * present in various i.MX devices. * - * Register map and bit definitions for the Freescale NAND Flash - * Controller present in various i.MX devices. + * MX31 and MX27 have version 1, which has: + * 4 512-byte main buffers and + * 4 16-byte spare buffers + * to support up to 2K byte pagesize nand. + * Reading or writing a 2K page requires 4 FDI/FDO cycles. * - * MX31 and MX27 have version 1 which has - * 4 512 byte main buffers and - * 4 16 byte spare buffers - * to support up to 2K byte pagesize nand. - * Reading or writing a 2K page requires 4 FDI/FDO cycles. - * - * MX25 has version 1.1 which has - * 8 512 byte main buffers and - * 8 64 byte spare buffers - * to support up to 4K byte pagesize nand. - * Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle. - * Also some of registers are moved and/or changed meaning as seen below. + * MX25 and MX35 have version 1.1, which has: + * 8 512-byte main buffers and + * 8 64-byte spare buffers + * to support up to 4K byte pagesize nand. + * Reading or writing a 2K or 4K page requires only 1 FDI/FDO cycle. + * Also some of registers are moved and/or changed meaning as seen below. */ -#if defined(CONFIG_MX31) || defined(CONFIG_MX27) +#if defined(CONFIG_MX27) || defined(CONFIG_MX31) #define MXC_NFC_V1 -#elif defined(CONFIG_MX25) +#elif defined(CONFIG_MX25) || defined(CONFIG_MX35) #define MXC_NFC_V1_1 #else #warning "MXC NFC version not defined" @@ -55,18 +52,20 @@ #define NAND_MXC_NR_BUFS 4 #define NAND_MXC_SPARE_BUF_SIZE 16 #define NAND_MXC_REG_OFFSET 0xe00 -#define NAND_MXC_2K_MULTI_CYCLE 1 +#define NAND_MXC_2K_MULTI_CYCLE +#define is_mxc_nfc_11() 0 #elif defined(MXC_NFC_V1_1) #define NAND_MXC_NR_BUFS 8 #define NAND_MXC_SPARE_BUF_SIZE 64 #define NAND_MXC_REG_OFFSET 0x1e00 +#define is_mxc_nfc_11() 1 #else -#error "define CONFIG_NAND_MXC_VXXX to use the mxc spl_nand driver" +#error "define CONFIG_NAND_MXC_VXXX to use the mxc nand driver" #endif struct fsl_nfc_regs { - u32 main_area[NAND_MXC_NR_BUFS][512/4]; - u32 spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE/4]; + u8 main_area[NAND_MXC_NR_BUFS][0x200]; + u8 spare_area[NAND_MXC_NR_BUFS][NAND_MXC_SPARE_BUF_SIZE]; /* * reserved size is offset of nfc registers * minus total main and spare sizes @@ -74,44 +73,44 @@ struct fsl_nfc_regs { u8 reserved1[NAND_MXC_REG_OFFSET - NAND_MXC_NR_BUFS * (512 + NAND_MXC_SPARE_BUF_SIZE)]; #if defined(MXC_NFC_V1) - u16 bufsiz; + u16 buf_size; u16 reserved2; - u16 buffer_address; - u16 flash_add; + u16 buf_addr; + u16 flash_addr; u16 flash_cmd; - u16 configuration; + u16 config; u16 ecc_status_result; - u16 ecc_rslt_main_area; - u16 ecc_rslt_spare_area; - u16 nf_wr_prot; - u16 unlock_start_blk_add; - u16 unlock_end_blk_add; - u16 nand_flash_wr_pr_st; - u16 nand_flash_config1; - u16 nand_flash_config2; + u16 rsltmain_area; + u16 rsltspare_area; + u16 wrprot; + u16 unlockstart_blkaddr; + u16 unlockend_blkaddr; + u16 nf_wrprst; + u16 config1; + u16 config2; #elif defined(MXC_NFC_V1_1) u16 reserved2[2]; - u16 buffer_address; - u16 flash_add; + u16 buf_addr; + u16 flash_addr; u16 flash_cmd; - u16 configuration; + u16 config; u16 ecc_status_result; u16 ecc_status_result2; u16 spare_area_size; - u16 nf_wr_prot; + u16 wrprot; u16 reserved3[2]; - u16 nand_flash_wr_pr_st; - u16 nand_flash_config1; - u16 nand_flash_config2; + u16 nf_wrprst; + u16 config1; + u16 config2; u16 reserved4; - u16 unlock_start_blk_add0; - u16 unlock_end_blk_add0; - u16 unlock_start_blk_add1; - u16 unlock_end_blk_add1; - u16 unlock_start_blk_add2; - u16 unlock_end_blk_add2; - u16 unlock_start_blk_add3; - u16 unlock_end_blk_add3; + u16 unlockstart_blkaddr; + u16 unlockend_blkaddr; + u16 unlockstart_blkaddr1; + u16 unlockend_blkaddr1; + u16 unlockstart_blkaddr2; + u16 unlockend_blkaddr2; + u16 unlockstart_blkaddr3; + u16 unlockend_blkaddr3; #endif }; diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index d6b0d9b..f437deb 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -36,13 +36,13 @@ static void nfc_wait_ready(void) { uint32_t tmp; - while (!(readw(&nfc->nand_flash_config2) & NFC_INT)) + while (!(readw(&nfc->config2) & NFC_INT)) ; /* Reset interrupt flag */ - tmp = readw(&nfc->nand_flash_config2); + tmp = readw(&nfc->config2); tmp &= ~NFC_INT; - writew(tmp, &nfc->nand_flash_config2); + writew(tmp, &nfc->config2); } void nfc_nand_init(void) @@ -54,10 +54,10 @@ void nfc_nand_init(void) writew(CONFIG_SYS_NAND_SPARE_SIZE / 2, &nfc->spare_area_size); /* unlocking RAM Buff */ - writew(0x2, &nfc->configuration); + writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - config1 = readw(&nfc->nand_flash_config1) | NFC_ECC_EN | 0x800; + config1 = readw(&nfc->config1) | NFC_ECC_EN | 0x800; /* * if spare size is larger that 16 bytes per 512 byte hunk * then use 8 symbol correction instead of 4 @@ -66,20 +66,20 @@ void nfc_nand_init(void) config1 &= ~NFC_4_8N_ECC; else config1 |= NFC_4_8N_ECC; - writew(config1, &nfc->nand_flash_config1); + writew(config1, &nfc->config1); #elif defined(MXC_NFC_V1) /* unlocking RAM Buff */ - writew(0x2, &nfc->configuration); + writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - writew(NFC_ECC_EN, &nfc->nand_flash_config1); + writew(NFC_ECC_EN, &nfc->config1); #endif } static void nfc_nand_command(unsigned short command) { writew(command, &nfc->flash_cmd); - writew(NFC_CMD, &nfc->nand_flash_config2); + writew(NFC_CMD, &nfc->config2); nfc_wait_ready(); } @@ -87,14 +87,14 @@ static void nfc_nand_page_address(unsigned int page_address) { unsigned int page_count; - writew(0x00, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); + writew(0x00, &nfc->flash_addr); + writew(NFC_ADDR, &nfc->config2); nfc_wait_ready(); /* code only for large page flash */ if (CONFIG_SYS_NAND_PAGE_SIZE > 512) { - writew(0x00, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); + writew(0x00, &nfc->flash_addr); + writew(NFC_ADDR, &nfc->config2); nfc_wait_ready(); } @@ -103,30 +103,30 @@ static void nfc_nand_page_address(unsigned int page_address) if (page_address <= page_count) { page_count--; /* transform 0x01000000 to 0x00ffffff */ do { - writew(page_address & 0xff, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); + writew(page_address & 0xff, &nfc->flash_addr); + writew(NFC_ADDR, &nfc->config2); nfc_wait_ready(); page_address = page_address >> 8; page_count = page_count >> 8; } while (page_count); } - writew(0x00, &nfc->flash_add); - writew(NFC_ADDR, &nfc->nand_flash_config2); + writew(0x00, &nfc->flash_addr); + writew(NFC_ADDR, &nfc->config2); nfc_wait_ready(); } static void nfc_nand_data_output(void) { - int config1 = readw(&nfc->nand_flash_config1); + int config1 = readw(&nfc->config1); #ifdef NAND_MXC_2K_MULTI_CYCLE int i; #endif config1 |= NFC_ECC_EN | NFC_INT_MSK; - writew(config1, &nfc->nand_flash_config1); - writew(0, &nfc->buffer_address); - writew(NFC_OUTPUT, &nfc->nand_flash_config2); + writew(config1, &nfc->config1); + writew(0, &nfc->buf_addr); + writew(NFC_OUTPUT, &nfc->config2); nfc_wait_ready(); #ifdef NAND_MXC_2K_MULTI_CYCLE /* @@ -134,11 +134,11 @@ static void nfc_nand_data_output(void) * for pages larger than 512 bytes. */ for (i = 1; i < (CONFIG_SYS_NAND_PAGE_SIZE / 512); i++) { - config1 = readw(&nfc->nand_flash_config1); + config1 = readw(&nfc->config1); config1 |= NFC_ECC_EN | NFC_INT_MSK; - writew(config1, &nfc->nand_flash_config1); - writew(i, &nfc->buffer_address); - writew(NFC_OUTPUT, &nfc->nand_flash_config2); + writew(config1, &nfc->config1); + writew(i, &nfc->buf_addr); + writew(NFC_OUTPUT, &nfc->config2); nfc_wait_ready(); } #endif @@ -155,7 +155,7 @@ static int nfc_read_page(unsigned int page_address, unsigned char *buf) u32 *src; u32 *dst; - writew(0, &nfc->buffer_address); /* read in first 0 buffer */ + writew(0, &nfc->buf_addr); /* read in first 0 buffer */ nfc_nand_command(NAND_CMD_READ0); nfc_nand_page_address(page_address); @@ -167,7 +167,7 @@ static int nfc_read_page(unsigned int page_address, unsigned char *buf) if (nfc_nand_check_ecc()) return -1; - src = &nfc->main_area[0][0]; + src = (u32 *)&nfc->main_area[0][0]; dst = (u32 *)buf; /* main copy loop from NAND-buffer to SDRAM memory */ @@ -188,7 +188,7 @@ static int is_badblock(int pagenumber) /* Check the first two pages for bad block markers */ for (page = pagenumber; page < pagenumber + 2; page++) { - writew(0, &nfc->buffer_address); /* read in first 0 buffer */ + writew(0, &nfc->buf_addr); /* read in first 0 buffer */ nfc_nand_command(NAND_CMD_READ0); nfc_nand_page_address(page); @@ -197,7 +197,7 @@ static int is_badblock(int pagenumber) nfc_nand_data_output(); /* fill the main buffer 0 */ - src = &nfc->spare_area[0][0]; + src = (u32 *)&nfc->spare_area[0][0]; /* * IMPORTANT NOTE: The nand flash controller uses a non- -- cgit v1.1 From 365b2c0761040764953e659f3385840e33823807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:48:26 +0200 Subject: mxc nand: cosmectic: Light cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 9 +++------ include/fsl_nfc.h | 1 + nand_spl/nand_boot_fsl_nfc.c | 14 +++++++------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 9a9260c..62d8c6b 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -123,8 +123,7 @@ static int is_16bit_nand(void) #elif defined(CONFIG_MX25) || defined(CONFIG_MX35) static int is_16bit_nand(void) { - struct ccm_regs *ccm = - (struct ccm_regs *)IMX_CCM_BASE; + struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; if (readl(&ccm->rcsr) & CCM_RCSR_NF_16BIT_SEL) return 1; @@ -238,7 +237,7 @@ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, if (spare_only) config1 |= NFC_SP_EN; else - config1 &= ~(NFC_SP_EN); + config1 &= ~NFC_SP_EN; writew(config1, &host->regs->config1); } @@ -687,7 +686,6 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, #define mxc_nand_write_page_syndrome NULL #define mxc_nand_write_page_raw_syndrome NULL #define mxc_nand_write_oob_syndrome NULL -#define mxc_nfc_11_nand_correct_data NULL static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) @@ -1188,7 +1186,6 @@ int board_nand_init(struct nand_chip *this) { struct mtd_info *mtd; uint16_t tmp; - int err = 0; #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT this->options |= NAND_USE_FLASH_BBT; @@ -1287,5 +1284,5 @@ int board_nand_init(struct nand_chip *this) this->ecc.layout = &nand_hw_eccoob; #endif mxc_setup_config1(); - return err; + return 0; } diff --git a/include/fsl_nfc.h b/include/fsl_nfc.h index 6691e41..1c16c71 100644 --- a/include/fsl_nfc.h +++ b/include/fsl_nfc.h @@ -166,5 +166,6 @@ struct fsl_nfc_regs { #define NFC_RST (1 << 6) #define NFC_CE (1 << 7) #define NFC_ONE_CYCLE (1 << 8) +#define NFC_FP_INT (1 << 11) #endif /* __FSL_NFC_H */ diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index f437deb..b90f93e 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -45,10 +45,10 @@ static void nfc_wait_ready(void) writew(tmp, &nfc->config2); } -void nfc_nand_init(void) +static void nfc_nand_init(void) { #if defined(MXC_NFC_V1_1) - int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; + int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; int config1; writew(CONFIG_SYS_NAND_SPARE_SIZE / 2, &nfc->spare_area_size); @@ -57,12 +57,12 @@ void nfc_nand_init(void) writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - config1 = readw(&nfc->config1) | NFC_ECC_EN | 0x800; + config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_FP_INT; /* * if spare size is larger that 16 bytes per 512 byte hunk * then use 8 symbol correction instead of 4 */ - if ((CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page) > 16) + if (CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page > 16) config1 &= ~NFC_4_8N_ECC; else config1 |= NFC_4_8N_ECC; @@ -133,7 +133,7 @@ static void nfc_nand_data_output(void) * This NAND controller requires multiple input commands * for pages larger than 512 bytes. */ - for (i = 1; i < (CONFIG_SYS_NAND_PAGE_SIZE / 512); i++) { + for (i = 1; i < CONFIG_SYS_NAND_PAGE_SIZE / 512; i++) { config1 = readw(&nfc->config1); config1 |= NFC_ECC_EN | NFC_INT_MSK; writew(config1, &nfc->config1); @@ -171,7 +171,7 @@ static int nfc_read_page(unsigned int page_address, unsigned char *buf) dst = (u32 *)buf; /* main copy loop from NAND-buffer to SDRAM memory */ - for (i = 0; i < (CONFIG_SYS_NAND_PAGE_SIZE / 4); i++) { + for (i = 0; i < CONFIG_SYS_NAND_PAGE_SIZE / 4; i++) { writel(readl(src), dst); src++; dst++; @@ -230,7 +230,7 @@ static int nand_load(unsigned int from, unsigned int size, unsigned char *buf) page = from / CONFIG_SYS_NAND_PAGE_SIZE; i = 0; - while (i < (size / CONFIG_SYS_NAND_PAGE_SIZE)) { + while (i < size / CONFIG_SYS_NAND_PAGE_SIZE) { if (nfc_read_page(page, buf) < 0) return -1; -- cgit v1.1 From 5d818a2821c3c7cf350ee4a2c67a11f8e1039af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:48:56 +0200 Subject: spl mxc nand: Merge duplicated code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge duplicated code into functions, which is better for SPL size too. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- nand_spl/nand_boot_fsl_nfc.c | 50 ++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index b90f93e..b98fe41 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -83,37 +83,35 @@ static void nfc_nand_command(unsigned short command) nfc_wait_ready(); } +static void nfc_nand_address(unsigned short address) +{ + writew(address, &nfc->flash_addr); + writew(NFC_ADDR, &nfc->config2); + nfc_wait_ready(); +} + static void nfc_nand_page_address(unsigned int page_address) { unsigned int page_count; - writew(0x00, &nfc->flash_addr); - writew(NFC_ADDR, &nfc->config2); - nfc_wait_ready(); + nfc_nand_address(0x00); /* code only for large page flash */ - if (CONFIG_SYS_NAND_PAGE_SIZE > 512) { - writew(0x00, &nfc->flash_addr); - writew(NFC_ADDR, &nfc->config2); - nfc_wait_ready(); - } + if (CONFIG_SYS_NAND_PAGE_SIZE > 512) + nfc_nand_address(0x00); page_count = CONFIG_SYS_NAND_SIZE / CONFIG_SYS_NAND_PAGE_SIZE; if (page_address <= page_count) { page_count--; /* transform 0x01000000 to 0x00ffffff */ do { - writew(page_address & 0xff, &nfc->flash_addr); - writew(NFC_ADDR, &nfc->config2); - nfc_wait_ready(); + nfc_nand_address(page_address & 0xff); page_address = page_address >> 8; page_count = page_count >> 8; } while (page_count); } - writew(0x00, &nfc->flash_addr); - writew(NFC_ADDR, &nfc->config2); - nfc_wait_ready(); + nfc_nand_address(0x00); } static void nfc_nand_data_output(void) @@ -149,12 +147,8 @@ static int nfc_nand_check_ecc(void) return readw(&nfc->ecc_status_result); } -static int nfc_read_page(unsigned int page_address, unsigned char *buf) +static void nfc_nand_read_page(unsigned int page_address) { - int i; - u32 *src; - u32 *dst; - writew(0, &nfc->buf_addr); /* read in first 0 buffer */ nfc_nand_command(NAND_CMD_READ0); nfc_nand_page_address(page_address); @@ -163,6 +157,15 @@ static int nfc_read_page(unsigned int page_address, unsigned char *buf) nfc_nand_command(NAND_CMD_READSTART); nfc_nand_data_output(); /* fill the main buffer 0 */ +} + +static int nfc_read_page(unsigned int page_address, unsigned char *buf) +{ + int i; + u32 *src; + u32 *dst; + + nfc_nand_read_page(page_address); if (nfc_nand_check_ecc()) return -1; @@ -188,14 +191,7 @@ static int is_badblock(int pagenumber) /* Check the first two pages for bad block markers */ for (page = pagenumber; page < pagenumber + 2; page++) { - writew(0, &nfc->buf_addr); /* read in first 0 buffer */ - nfc_nand_command(NAND_CMD_READ0); - nfc_nand_page_address(page); - - if (CONFIG_SYS_NAND_PAGE_SIZE > 512) - nfc_nand_command(NAND_CMD_READSTART); - - nfc_nand_data_output(); /* fill the main buffer 0 */ + nfc_nand_read_page(page); src = (u32 *)&nfc->spare_area[0][0]; -- cgit v1.1 From 0eee20fc1bb16f484771d626e1d7bde7d770a01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:49:15 +0200 Subject: spl mxc nand: Remove duplicated code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ECC_EN and INT_MSK bits of CONFIG1 are not volatile, so it is sufficient to set them once in nfc_nand_init(). Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- nand_spl/nand_boot_fsl_nfc.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index b98fe41..059969b 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -57,7 +57,7 @@ static void nfc_nand_init(void) writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_FP_INT; + config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_INT_MSK | NFC_FP_INT; /* * if spare size is larger that 16 bytes per 512 byte hunk * then use 8 symbol correction instead of 4 @@ -72,7 +72,7 @@ static void nfc_nand_init(void) writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - writew(NFC_ECC_EN, &nfc->config1); + writew(NFC_ECC_EN | NFC_INT_MSK, &nfc->config1); #endif } @@ -116,13 +116,10 @@ static void nfc_nand_page_address(unsigned int page_address) static void nfc_nand_data_output(void) { - int config1 = readw(&nfc->config1); #ifdef NAND_MXC_2K_MULTI_CYCLE int i; #endif - config1 |= NFC_ECC_EN | NFC_INT_MSK; - writew(config1, &nfc->config1); writew(0, &nfc->buf_addr); writew(NFC_OUTPUT, &nfc->config2); nfc_wait_ready(); @@ -132,9 +129,6 @@ static void nfc_nand_data_output(void) * for pages larger than 512 bytes. */ for (i = 1; i < CONFIG_SYS_NAND_PAGE_SIZE / 512; i++) { - config1 = readw(&nfc->config1); - config1 |= NFC_ECC_EN | NFC_INT_MSK; - writew(config1, &nfc->config1); writew(i, &nfc->buf_addr); writew(NFC_OUTPUT, &nfc->config2); nfc_wait_ready(); -- cgit v1.1 From 0e55ad7271259b1de183fb5329ea7f07774e368d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:49:31 +0200 Subject: spl mxc nand: Set symmetric mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set the spl mxc nand driver for IP 1.1 in symmetric mode, like the mtd driver. In this way, for both drivers, one input clock period of the NFC IP will produce one R/W cycle. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- nand_spl/nand_boot_fsl_nfc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index 059969b..842943c 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -57,7 +57,8 @@ static void nfc_nand_init(void) writew(0x2, &nfc->config); /* hardware ECC checking and correct */ - config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_INT_MSK | NFC_FP_INT; + config1 = readw(&nfc->config1) | NFC_ECC_EN | NFC_INT_MSK | + NFC_ONE_CYCLE | NFC_FP_INT; /* * if spare size is larger that 16 bytes per 512 byte hunk * then use 8 symbol correction instead of 4 -- cgit v1.1 From c1db8dd62b337372a08942e1c5945a8590afbc58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:49:42 +0200 Subject: mxc nand: Access all ecc_status_result fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the NFC IP 1.1, the 32-bit ecc_status_result value comes from 2 consecutive 16-bit registers. This patch reads all the fields of this value, which makes a difference for 4-kiB NF pages. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 2 +- include/fsl_nfc.h | 3 +-- nand_spl/nand_boot_fsl_nfc.c | 4 ++++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 62d8c6b..4564b25 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -653,7 +653,7 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, { struct nand_chip *nand_chip = mtd->priv; struct mxc_nand_host *host = nand_chip->priv; - uint16_t ecc_status = readw(&host->regs->ecc_status_result); + uint32_t ecc_status = readl(&host->regs->ecc_status_result); int subpages = mtd->writesize / nand_chip->subpagesize; int pg2blk_shift = nand_chip->phys_erase_shift - nand_chip->page_shift; diff --git a/include/fsl_nfc.h b/include/fsl_nfc.h index 1c16c71..c248cef 100644 --- a/include/fsl_nfc.h +++ b/include/fsl_nfc.h @@ -94,8 +94,7 @@ struct fsl_nfc_regs { u16 flash_addr; u16 flash_cmd; u16 config; - u16 ecc_status_result; - u16 ecc_status_result2; + u32 ecc_status_result; u16 spare_area_size; u16 wrprot; u16 reserved3[2]; diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index 842943c..4c5a7fe 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -139,7 +139,11 @@ static void nfc_nand_data_output(void) static int nfc_nand_check_ecc(void) { +#if defined(MXC_NFC_V1) return readw(&nfc->ecc_status_result); +#elif defined(MXC_NFC_V1_1) + return readl(&nfc->ecc_status_result); +#endif } static void nfc_nand_read_page(unsigned int page_address) -- cgit v1.1 From b8fea2b27d7aeabd2e0bc4242277ff2787c7c622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:49:53 +0200 Subject: spl mxc nand: Fix broken boot for correctable ECC errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not stop boot as soon as an ECC error is detected. Only stop boot for uncorrectable ECC errors. This fixes boards no longer booting after some time because a NAND Flash bit has flipped. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- nand_spl/nand_boot_fsl_nfc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index 4c5a7fe..ea05952 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -140,9 +140,21 @@ static void nfc_nand_data_output(void) static int nfc_nand_check_ecc(void) { #if defined(MXC_NFC_V1) - return readw(&nfc->ecc_status_result); + u16 ecc_status = readw(&nfc->ecc_status_result); + return (ecc_status & 0x3) == 2 || (ecc_status >> 2) == 2; #elif defined(MXC_NFC_V1_1) - return readl(&nfc->ecc_status_result); + u32 ecc_status = readl(&nfc->ecc_status_result); + int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; + int err_limit = CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page > 16 ? 8 : 4; + int subpages = CONFIG_SYS_NAND_PAGE_SIZE / 512; + + do { + if ((ecc_status & 0xf) > err_limit) + return 1; + ecc_status >>= 4; + } while (--subpages); + + return 0; #endif } -- cgit v1.1 From 0e499b07ef417b153e3feb54c249d56edbc364b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:50:07 +0200 Subject: mtd mxc nand: Use _mxc_nand_enable_hwecc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use _mxc_nand_enable_hwecc() instead of duplicating its code. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 4564b25..7a180e1 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -355,16 +355,6 @@ static int mxc_nand_dev_ready(struct mtd_info *mtd) return 1; } -#ifdef CONFIG_MXC_NAND_HWECC -static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) -{ - /* - * If HW ECC is enabled, we turn it on during init. There is - * no need to enable again here. - */ -} - -#ifdef MXC_NFC_V1_1 static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on) { struct nand_chip *nand_chip = mtd->priv; @@ -378,6 +368,16 @@ static void _mxc_nand_enable_hwecc(struct mtd_info *mtd, int on) writew(tmp, &host->regs->config1); } +#ifdef CONFIG_MXC_NAND_HWECC +static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) +{ + /* + * If HW ECC is enabled, we turn it on during init. There is + * no need to enable again here. + */ +} + +#ifdef MXC_NFC_V1_1 static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip, int page, int sndcmd) @@ -1235,15 +1235,11 @@ int board_nand_init(struct nand_chip *this) host->pagesize_2k = 0; this->ecc.size = 512; - tmp = readw(&host->regs->config1); - tmp |= NFC_ECC_EN; - writew(tmp, &host->regs->config1); + _mxc_nand_enable_hwecc(mtd, 1); #else this->ecc.layout = &nand_soft_eccoob; this->ecc.mode = NAND_ECC_SOFT; - tmp = readw(&host->regs->config1); - tmp &= ~NFC_ECC_EN; - writew(tmp, &host->regs->config1); + _mxc_nand_enable_hwecc(mtd, 0); #endif /* Reset NAND */ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); -- cgit v1.1 From 7c28a1cfdf5e919f2a09abb644f614f1b67d3322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:50:19 +0200 Subject: mtd mxc nand: Fix ECC state after read_page_raw_syndrome() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mxc_nand_read_page_raw_syndrome() should reenable ECC upon exit. This fixes ECC errors left uncorrected after a call to this function. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 7a180e1..2ae41dc 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -470,7 +470,7 @@ static int mxc_nand_read_page_raw_syndrome(struct mtd_info *mtd, size = mtd->oobsize - (oob - chip->oob_poi); if (size) chip->read_buf(mtd, oob, size); - _mxc_nand_enable_hwecc(mtd, 0); + _mxc_nand_enable_hwecc(mtd, 1); return 0; } -- cgit v1.1 From 13927f07334ce47a975c2e2a5bcd6bb708692534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:50:30 +0200 Subject: mtd mxc nand: Merge init functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge mxc_setup_config1() into board_nand_init() in order to ease the addition of i.MX5 support in the following patches. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 53 ++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 2ae41dc..e743796 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1137,24 +1137,6 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, } } -#ifdef MXC_NFC_V1_1 -static void mxc_setup_config1(void) -{ - uint16_t tmp; - - tmp = readw(&host->regs->config1); - tmp |= NFC_ONE_CYCLE; - tmp |= NFC_4_8N_ECC; - writew(tmp, &host->regs->config1); - if (host->pagesize_2k) - writew(64/2, &host->regs->spare_area_size); - else - writew(16/2, &host->regs->spare_area_size); -} -#else -#define mxc_setup_config1() -#endif - #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; @@ -1244,6 +1226,29 @@ int board_nand_init(struct nand_chip *this) /* Reset NAND */ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + /* NAND bus width determines access functions used by upper layer */ + if (is_16bit_nand()) + this->options |= NAND_BUSWIDTH_16; + +#ifdef CONFIG_SYS_NAND_LARGEPAGE + host->pagesize_2k = 1; + this->ecc.layout = &nand_hw_eccoob2k; +#else + host->pagesize_2k = 0; + this->ecc.layout = &nand_hw_eccoob; +#endif + +#ifdef MXC_NFC_V1_1 + tmp = readw(&host->regs->config1); + tmp |= NFC_ONE_CYCLE; + tmp |= NFC_4_8N_ECC; + writew(tmp, &host->regs->config1); + if (host->pagesize_2k) + writew(64/2, &host->regs->spare_area_size); + else + writew(16/2, &host->regs->spare_area_size); +#endif + /* * preset operation * Unlock the internal RAM Buffer @@ -1268,17 +1273,5 @@ int board_nand_init(struct nand_chip *this) /* Unlock Block Command for given address range */ writew(0x4, &host->regs->wrprot); - /* NAND bus width determines access functions used by upper layer */ - if (is_16bit_nand()) - this->options |= NAND_BUSWIDTH_16; - -#ifdef CONFIG_SYS_NAND_LARGEPAGE - host->pagesize_2k = 1; - this->ecc.layout = &nand_hw_eccoob2k; -#else - host->pagesize_2k = 0; - this->ecc.layout = &nand_hw_eccoob; -#endif - mxc_setup_config1(); return 0; } -- cgit v1.1 From 1884d6577e6b298ab2966d7d8fd7be888c3b7332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:50:42 +0200 Subject: mxc nand: Let driver detect IP revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no reason to have board configs to select the NFC IP revision. Just let the driver detect it. BTW, remove broken NFC IP revision configs from board config files. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- include/configs/flea3.h | 1 - include/configs/mx35pdk.h | 1 - include/configs/tx25.h | 1 - include/fsl_nfc.h | 8 +++----- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/include/configs/flea3.h b/include/configs/flea3.h index 4350518..027a5dc 100644 --- a/include/configs/flea3.h +++ b/include/configs/flea3.h @@ -213,7 +213,6 @@ * NAND FLASH driver setup */ #define CONFIG_NAND_MXC -#define CONFIG_NAND_MXC_V1_1 #define CONFIG_MXC_NAND_REGS_BASE (NFC_BASE_ADDR) #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE (NFC_BASE_ADDR) diff --git a/include/configs/mx35pdk.h b/include/configs/mx35pdk.h index 9bc6bd4..5816152 100644 --- a/include/configs/mx35pdk.h +++ b/include/configs/mx35pdk.h @@ -231,7 +231,6 @@ * NAND FLASH driver setup */ #define CONFIG_NAND_MXC -#define CONFIG_NAND_MXC_V1_1 #define CONFIG_MXC_NAND_REGS_BASE (NFC_BASE_ADDR) #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE (NFC_BASE_ADDR) diff --git a/include/configs/tx25.h b/include/configs/tx25.h index c8a49bb..71b1d32 100644 --- a/include/configs/tx25.h +++ b/include/configs/tx25.h @@ -107,7 +107,6 @@ /* NAND */ #define CONFIG_NAND_MXC -#define CONFIG_NAND_MXC_V1_1 #define CONFIG_MXC_NAND_REGS_BASE (0xBB000000) #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE (0xBB000000) diff --git a/include/fsl_nfc.h b/include/fsl_nfc.h index c248cef..6618089 100644 --- a/include/fsl_nfc.h +++ b/include/fsl_nfc.h @@ -42,10 +42,12 @@ */ #if defined(CONFIG_MX27) || defined(CONFIG_MX31) #define MXC_NFC_V1 +#define is_mxc_nfc_11() 0 #elif defined(CONFIG_MX25) || defined(CONFIG_MX35) #define MXC_NFC_V1_1 +#define is_mxc_nfc_11() 1 #else -#warning "MXC NFC version not defined" +#error "MXC NFC implementation not supported" #endif #if defined(MXC_NFC_V1) @@ -53,14 +55,10 @@ #define NAND_MXC_SPARE_BUF_SIZE 16 #define NAND_MXC_REG_OFFSET 0xe00 #define NAND_MXC_2K_MULTI_CYCLE -#define is_mxc_nfc_11() 0 #elif defined(MXC_NFC_V1_1) #define NAND_MXC_NR_BUFS 8 #define NAND_MXC_SPARE_BUF_SIZE 64 #define NAND_MXC_REG_OFFSET 0x1e00 -#define is_mxc_nfc_11() 1 -#else -#error "define CONFIG_NAND_MXC_VXXX to use the mxc nand driver" #endif struct fsl_nfc_regs { -- cgit v1.1 From 9c60e75e05dab5a0197728b6a940aaac02762936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Mon, 13 Aug 2012 22:50:53 +0200 Subject: mxc nand: Homogenize IP revisions with Linux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the same IP revisions as in Linux in order to make the comparison more clear. Signed-off-by: Benoît Thébaudeau Cc: Scott Wood Cc: Stefano Babic Signed-off-by: Scott Wood --- drivers/mtd/nand/mxc_nand.c | 16 ++++++++-------- include/fsl_nfc.h | 16 +++++++++------- nand_spl/nand_boot_fsl_nfc.c | 4 ++-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index e743796..cf2a7b0 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -77,7 +77,7 @@ static struct nand_ecclayout nand_hw_eccoob2k = { .oobfree = { {2, 4}, {11, 11}, {27, 11}, {43, 11}, {59, 5} }, }; #endif -#elif defined(MXC_NFC_V1_1) +#elif defined(MXC_NFC_V2_1) #ifndef CONFIG_SYS_NAND_LARGEPAGE static struct nand_ecclayout nand_hw_eccoob = { .eccbytes = 9, @@ -213,7 +213,7 @@ static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, if (spare_only) MTDDEBUG(MTD_DEBUG_LEVEL1, "send_prog_page (%d)\n", spare_only); - if (is_mxc_nfc_11()) { + if (is_mxc_nfc_21()) { int i; /* * The controller copies the 64 bytes of spare data from @@ -273,7 +273,7 @@ static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id, /* Wait for operation to complete */ wait_op_done(host, TROP_US_DELAY, spare_only); - if (is_mxc_nfc_11()) { + if (is_mxc_nfc_21()) { int i; /* @@ -377,7 +377,7 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) */ } -#ifdef MXC_NFC_V1_1 +#ifdef MXC_NFC_V2_1 static int mxc_nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip, int page, int sndcmd) @@ -1061,7 +1061,7 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, case NAND_CMD_PAGEPROG: send_prog_page(host, 0, host->spare_only); - if (host->pagesize_2k && !is_mxc_nfc_11()) { + if (host->pagesize_2k && is_mxc_nfc_1()) { /* data in 4 areas */ send_prog_page(host, 1, host->spare_only); send_prog_page(host, 2, host->spare_only); @@ -1111,7 +1111,7 @@ void mxc_nand_command(struct mtd_info *mtd, unsigned command, send_cmd(host, NAND_CMD_READSTART); /* read for each AREA */ send_read_page(host, 0, host->spare_only); - if (!is_mxc_nfc_11()) { + if (is_mxc_nfc_1()) { send_read_page(host, 1, host->spare_only); send_read_page(host, 2, host->spare_only); send_read_page(host, 3, host->spare_only); @@ -1200,7 +1200,7 @@ int board_nand_init(struct nand_chip *this) this->ecc.calculate = mxc_nand_calculate_ecc; this->ecc.hwctl = mxc_nand_enable_hwecc; this->ecc.correct = mxc_nand_correct_data; - if (is_mxc_nfc_11()) { + if (is_mxc_nfc_21()) { this->ecc.mode = NAND_ECC_HW_SYNDROME; this->ecc.read_page = mxc_nand_read_page_syndrome; this->ecc.read_page_raw = mxc_nand_read_page_raw_syndrome; @@ -1238,7 +1238,7 @@ int board_nand_init(struct nand_chip *this) this->ecc.layout = &nand_hw_eccoob; #endif -#ifdef MXC_NFC_V1_1 +#ifdef MXC_NFC_V2_1 tmp = readw(&host->regs->config1); tmp |= NFC_ONE_CYCLE; tmp |= NFC_4_8N_ECC; diff --git a/include/fsl_nfc.h b/include/fsl_nfc.h index 6618089..ff537b4 100644 --- a/include/fsl_nfc.h +++ b/include/fsl_nfc.h @@ -33,7 +33,7 @@ * to support up to 2K byte pagesize nand. * Reading or writing a 2K page requires 4 FDI/FDO cycles. * - * MX25 and MX35 have version 1.1, which has: + * MX25 and MX35 have version 2.1, which has: * 8 512-byte main buffers and * 8 64-byte spare buffers * to support up to 4K byte pagesize nand. @@ -42,10 +42,12 @@ */ #if defined(CONFIG_MX27) || defined(CONFIG_MX31) #define MXC_NFC_V1 -#define is_mxc_nfc_11() 0 +#define is_mxc_nfc_1() 1 +#define is_mxc_nfc_21() 0 #elif defined(CONFIG_MX25) || defined(CONFIG_MX35) -#define MXC_NFC_V1_1 -#define is_mxc_nfc_11() 1 +#define MXC_NFC_V2_1 +#define is_mxc_nfc_1() 0 +#define is_mxc_nfc_21() 1 #else #error "MXC NFC implementation not supported" #endif @@ -55,7 +57,7 @@ #define NAND_MXC_SPARE_BUF_SIZE 16 #define NAND_MXC_REG_OFFSET 0xe00 #define NAND_MXC_2K_MULTI_CYCLE -#elif defined(MXC_NFC_V1_1) +#elif defined(MXC_NFC_V2_1) #define NAND_MXC_NR_BUFS 8 #define NAND_MXC_SPARE_BUF_SIZE 64 #define NAND_MXC_REG_OFFSET 0x1e00 @@ -86,7 +88,7 @@ struct fsl_nfc_regs { u16 nf_wrprst; u16 config1; u16 config2; -#elif defined(MXC_NFC_V1_1) +#elif defined(MXC_NFC_V2_1) u16 reserved2[2]; u16 buf_addr; u16 flash_addr; @@ -153,7 +155,7 @@ struct fsl_nfc_regs { */ #define NFC_INT 0x8000 -#ifdef MXC_NFC_V1_1 +#ifdef MXC_NFC_V2_1 #define NFC_4_8N_ECC (1 << 0) #endif #define NFC_SP_EN (1 << 2) diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c index ea05952..a40c998 100644 --- a/nand_spl/nand_boot_fsl_nfc.c +++ b/nand_spl/nand_boot_fsl_nfc.c @@ -47,7 +47,7 @@ static void nfc_wait_ready(void) static void nfc_nand_init(void) { -#if defined(MXC_NFC_V1_1) +#if defined(MXC_NFC_V2_1) int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; int config1; @@ -142,7 +142,7 @@ static int nfc_nand_check_ecc(void) #if defined(MXC_NFC_V1) u16 ecc_status = readw(&nfc->ecc_status_result); return (ecc_status & 0x3) == 2 || (ecc_status >> 2) == 2; -#elif defined(MXC_NFC_V1_1) +#elif defined(MXC_NFC_V2_1) u32 ecc_status = readl(&nfc->ecc_status_result); int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512; int err_limit = CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page > 16 ? 8 : 4; -- cgit v1.1 From efa1f43b7dbdc0ab4db103f472f2838adc6f7ba1 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 18 Sep 2012 09:24:22 -0700 Subject: mxc nand: Fix warning on !MXC_NFC_V2_1 In board_nand_init() we only need the 'tmp' variable if MXC_NFC_V2_1 is defined. Signed-off-by: Tom Rini --- drivers/mtd/nand/mxc_nand.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index cf2a7b0..d0ded48 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1167,7 +1167,9 @@ static struct nand_bbt_descr bbt_mirror_descr = { int board_nand_init(struct nand_chip *this) { struct mtd_info *mtd; +#ifdef MXC_NFC_V2_1 uint16_t tmp; +#endif #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT this->options |= NAND_USE_FLASH_BBT; -- cgit v1.1 From fa2afe02743a74280717020d17f0c1d603468553 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 27 Jul 2012 08:04:32 +0000 Subject: dm: sparc: net: Fixup greth compile warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit greth.c: In function ‘greth_recv’: greth.c:507:3: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘unsigned int’ [-Wformat] greth.c:507:3: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘unsigned int’ [-Wformat] greth.c:541:6: warning: pointer targets in assignment differ in signedness [-Wpointer-sign] greth.c: In function ‘greth_initialize’: greth.c:623:2: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘struct greth_regs *’ [-Wformat] greth.c:655:3: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘struct greth_regs *’ [-Wformat] greth.c:684:2: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘struct greth_regs *’ [-Wformat] Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Daniel Hellstrom Cc: u-boot-dm@lists.denx.de --- drivers/net/greth.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/greth.c b/drivers/net/greth.c index 08206c8..3103a74 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -483,7 +483,7 @@ int greth_recv(struct eth_device *dev) greth_regs *regs = greth->regs; greth_bd *rxbd; unsigned int status, len = 0, bad; - unsigned char *d; + char *d; int enable = 0; int i; @@ -504,7 +504,7 @@ int greth_recv(struct eth_device *dev) goto done; } - debug("greth_recv: packet 0x%lx, 0x%lx, len: %d\n", + debug("greth_recv: packet 0x%x, 0x%x, len: %d\n", (unsigned int)rxbd, status, status & GRETH_BD_LEN); /* Check status for errors. @@ -620,7 +620,7 @@ int greth_initialize(bd_t * bis) greth->regs = (greth_regs *) apbdev.address; greth->irq = apbdev.irq; - debug("Found GRETH at 0x%lx, irq %d\n", greth->regs, greth->irq); + debug("Found GRETH at %p, irq %d\n", greth->regs, greth->irq); dev->priv = (void *)greth; dev->iobase = (unsigned int)greth->regs; dev->init = greth_init; @@ -652,7 +652,7 @@ int greth_initialize(bd_t * bis) /* initiate PHY, select speed/duplex depending on connected PHY */ if (greth_init_phy(greth, bis)) { /* Failed to init PHY (timedout) */ - debug("GRETH[0x%08x]: Failed to init PHY\n", greth->regs); + debug("GRETH[%p]: Failed to init PHY\n", greth->regs); return -1; } @@ -681,6 +681,6 @@ int greth_initialize(bd_t * bis) /* set and remember MAC address */ greth_set_hwaddr(greth, addr); - debug("GRETH[0x%08x]: Initialized successfully\n", greth->regs); + debug("GRETH[%p]: Initialized successfully\n", greth->regs); return 0; } -- cgit v1.1 From d97f01a64fa87a018258dfe6cfe4fff1b08975e0 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 27 Jul 2012 08:04:33 +0000 Subject: dm: sparc: common: Fixup cmd_bdinfo warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cmd_bdinfo.c: In function ‘do_bdinfo’: cmd_bdinfo.c:220:9: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘int’ [-Wformat] cmd_bdinfo.c:222:9: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘int’ [-Wformat] cmd_bdinfo.c:224:9: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘int’ [-Wformat] cmd_bdinfo.c:226:9: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘int’ [-Wformat] cmd_bdinfo.c:228:9: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘int’ [-Wformat] Signed-off-by: Marek Vasut Cc: Daniel Hellstrom Cc: u-boot-dm@lists.denx.de --- common/cmd_bdinfo.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index 42f08fd..23bd8a5 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -216,15 +216,15 @@ int do_bdinfo(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) print_num("flashstart ", bd->bi_flashstart); print_num("CONFIG_SYS_MONITOR_BASE ", CONFIG_SYS_MONITOR_BASE); print_num("CONFIG_ENV_ADDR ", CONFIG_ENV_ADDR); - printf("CONFIG_SYS_RELOC_MONITOR_BASE = 0x%lx (%d)\n", CONFIG_SYS_RELOC_MONITOR_BASE, + printf("CONFIG_SYS_RELOC_MONITOR_BASE = 0x%x (%d)\n", CONFIG_SYS_RELOC_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN); - printf("CONFIG_SYS_MALLOC_BASE = 0x%lx (%d)\n", CONFIG_SYS_MALLOC_BASE, + printf("CONFIG_SYS_MALLOC_BASE = 0x%x (%d)\n", CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN); - printf("CONFIG_SYS_INIT_SP_OFFSET = 0x%lx (%d)\n", CONFIG_SYS_INIT_SP_OFFSET, + printf("CONFIG_SYS_INIT_SP_OFFSET = 0x%x (%d)\n", CONFIG_SYS_INIT_SP_OFFSET, CONFIG_SYS_STACK_SIZE); - printf("CONFIG_SYS_PROM_OFFSET = 0x%lx (%d)\n", CONFIG_SYS_PROM_OFFSET, + printf("CONFIG_SYS_PROM_OFFSET = 0x%x (%d)\n", CONFIG_SYS_PROM_OFFSET, CONFIG_SYS_PROM_SIZE); - printf("CONFIG_SYS_GBL_DATA_OFFSET = 0x%lx (%d)\n", CONFIG_SYS_GBL_DATA_OFFSET, + printf("CONFIG_SYS_GBL_DATA_OFFSET = 0x%x (%d)\n", CONFIG_SYS_GBL_DATA_OFFSET, GENERATED_GBL_DATA_SIZE); #if defined(CONFIG_CMD_NET) -- cgit v1.1 From b2f2760006344a55ed93eae870312ab9675eea7d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 27 Jul 2012 08:04:34 +0000 Subject: dm: sparc: Fixup the compile warnings in sparc code Signed-off-by: Marek Vasut Cc: Daniel Hellstrom Cc: u-boot-dm@lists.denx.de --- arch/sparc/cpu/leon2/interrupts.c | 6 +++--- arch/sparc/cpu/leon3/interrupts.c | 6 +++--- arch/sparc/lib/board.c | 1 - 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/sparc/cpu/leon2/interrupts.c b/arch/sparc/cpu/leon2/interrupts.c index 5149550..f707efd 100644 --- a/arch/sparc/cpu/leon2/interrupts.c +++ b/arch/sparc/cpu/leon2/interrupts.c @@ -207,9 +207,9 @@ void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const a for (irq = 0; irq < NR_IRQS; irq++) { if (irq_handlers[irq].handler != NULL) { - printf("%02d %08lx %08lx %ld\n", irq, - (unsigned int)irq_handlers[irq].handler, - (unsigned int)irq_handlers[irq].arg, + printf("%02d %p %p %d\n", irq, + irq_handlers[irq].handler, + irq_handlers[irq].arg, irq_handlers[irq].count); } } diff --git a/arch/sparc/cpu/leon3/interrupts.c b/arch/sparc/cpu/leon3/interrupts.c index 4138f9b..4a3847d 100644 --- a/arch/sparc/cpu/leon3/interrupts.c +++ b/arch/sparc/cpu/leon3/interrupts.c @@ -209,9 +209,9 @@ void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char * const a for (irq = 0; irq < NR_IRQS; irq++) { if (irq_handlers[irq].handler != NULL) { - printf("%02d %08lx %08lx %ld\n", irq, - (unsigned int)irq_handlers[irq].handler, - (unsigned int)irq_handlers[irq].arg, + printf("%02d %p %p %d\n", irq, + irq_handlers[irq].handler, + irq_handlers[irq].arg, irq_handlers[irq].count); } } diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c index 7e48775..6f33666 100644 --- a/arch/sparc/lib/board.c +++ b/arch/sparc/lib/board.c @@ -166,7 +166,6 @@ char *str_init_seq_done = "\n\rInit sequence done...\r\n\r\n"; void board_init_f(ulong bootflag) { bd_t *bd; - unsigned char *s; init_fnc_t **init_fnc_ptr; int j; -- cgit v1.1 From be7e41efdab086d15108020de8eeada8e7baac8d Mon Sep 17 00:00:00 2001 From: Tyler Olmstead Date: Wed, 8 Aug 2012 16:24:13 +0000 Subject: spl: remove forced linking of commands into SPL Remove linker command line options from the SPL makefile that force the inclusion of unreferenced command code from linked object files. As commands are not used in the SPL, these options resulted in an unnecessary increase in the image size, in addition to introducing the possibility of tricky link errors in the case where the command code contained symbols that were not resolved by linking in the limited objects compiled in the SPL build. Signed-off-by: Tyler Olmstead Acked-by: Tom Rini --- spl/Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/spl/Makefile b/spl/Makefile index 476a5e6..d4cb668 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -135,9 +135,7 @@ $(obj)u-boot-spl.bin: $(obj)u-boot-spl $(OBJCOPY) $(OBJCFLAGS) -O binary $< $@ GEN_UBOOT = \ - UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) | \ - sed -n -e 's/.*\($(SYM_PREFIX)__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\ - cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) $$UNDEF_SYM $(__START) \ + cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) $(__START) \ --start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \ -Map u-boot-spl.map -o u-boot-spl -- cgit v1.1 From e4a189acfed4e8a99599f948a019f709b066722f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 5 Sep 2012 17:09:08 +0000 Subject: IPL: Remove remains of OneNAND IPL After removing the Apollon board, remove the OneNAND IPL too. There are no users for it any more. Signed-off-by: Marek Vasut Cc: Albert Aribaud Cc: Minkyu Kang Cc: Tom Rini Acked-by: Minkyu Kang --- .gitignore | 5 -- Makefile | 10 --- board/samsung/goni/lowlevel_init.S | 120 ------------------------- board/samsung/smdkc100/lowlevel_init.S | 42 --------- onenand_ipl/onenand_boot.c | 48 ---------- onenand_ipl/onenand_ipl.h | 36 -------- onenand_ipl/onenand_read.c | 158 --------------------------------- 7 files changed, 419 deletions(-) delete mode 100644 onenand_ipl/onenand_boot.c delete mode 100644 onenand_ipl/onenand_ipl.h delete mode 100644 onenand_ipl/onenand_read.c diff --git a/.gitignore b/.gitignore index 2e6fde8..d91e91b 100644 --- a/.gitignore +++ b/.gitignore @@ -75,10 +75,5 @@ cscope.* /ctags /etags -# OneNAND IPL files -/onenand_ipl/onenand-ipl* -/onenand_ipl/board/*/onenand* -/onenand_ipl/board/*/*.S - # spl ais files /spl/*.ais diff --git a/Makefile b/Makefile index 058fb53..971513d 100644 --- a/Makefile +++ b/Makefile @@ -378,7 +378,6 @@ ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map ALL-$(CONFIG_NAND_U_BOOT) += $(obj)u-boot-nand.bin ALL-$(CONFIG_ONENAND_U_BOOT) += $(obj)u-boot-onenand.bin -ONENAND_BIN ?= $(obj)onenand_ipl/onenand-ipl-2k.bin ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin ALL-$(CONFIG_OF_SEPARATE) += $(obj)u-boot.dtb $(obj)u-boot-dtb.bin @@ -550,12 +549,6 @@ nand_spl: $(TIMESTAMP_FILE) $(VERSION_FILE) depend $(obj)u-boot-nand.bin: nand_spl $(obj)u-boot.bin cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin -onenand_ipl: $(TIMESTAMP_FILE) $(VERSION_FILE) $(obj)include/autoconf.mk - $(MAKE) -C onenand_ipl/board/$(BOARDDIR) all - -$(obj)u-boot-onenand.bin: onenand_ipl $(obj)u-boot.bin - cat $(ONENAND_BIN) $(obj)u-boot.bin > $(obj)u-boot-onenand.bin - $(obj)spl/u-boot-spl.bin: $(SUBDIR_TOOLS) depend $(MAKE) -C spl all @@ -790,9 +783,7 @@ clean: @rm -f $(obj)include/generated/asm-offsets.h @rm -f $(obj)$(CPUDIR)/$(SOC)/asm-offsets.s @rm -f $(obj)nand_spl/{u-boot.lds,u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map,System.map} - @rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl.map} @rm -f $(ONENAND_BIN) - @rm -f $(obj)onenand_ipl/u-boot.lds @rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.lds,u-boot-spl.map} @rm -f $(obj)MLO @rm -f $(TIMESTAMP_FILE) $(VERSION_FILE) @@ -825,7 +816,6 @@ clobber: tidy @rm -fr $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm @rm -fr $(obj)include/generated @[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -name "*" -type l -print | xargs rm -f - @[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -name "*" -type l -print | xargs rm -f @rm -f $(obj)dts/*.tmp @rm -f $(obj)spl/u-boot-spl{,-pad}.ais diff --git a/board/samsung/goni/lowlevel_init.S b/board/samsung/goni/lowlevel_init.S index 30a5835..1effc9c 100644 --- a/board/samsung/goni/lowlevel_init.S +++ b/board/samsung/goni/lowlevel_init.S @@ -79,11 +79,7 @@ skip_check_didle: str r1, [r0, #0x0] @ GPIO_CON_OFFSET ldr r1, [r0, #0x4] @ GPIO_DAT_OFFSET -#ifdef CONFIG_ONENAND_IPL - orr r1, r1, #(1 << 1) @ 1 * 1-bit -#else bic r1, r1, #(1 << 1) -#endif str r1, [r0, #0x4] @ GPIO_DAT_OFFSET /* Don't setup at s5pc100 */ @@ -182,7 +178,6 @@ skip_check_didle: /* Do not release retention here for S5PC110 */ streq r1, [r0] -#ifndef CONFIG_ONENAND_IPL /* Disable Watchdog */ ldreq r0, =S5PC100_WATCHDOG_BASE @ 0xEA200000 ldrne r0, =S5PC110_WATCHDOG_BASE @ 0xE2700000 @@ -193,7 +188,6 @@ skip_check_didle: ldrne r0, =S5PC110_SROMC_BASE ldr r1, =0x9 str r1, [r0] -#endif /* S5PC100 has 3 groups of interrupt sources */ ldreq r0, =S5PC100_VIC0_BASE @ 0xE4000000 @@ -207,7 +201,6 @@ skip_check_didle: str r3, [r1, #0x14] @ INTENCLEAR str r3, [r2, #0x14] @ INTENCLEAR -#ifndef CONFIG_ONENAND_IPL /* Set all interrupts as IRQ */ str r5, [r0, #0xc] @ INTSELECT str r5, [r1, #0xc] @ INTSELECT @@ -217,120 +210,12 @@ skip_check_didle: str r5, [r0, #0xf00] @ INTADDRESS str r5, [r1, #0xf00] @ INTADDRESS str r5, [r2, #0xf00] @ INTADDRESS -#endif -#ifndef CONFIG_ONENAND_IPL /* for UART */ bl uart_asm_init bl internal_ram_init -#endif - -#ifdef CONFIG_ONENAND_IPL - /* init system clock */ - bl system_clock_init - - /* OneNAND Sync Read Support at S5PC110 only - * RM[15] : Sync Read - * BRWL[14:12] : 7 CLK - * BL[11:9] : Continuous - * VHF[3] : Very High Frequency Enable (Over 83MHz) - * HF[2] : High Frequency Enable (Over 66MHz) - * WM[1] : Sync Write - */ - cmp r7, r8 - ldrne r1, =0xE006 - ldrne r0, =0xB001E442 - strneh r1, [r0] - - /* - * GCE[26] : Gated Clock Enable - * RPE[17] : Enables Read Prefetch - */ - ldrne r1, =((1 << 26) | (1 << 17) | 0xE006) - ldrne r0, =0xB0600000 - strne r1, [r0, #0x100] @ ONENAND_IF_CTRL - ldrne r1, =0x1212 - strne r1, [r0, #0x108] - - /* Board detection to set proper memory configuration */ - cmp r7, r8 - moveq r9, #1 /* r9 has 1Gib default at s5pc100 */ - movne r9, #2 /* r9 has 2Gib default at s5pc110 */ - - ldr r2, =0xE0200200 - ldr r4, [r2, #0x48] - - bic r1, r4, #(0x3F << 4) /* PULLUP_DISABLE: 3 * 2-bit */ - bic r1, r1, #(0x3 << 2) /* PULLUP_DISABLE: 2 * 2-bit */ - bic r1, r1, #(0x3 << 14) /* PULLUP_DISABLE: 2 * 2-bit */ - str r1, [r2, #0x48] - /* For write completion */ - nop - nop - - ldr r3, [r2, #0x44] - and r1, r3, #(0x7 << 2) - mov r1, r1, lsr #2 - cmp r1, #0x5 - moveq r9, #3 - cmp r1, #0x6 - moveq r9, #1 - cmp r1, #0x7 - moveq r9, #2 - and r0, r3, #(0x1 << 1) - mov r0, r0, lsr #1 - orr r1, r1, r0, lsl #3 - cmp r1, #0x8 - moveq r9, #3 - and r1, r3, #(0x7 << 2) - mov r1, r1, lsr #2 - and r0, r3, #(0x1 << 7) - mov r0, r0, lsr #7 - orr r1, r1, r0, lsl #3 - cmp r1, #0x9 - moveq r9, #3 - str r4, [r2, #0x48] /* Restore PULLUP configuration */ - - bl mem_ctrl_asm_init - - /* Wakeup support. Don't know if it's going to be used, untested. */ - ldreq r0, =S5PC100_RST_STAT - ldrne r0, =S5PC110_RST_STAT - ldr r1, [r0] - biceq r1, r1, #0xfffffff7 - moveq r2, #(1 << 3) - bicne r1, r1, #0xfffeffff - movne r2, #(1 << 16) - cmp r1, r2 - bne 1f -wakeup: - /* turn off L2 cache */ - bl l2_cache_disable - - cmp r7, r8 - ldreq r0, =0xC100 - ldrne r0, =0xC110 - - /* invalidate L2 cache also */ - bl invalidate_dcache - - /* turn on L2 cache */ - bl l2_cache_enable - - cmp r7, r8 - /* Load return address and jump to kernel */ - ldreq r0, =S5PC100_INFORM0 - ldrne r0, =S5PC110_INFORM0 - - /* r1 = physical address of s5pc1xx_cpu_resume function */ - ldr r1, [r0] - /* Jump to kernel (sleep-s5pc1xx.S) */ - mov pc, r1 - nop - nop -#else cmp r7, r8 /* Clear wakeup status register */ ldreq r0, =S5PC100_WAKEUP_STAT @@ -347,7 +232,6 @@ wakeup: orr r1, r1, r2 str r1, [r0] -#endif b 1f didle_wakeup: @@ -517,7 +401,6 @@ system_clock_init: mov pc, lr -#ifndef CONFIG_ONENAND_IPL internal_ram_init: ldreq r0, =0xE3800000 ldrne r0, =0xF1500000 @@ -525,9 +408,7 @@ internal_ram_init: str r1, [r0] mov pc, lr -#endif -#ifndef CONFIG_ONENAND_IPL /* * uart_asm_init: Initialize UART's pins */ @@ -582,4 +463,3 @@ uart_asm_init: str r1, [r0, #0x4] @ S5PC1XX_GPIO_DAT_OFFSET 200: mov pc, lr -#endif diff --git a/board/samsung/smdkc100/lowlevel_init.S b/board/samsung/smdkc100/lowlevel_init.S index 6d18835..6f9a554 100644 --- a/board/samsung/smdkc100/lowlevel_init.S +++ b/board/samsung/smdkc100/lowlevel_init.S @@ -50,12 +50,10 @@ lowlevel_init: orr r0, r0, #0x0 str r5, [r0] -#ifndef CONFIG_ONENAND_IPL /* setting SRAM */ ldr r0, =S5PC100_SROMC_BASE ldr r1, =0x9 str r1, [r0] -#endif /* S5PC100 has 3 groups of interrupt sources */ ldr r0, =S5PC100_VIC0_BASE @0xE4000000 @@ -68,7 +66,6 @@ lowlevel_init: str r3, [r1, #0x14] @INTENCLEAR str r3, [r2, #0x14] @INTENCLEAR -#ifndef CONFIG_ONENAND_IPL /* Set all interrupts as IRQ */ str r5, [r0, #0xc] @INTSELECT str r5, [r1, #0xc] @INTSELECT @@ -78,54 +75,17 @@ lowlevel_init: str r5, [r0, #0xf00] @INTADDRESS str r5, [r1, #0xf00] @INTADDRESS str r5, [r2, #0xf00] @INTADDRESS -#endif -#ifndef CONFIG_ONENAND_IPL /* for UART */ bl uart_asm_init /* for TZPC */ bl tzpc_asm_init -#endif - -#ifdef CONFIG_ONENAND_IPL - /* init system clock */ - bl system_clock_init - - bl mem_ctrl_asm_init - - /* Wakeup support. Don't know if it's going to be used, untested. */ - ldr r0, =S5PC100_RST_STAT - ldr r1, [r0] - bic r1, r1, #0xfffffff7 - cmp r1, #0x8 - beq wakeup_reset -#endif 1: mov lr, r9 mov pc, lr -#ifdef CONFIG_ONENAND_IPL -wakeup_reset: - - /* Clear wakeup status register */ - ldr r0, =S5PC100_WAKEUP_STAT - ldr r1, [r0] - str r1, [r0] - - /* Load return address and jump to kernel */ - ldr r0, =S5PC100_INFORM0 - - /* r1 = physical address of s5pc100_cpu_resume function */ - ldr r1, [r0] - - /* Jump to kernel (sleep.S) */ - mov pc, r1 - nop - nop -#endif - /* * system_clock_init: Initialize core clock and bus clock. * void system_clock_init(void) @@ -178,7 +138,6 @@ system_clock_init: mov pc, lr -#ifndef CONFIG_ONENAND_IPL /* * uart_asm_init: Initialize UART's pins */ @@ -212,4 +171,3 @@ tzpc_asm_init: str r1, [r0, #0x810] mov pc, lr -#endif diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c deleted file mode 100644 index 22baebb..0000000 --- a/onenand_ipl/onenand_boot.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * (C) Copyright 2005-2008 Samsung Electronics - * Kyungmin Park - * - * Derived from x-loader - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#include "onenand_ipl.h" - -typedef int (init_fnc_t)(void); - -void start_oneboot(void) -{ - uchar *buf; - - buf = (uchar *) CONFIG_SYS_LOAD_ADDR; - - onenand_read_block(buf); - - ((init_fnc_t *)CONFIG_SYS_LOAD_ADDR)(); - - /* should never come here */ -} - -void hang(void) -{ - for (;;); -} diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h deleted file mode 100644 index 7ebb3e3..0000000 --- a/onenand_ipl/onenand_ipl.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * (C) Copyright 2005-2008 Samsung Electronics - * Kyungmin Park - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef _ONENAND_IPL_H -#define _ONENAND_IPL_H - -#include - -#define onenand_readw(a) readw(THIS_ONENAND(a)) -#define onenand_writew(v, a) writew(v, THIS_ONENAND(a)) - -#define THIS_ONENAND(a) (CONFIG_SYS_ONENAND_BASE + (a)) - -#define READ_INTERRUPT() onenand_readw(ONENAND_REG_INTERRUPT) - -extern int (*onenand_read_page)(ulong block, ulong page, - u_char *buf, int pagesize); -extern int onenand_read_block(unsigned char *buf); -#endif diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c deleted file mode 100644 index 8d0df81..0000000 --- a/onenand_ipl/onenand_read.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * (C) Copyright 2005-2009 Samsung Electronics - * Kyungmin Park - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#include -#include - -#include "onenand_ipl.h" - -#define onenand_block_address(block) (block) -#define onenand_sector_address(page) (page << 2) -#define onenand_buffer_address() ((1 << 3) << 8) -#define onenand_bufferram_address(block) (0) - -#ifdef __HAVE_ARCH_MEMCPY32 -extern void *memcpy32(void *dest, void *src, int size); -#endif - -int (*onenand_read_page)(ulong block, ulong page, u_char *buf, int pagesize); - -/* read a page with ECC */ -static int generic_onenand_read_page(ulong block, ulong page, - u_char * buf, int pagesize) -{ - unsigned long *base; - -#ifndef __HAVE_ARCH_MEMCPY32 - unsigned int offset, value; - unsigned long *p; -#endif - - onenand_writew(onenand_block_address(block), - ONENAND_REG_START_ADDRESS1); - - onenand_writew(onenand_bufferram_address(block), - ONENAND_REG_START_ADDRESS2); - - onenand_writew(onenand_sector_address(page), - ONENAND_REG_START_ADDRESS8); - - onenand_writew(onenand_buffer_address(), - ONENAND_REG_START_BUFFER); - - onenand_writew(ONENAND_INT_CLEAR, ONENAND_REG_INTERRUPT); - - onenand_writew(ONENAND_CMD_READ, ONENAND_REG_COMMAND); - -#ifndef __HAVE_ARCH_MEMCPY32 - p = (unsigned long *) buf; -#endif - base = (unsigned long *) (CONFIG_SYS_ONENAND_BASE + ONENAND_DATARAM); - - while (!(READ_INTERRUPT() & ONENAND_INT_READ)) - continue; - - /* Check for invalid block mark */ - if (page < 2 && (onenand_readw(ONENAND_SPARERAM) != 0xffff)) - return 1; - -#ifdef __HAVE_ARCH_MEMCPY32 - /* 32 bytes boundary memory copy */ - memcpy32(buf, base, pagesize); -#else - for (offset = 0; offset < (pagesize >> 2); offset++) { - value = *(base + offset); - *p++ = value; - } -#endif - - return 0; -} - -#ifndef CONFIG_ONENAND_START_PAGE -#define CONFIG_ONENAND_START_PAGE 1 -#endif -#define ONENAND_PAGES_PER_BLOCK 64 - -static void onenand_generic_init(int *page_is_4KiB, int *page) -{ - int dev_id, density; - - if (onenand_readw(ONENAND_REG_TECHNOLOGY)) - *page_is_4KiB = 1; - dev_id = onenand_readw(ONENAND_REG_DEVICE_ID); - density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; - density &= ONENAND_DEVICE_DENSITY_MASK; - if (density >= ONENAND_DEVICE_DENSITY_4Gb && - !(dev_id & ONENAND_DEVICE_IS_DDP)) - *page_is_4KiB = 1; -} - -/** - * onenand_read_block - Read CONFIG_SYS_MONITOR_LEN from begining - * of OneNAND, skipping bad blocks - * @return 0 on success - */ -int onenand_read_block(unsigned char *buf) -{ - int block, nblocks; - int page = CONFIG_ONENAND_START_PAGE, offset = 0; - int pagesize, erasesize, erase_shift; - int page_is_4KiB = 0; - - onenand_read_page = generic_onenand_read_page; - - onenand_generic_init(&page_is_4KiB, &page); - - if (page_is_4KiB) { - pagesize = 4096; /* OneNAND has 4KiB pagesize */ - erase_shift = 18; - } else { - pagesize = 2048; /* OneNAND has 2KiB pagesize */ - erase_shift = 17; - } - - erasesize = (1 << erase_shift); - nblocks = (CONFIG_SYS_MONITOR_LEN + erasesize - 1) >> erase_shift; - - /* NOTE: you must read page from page 1 of block 0 */ - /* read the block page by page */ - for (block = 0; block < nblocks; block++) { - for (; page < ONENAND_PAGES_PER_BLOCK; page++) { - if (onenand_read_page(block, page, buf + offset, - pagesize)) { - /* This block is bad. Skip it - * and read next block */ - offset -= page * pagesize; - nblocks++; - break; - } - offset += pagesize; - } - page = 0; - } - - return 0; -} -- cgit v1.1 From 535c74f80cb9eff0fa66ce750fc7fc8a8539635c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 5 Sep 2012 17:16:55 +0000 Subject: ARM: Remove apollon board This board is the only board that still sticks to OneNAND IPL. Remove this board, since we have SPL around for a while and OneNAND is well supported in the SPL framework. The board can be revived if necessary. Signed-off-by: Marek Vasut Cc: Albert Aribaud Cc: Kyungmin Park Cc: Tom Rini --- MAINTAINERS | 4 - arch/arm/include/asm/arch-omap24xx/omap2420.h | 10 - board/apollon/Makefile | 43 --- board/apollon/apollon.c | 470 -------------------------- board/apollon/config.mk | 25 -- board/apollon/lowlevel_init.S | 337 ------------------ board/apollon/mem.c | 237 ------------- board/apollon/mem.h | 170 ---------- board/apollon/sys_info.c | 396 ---------------------- boards.cfg | 1 - doc/README.scrapyard | 1 + include/configs/apollon.h | 261 -------------- onenand_ipl/board/apollon/Makefile | 87 ----- onenand_ipl/board/apollon/apollon.c | 70 ---- onenand_ipl/board/apollon/config.mk | 14 - onenand_ipl/board/apollon/low_levelinit.S | 205 ----------- onenand_ipl/board/apollon/u-boot.onenand.lds | 53 --- 17 files changed, 1 insertion(+), 2383 deletions(-) delete mode 100644 board/apollon/Makefile delete mode 100644 board/apollon/apollon.c delete mode 100644 board/apollon/config.mk delete mode 100644 board/apollon/lowlevel_init.S delete mode 100644 board/apollon/mem.c delete mode 100644 board/apollon/mem.h delete mode 100644 board/apollon/sys_info.c delete mode 100644 include/configs/apollon.h delete mode 100644 onenand_ipl/board/apollon/Makefile delete mode 100644 onenand_ipl/board/apollon/apollon.c delete mode 100644 onenand_ipl/board/apollon/config.mk delete mode 100644 onenand_ipl/board/apollon/low_levelinit.S delete mode 100644 onenand_ipl/board/apollon/u-boot.onenand.lds diff --git a/MAINTAINERS b/MAINTAINERS index cd18732..aa54fe1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -777,10 +777,6 @@ Nagendra T S am3517_crane ARM ARMV7 (AM35x SoC) -Kyungmin Park - - apollon ARM1136EJS - Sandeep Paulraj davinci_dm355evm ARM926EJS diff --git a/arch/arm/include/asm/arch-omap24xx/omap2420.h b/arch/arm/include/asm/arch-omap24xx/omap2420.h index 6032419..d8d5647 100644 --- a/arch/arm/include/asm/arch-omap24xx/omap2420.h +++ b/arch/arm/include/asm/arch-omap24xx/omap2420.h @@ -228,16 +228,6 @@ #define LAN_RESET_REGISTER (H4_CS1_BASE+0x1c) #endif /* endif CONFIG_2420H4 */ -#if defined(CONFIG_APOLLON) -#define APOLLON_CS0_BASE 0x00000000 /* OneNAND */ -#define APOLLON_CS1_BASE 0x08000000 /* ethernet */ -#define APOLLON_CS2_BASE 0x10000000 /* OneNAND */ -#define APOLLON_CS3_BASE 0x18000000 /* NOR */ - -#define ETH_CONTROL_REG (APOLLON_CS1_BASE + 0x30b) -#define LAN_RESET_REGISTER (APOLLON_CS1_BASE + 0x1c) -#endif /* endif CONFIG_APOLLON */ - /* Common */ #define LOW_LEVEL_SRAM_STACK 0x4020FFFC diff --git a/board/apollon/Makefile b/board/apollon/Makefile deleted file mode 100644 index 1bf1a32..0000000 --- a/board/apollon/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# -# (C) Copyright 2000, 2001, 2002 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(BOARD).o - -COBJS-y := apollon.o mem.o sys_info.o -SOBJS := lowlevel_init.o - -COBJS := $(COBJS-y) -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS)) -SOBJS := $(addprefix $(obj),$(SOBJS)) - -$(LIB): $(obj).depend $(OBJS) $(SOBJS) - $(call cmd_link_o_target, $(OBJS) $(SOBJS)) - -######################################################################### - -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend diff --git a/board/apollon/apollon.c b/board/apollon/apollon.c deleted file mode 100644 index 76626f0..0000000 --- a/board/apollon/apollon.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * (C) Copyright 2005-2007 - * Samsung Electronics. - * Kyungmin Park - * - * Derived from omap2420 - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void wait_for_command_complete(unsigned int wd_base); - -DECLARE_GLOBAL_DATA_PTR; - -#define write_config_reg(reg, value) \ -do { \ - writeb(value, reg); \ -} while (0) - -#define mask_config_reg(reg, mask) \ -do { \ - char value = readb(reg) & ~(mask); \ - writeb(value, reg); \ -} while (0) - -/******************************************************* - * Routine: delay - * Description: spinning delay to use before udelay works - ******************************************************/ -static inline void delay(unsigned long loops) -{ - __asm__("1:\n" "subs %0, %1, #1\n" - "bne 1b":"=r" (loops):"0"(loops)); -} - -/***************************************** - * Routine: board_init - * Description: Early hardware init. - *****************************************/ -int board_init(void) -{ - gpmc_init(); /* in SRAM or SDRM, finish GPMC */ - - gd->bd->bi_arch_number = 919; - /* adress of boot parameters */ - gd->bd->bi_boot_params = (OMAP2420_SDRC_CS0 + 0x100); - - return 0; -} - -/********************************************************** - * Routine: s_init - * Description: Does early system init of muxing and clocks. - * - Called path is with sram stack. - **********************************************************/ -void s_init(void) -{ - watchdog_init(); - set_muxconf_regs(); - delay(100); - - peripheral_enable(); - icache_enable(); -} - -/******************************************************* - * Routine: misc_init_r - * Description: Init ethernet (done here so udelay works) - ********************************************************/ -int misc_init_r(void) -{ - return (0); -} - -/**************************************** - * Routine: watchdog_init - * Description: Shut down watch dogs - *****************************************/ -void watchdog_init(void) -{ - /* There are 4 watch dogs. 1 secure, and 3 general purpose. - * The ROM takes care of the secure one. Of the 3 GP ones, - * 1 can reset us directly, the other 2 only generate MPU interrupts. - */ - __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR); - wait_for_command_complete(WD2_BASE); - __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR); - -#define MPU_WD_CLOCKED 1 -#if MPU_WD_CLOCKED - /* value 0x10 stick on aptix, BIT4 polarity seems oppsite */ - __raw_writel(WD_UNLOCK1, WD3_BASE + WSPR); - wait_for_command_complete(WD3_BASE); - __raw_writel(WD_UNLOCK2, WD3_BASE + WSPR); - - __raw_writel(WD_UNLOCK1, WD4_BASE + WSPR); - wait_for_command_complete(WD4_BASE); - __raw_writel(WD_UNLOCK2, WD4_BASE + WSPR); -#endif -} - -/****************************************************** - * Routine: wait_for_command_complete - * Description: Wait for posting to finish on watchdog - ******************************************************/ -void wait_for_command_complete(unsigned int wd_base) -{ - int pending = 1; - do { - pending = __raw_readl(wd_base + WWPS); - } while (pending); -} - -/******************************************************************* - * Routine:board_eth_init - * Description: take the Ethernet controller out of reset and wait - * for the EEPROM load to complete. - ******************************************************************/ -int board_eth_init(bd_t *bis) -{ - int rc = 0; -#ifdef CONFIG_LAN91C96 - int cnt = 20; - - __raw_writeb(0x03, OMAP2420_CTRL_BASE + 0x0f2); /*protect->gpio74 */ - - __raw_writew(0x0, LAN_RESET_REGISTER); - do { - __raw_writew(0x1, LAN_RESET_REGISTER); - udelay(100); - if (cnt == 0) - goto eth_reset_err_out; - --cnt; - } while (__raw_readw(LAN_RESET_REGISTER) != 0x1); - - cnt = 20; - - do { - __raw_writew(0x0, LAN_RESET_REGISTER); - udelay(100); - if (cnt == 0) - goto eth_reset_err_out; - --cnt; - } while (__raw_readw(LAN_RESET_REGISTER) != 0x0000); - udelay(1000); - - mask_config_reg(ETH_CONTROL_REG, 0x01); - udelay(1000); - rc = lan91c96_initialize(0, CONFIG_LAN91C96_BASE); -eth_reset_err_out: -#endif - return rc; -} - -/********************************************** - * Routine: dram_init - * Description: sets uboots idea of sdram size - **********************************************/ -int dram_init(void) -{ - unsigned int size; - u32 mtype, btype; -#define NOT_EARLY 0 - - btype = get_board_type(); - mtype = get_mem_type(); - - display_board_info(btype); - - if ((mtype == DDR_COMBO) || (mtype == DDR_STACKED)) { - /* init other chip select */ - do_sdrc_init(SDRC_CS1_OSET, NOT_EARLY); - } - - size = get_sdr_cs_size(SDRC_CS0_OSET); - - gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = size; -#if CONFIG_NR_DRAM_BANKS > 1 - size = get_sdr_cs_size(SDRC_CS1_OSET); - - gd->bd->bi_dram[1].start = gd->bd->bi_dram[0].start + - gd->bd->bi_dram[0].size; - gd->bd->bi_dram[1].size = size; -#endif - - return 0; -} - -/********************************************************** - * Routine: set_muxconf_regs - * Description: Setting up the configuration Mux registers - * specific to the hardware - *********************************************************/ -void set_muxconf_regs(void) -{ - muxSetupSDRC(); - muxSetupGPMC(); - muxSetupUsb0(); /* USB Device */ - muxSetupUsbHost(); /* USB Host */ - muxSetupUART1(); - muxSetupLCD(); - muxSetupMMCSD(); - muxSetupTouchScreen(); -} - -/***************************************************************** - * Routine: peripheral_enable - * Description: Enable the clks & power for perifs (GPT2, UART1,...) - ******************************************************************/ -void peripheral_enable(void) -{ - unsigned int v, if_clks = 0, func_clks = 0; - - /* Enable GP2 timer. */ - if_clks |= BIT4 | BIT3; - func_clks |= BIT4 | BIT3; - /* Sys_clk input OMAP2420_GPT2 */ - v = __raw_readl(CM_CLKSEL2_CORE) | 0x4 | 0x2; - __raw_writel(v, CM_CLKSEL2_CORE); - __raw_writel(0x1, CM_CLKSEL_WKUP); - -#ifdef CONFIG_SYS_NS16550 - /* Enable UART1 clock */ - func_clks |= BIT21; - if_clks |= BIT21; -#endif - /* Interface clocks on */ - v = __raw_readl(CM_ICLKEN1_CORE) | if_clks; - __raw_writel(v, CM_ICLKEN1_CORE); - /* Functional Clocks on */ - v = __raw_readl(CM_FCLKEN1_CORE) | func_clks; - __raw_writel(v, CM_FCLKEN1_CORE); - delay(1000); - -#ifndef KERNEL_UPDATED - { -#define V1 0xffffffff -#define V2 0x00000007 - - __raw_writel(V1, CM_FCLKEN1_CORE); - __raw_writel(V2, CM_FCLKEN2_CORE); - __raw_writel(V1, CM_ICLKEN1_CORE); - __raw_writel(V1, CM_ICLKEN2_CORE); - } -#endif -} - -/**************************************** - * Routine: muxSetupUsb0 (ostboot) - * Description: Setup usb muxing - *****************************************/ -void muxSetupUsb0(void) -{ - mask_config_reg(CONTROL_PADCONF_USB0_PUEN, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_VP, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_VM, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_RCV, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_TXEN, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_SE0, 0x1f); - mask_config_reg(CONTROL_PADCONF_USB0_DAT, 0x1f); -} - -/**************************************** - * Routine: muxSetupUSBHost (ostboot) - * Description: Setup USB Host muxing - *****************************************/ -void muxSetupUsbHost(void) -{ - /* V19 */ - write_config_reg(CONTROL_PADCONF_USB1_RCV, 1); - /* W20 */ - write_config_reg(CONTROL_PADCONF_USB1_TXEN, 1); - /* N14 */ - write_config_reg(CONTROL_PADCONF_GPIO69, 3); - /* P15 */ - write_config_reg(CONTROL_PADCONF_GPIO70, 3); - /* L18 */ - write_config_reg(CONTROL_PADCONF_GPIO102, 3); - /* L19 */ - write_config_reg(CONTROL_PADCONF_GPIO103, 3); - /* K15 */ - write_config_reg(CONTROL_PADCONF_GPIO104, 3); - /* K14 */ - write_config_reg(CONTROL_PADCONF_GPIO105, 3); -} - -/**************************************** - * Routine: muxSetupUART1 (ostboot) - * Description: Set up uart1 muxing - *****************************************/ -void muxSetupUART1(void) -{ - /* UART1_CTS pin configuration, PIN = D21, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_UART1_CTS, 0); - /* UART1_RTS pin configuration, PIN = H21, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_UART1_RTS, 0); - /* UART1_TX pin configuration, PIN = L20, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_UART1_TX, 0); - /* UART1_RX pin configuration, PIN = T21, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_UART1_RX, 0); -} - -/**************************************** - * Routine: muxSetupLCD (ostboot) - * Description: Setup lcd muxing - *****************************************/ -void muxSetupLCD(void) -{ - /* LCD_D0 pin configuration, PIN = Y7, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D0, 0); - /* LCD_D1 pin configuration, PIN = P10 , Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D1, 0); - /* LCD_D2 pin configuration, PIN = V8, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D2, 0); - /* LCD_D3 pin configuration, PIN = Y8, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D3, 0); - /* LCD_D4 pin configuration, PIN = W8, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D4, 0); - /* LCD_D5 pin configuration, PIN = R10, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D5, 0); - /* LCD_D6 pin configuration, PIN = Y9, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D6, 0); - /* LCD_D7 pin configuration, PIN = V9, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D7, 0); - /* LCD_D8 pin configuration, PIN = W9, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D8, 0); - /* LCD_D9 pin configuration, PIN = P11, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D9, 0); - /* LCD_D10 pin configuration, PIN = V10, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D10, 0); - /* LCD_D11 pin configuration, PIN = Y10, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D11, 0); - /* LCD_D12 pin configuration, PIN = W10, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D12, 0); - /* LCD_D13 pin configuration, PIN = R11, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D13, 0); - /* LCD_D14 pin configuration, PIN = V11, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D14, 0); - /* LCD_D15 pin configuration, PIN = W11, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D15, 0); - /* LCD_D16 pin configuration, PIN = P12, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D16, 0); - /* LCD_D17 pin configuration, PIN = R12, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_D17, 0); - /* LCD_PCLK pin configuration, PIN = W6, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_PCLK, 0); - /* LCD_VSYNC pin configuration, PIN = V7, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_VSYNC, 0); - /* LCD_HSYNC pin configuration, PIN = Y6, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_HSYNC, 0); - /* LCD_ACBIAS pin configuration, PIN = W7, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_DSS_ACBIAS, 0); -} - -/**************************************** - * Routine: muxSetupMMCSD (ostboot) - * Description: set up MMC muxing - *****************************************/ -void muxSetupMMCSD(void) -{ - /* SDMMC_CLKI pin configuration, PIN = H15, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_CLKI, 0); - /* SDMMC_CLKO pin configuration, PIN = G19, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_CLKO, 0); - /* SDMMC_CMD pin configuration, PIN = H18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_CMD, 0); - /* SDMMC_DAT0 pin configuration, PIN = F20, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT0, 0); - /* SDMMC_DAT1 pin configuration, PIN = H14, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT1, 0); - /* SDMMC_DAT2 pin configuration, PIN = E19, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT2, 0); - /* SDMMC_DAT3 pin configuration, PIN = D19, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT3, 0); - /* SDMMC_DDIR0 pin configuration, PIN = F19, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT_DIR0, 0); - /* SDMMC_DDIR1 pin configuration, PIN = E20, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT_DIR1, 0); - /* SDMMC_DDIR2 pin configuration, PIN = F18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT_DIR2, 0); - /* SDMMC_DDIR3 pin configuration, PIN = E18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_DAT_DIR3, 0); - /* SDMMC_CDIR pin configuration, PIN = G18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_MMC_CMD_DIR, 0); -} - -/****************************************** - * Routine: muxSetupTouchScreen (ostboot) - * Description: Set up touch screen muxing - *******************************************/ -void muxSetupTouchScreen(void) -{ - /* SPI1_CLK pin configuration, PIN = U18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_SPI1_CLK, 0); - /* SPI1_MOSI pin configuration, PIN = V20, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_SPI1_SIMO, 0); - /* SPI1_MISO pin configuration, PIN = T18, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_SPI1_SOMI, 0); - /* SPI1_nCS0 pin configuration, PIN = U19, Mode = 0, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_SPI1_NCS0, 0); -#define CONTROL_PADCONF_GPIO85 CONTROL_PADCONF_SPI1_NCS1 - /* PEN_IRQ pin configuration, PIN = N15, Mode = 3, PUPD=Disabled */ - write_config_reg(CONTROL_PADCONF_GPIO85, 3); -} - -/*************************************************************** - * Routine: muxSetupGPMC (ostboot) - * Description: Configures balls which cam up in protected mode - ***************************************************************/ -void muxSetupGPMC(void) -{ - /* gpmc_io_dir, MCR */ - volatile unsigned int *MCR = (unsigned int *) 0x4800008C; - *MCR = 0x19000000; - - /* NOR FLASH CS0 */ - /* signal - Gpmc_clk; pin - J4; offset - 0x0088; mode 0; Byte-3 */ - write_config_reg(CONTROL_PADCONF_GPMC_D2_BYTE3, 0); - /* MPDB(Multi Port Debug Port) CS1 */ - /* signal - gpmc_ncs1; pin - N8; offset - 0x008D; mode 0; Byte-1 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE1, 0); - /* signal - Gpmc_ncs2; pin - E2; offset - 0x008E; mode 0; Byte-2 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE2, 0); - /* signal - Gpmc_ncs3; pin - N2; offset - 0x008F; mode 0; Byte-3 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE3, 0); - /* signal - Gpmc_ncs4; pin - ??; offset - 0x0090; mode 0; Byte-4 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE4, 0); - /* signal - Gpmc_ncs5; pin - ??; offset - 0x0091; mode 0; Byte-5 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE5, 0); - /* signal - Gpmc_ncs6; pin - ??; offset - 0x0092; mode 0; Byte-6 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE6, 0); - /* signal - Gpmc_ncs7; pin - ??; offset - 0x0093; mode 0; Byte-7 */ - write_config_reg(CONTROL_PADCONF_GPMC_NCS0_BYTE7, 0); -} - -/**************************************************************** - * Routine: muxSetupSDRC (ostboot) - * Description: Configures balls which come up in protected mode - ****************************************************************/ -void muxSetupSDRC(void) -{ - /* It's set by IPL */ -} diff --git a/board/apollon/config.mk b/board/apollon/config.mk deleted file mode 100644 index 66005d4..0000000 --- a/board/apollon/config.mk +++ /dev/null @@ -1,25 +0,0 @@ -# -# (C) Copyright 2005-2007 -# Samsung Electronics -# -# Samsung December board with OMAP2420 (ARM1136) cpu -# see http://www.ti.com/ for more information on Texas Instruments -# -# December has 1 bank of 128MB mDDR-SDRAM on CS0 -# December has 1 bank of 00MB mDDR-SDRAM on CS1 -# Physical Address: -# 8000'0000 (bank0) -# A000/0000 (bank1) ES2 will be configurable -# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 -# (mem base + reserved) -# For use with external or internal boots. -CONFIG_SYS_TEXT_BASE = 0x83e80000 - -# Used with full SRAM boot. -# This is either with a GP system or a signed boot image. -# easiest, and safest way to go if you can. -#CONFIG_SYS_TEXT_BASE = 0x40270000 - -# Handy to get symbols to debug ROM version. -#CONFIG_SYS_TEXT_BASE = 0x0 -#CONFIG_SYS_TEXT_BASE = 0x08000000 diff --git a/board/apollon/lowlevel_init.S b/board/apollon/lowlevel_init.S deleted file mode 100644 index f066fe4..0000000 --- a/board/apollon/lowlevel_init.S +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Board specific setup info - * - * (C) Copyright 2005-2007 - * Samsung Electronics, - * Kyungmin Park - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include "mem.h" - -#define APOLLON_CS0_BASE 0x00000000 - -#ifdef PRCM_CONFIG_I -#define SDRC_ACTIM_CTRLA_0_VAL 0x7BA35907 -#define SDRC_ACTIM_CTRLB_0_VAL 0x00000013 -#define SDRC_RFR_CTRL_0_VAL 0x00044C01 -#elif defined(PRCM_CONFIG_II) -#define SDRC_ACTIM_CTRLA_0_VAL 0x4A59B485 -#define SDRC_ACTIM_CTRLB_0_VAL 0x0000000C -#define SDRC_RFR_CTRL_0_VAL 0x00030001 -#endif - -#define SDRAM_BASE_ADDRESS 0x80008000 - -_TEXT_BASE: - .word CONFIG_SYS_TEXT_BASE /* sdram load addr from config.mk */ - -.globl lowlevel_init -lowlevel_init: - -#ifdef CONFIG_SYS_NOR_BOOT - /* Check running in SDRAM */ - mov r0, pc, lsr #28 - cmp r0, #8 - beq prcm_setup - -flash_setup: - /* In Flash */ - ldr r0, =WD2_BASE - ldr r1, =WD_UNLOCK1 - str r1, [r0, #WSPR] - - ldr r1, =WD_UNLOCK2 - str r1, [r0, #WSPR] - - /* Pin muxing for SDRC */ - mov r1, #0x00 - ldr r0, =0x480000A1 /* ball C12, mode 0 */ - strb r1, [r0] - - ldr r0, =0x48000032 /* ball D11, mode 0 */ - strb r1, [r0] - - ldr r0, =0x480000A3 /* ball B13, mode 0 */ - strb r1, [r0] - - /* SDRC setting */ - ldr r0, =OMAP2420_SDRC_BASE - ldr r1, =0x00000010 - str r1, [r0, #0x10] - - ldr r1, =0x00000100 - str r1, [r0, #0x44] - - /* SDRC CS0 configuration */ - ldr r1, =0x00d04011 - str r1, [r0, #0x80] - - ldr r1, =SDRC_ACTIM_CTRLA_0_VAL - str r1, [r0, #0x9C] - - ldr r1, =SDRC_ACTIM_CTRLB_0_VAL - str r1, [r0, #0xA0] - - ldr r1, =SDRC_RFR_CTRL_0_VAL - str r1, [r0, #0xA4] - - ldr r1, =0x00000041 - str r1, [r0, #0x70] - - /* Manual command sequence */ - ldr r1, =0x00000007 - str r1, [r0, #0xA8] - - ldr r1, =0x00000000 - str r1, [r0, #0xA8] - - ldr r1, =0x00000001 - str r1, [r0, #0xA8] - - ldr r1, =0x00000002 - str r1, [r0, #0xA8] - str r1, [r0, #0xA8] - - /* - * CS0 SDRC Mode register - * Burst length = 4 - DDR memory - * Serial mode - * CAS latency = 3 - */ - ldr r1, =0x00000032 - str r1, [r0, #0x84] - - /* Note: You MUST set EMR values */ - /* EMR1 & EMR2 */ - ldr r1, =0x00000000 - str r1, [r0, #0x88] - str r1, [r0, #0x8C] - -#ifdef OLD_SDRC_DLLA_CTRL - /* SDRC_DLLA_CTRL */ - ldr r1, =0x00007306 - str r1, [r0, #0x60] - - ldr r1, =0x00007303 - str r1, [r0, #0x60] -#else - /* SDRC_DLLA_CTRL */ - ldr r1, =0x00000506 - str r1, [r0, #0x60] - - ldr r1, =0x00000503 - str r1, [r0, #0x60] -#endif - -#ifdef __BROKEN_FEATURE__ - /* SDRC_DLLB_CTRL */ - ldr r1, =0x00000506 - str r1, [r0, #0x68] - - ldr r1, =0x00000503 - str r1, [r0, #0x68] -#endif - - /* little delay after init */ - mov r2, #0x1800 -1: - subs r2, r2, #0x1 - bne 1b - - /* Setup base address */ - ldr r0, =0x00000000 /* NOR address */ - ldr r1, =SDRAM_BASE_ADDRESS /* SDRAM address */ - ldr r2, =0x20000 /* Size: 128KB */ - -copy_loop: - ldmia r0!, {r3-r10} - stmia r1!, {r3-r10} - cmp r0, r2 - ble copy_loop - - ldr r1, =SDRAM_BASE_ADDRESS - mov lr, pc - mov pc, r1 -#endif - -prcm_setup: - ldr r0, =OMAP2420_CM_BASE - ldr r1, [r0, #0x544] /* CLKSEL2_PLL */ - bic r1, r1, #0x03 - orr r1, r1, #0x02 - str r1, [r0, #0x544] - - ldr r1, [r0, #0x500] - bic r1, r1, #0x03 - orr r1, r1, #0x01 - str r1, [r0, #0x500] - - ldr r1, [r0, #0x140] - bic r1, r1, #0x1f - orr r1, r1, #0x02 - str r1, [r0, #0x140] - -#ifdef PRCM_CONFIG_I - ldr r1, =0x000003C3 -#else - ldr r1, =0x00000343 -#endif - str r1, [r0, #0x840] - - ldr r1, =0x00000002 - str r1, [r0, #0x340] - - ldr r1, =CM_CLKSEL1_CORE -#ifdef PRCM_CONFIG_I - ldr r2, =0x08300C44 -#else - ldr r2, =0x04600C26 -#endif - str r2, [r1] - - ldr r0, =OMAP2420_CM_BASE - ldr r1, [r0, #0x084] - and r1, r1, #0x01 - cmp r1, #0x01 - bne clkvalid - - b . - -clkvalid: - mov r1, #0x01 - str r1, [r0, #0x080] - -waitvalid: - ldr r1, [r0, #0x084] - and r1, r1, #0x01 - cmp r1, #0x00 - bne waitvalid - - ldr r0, =CM_CLKSEL1_PLL -#ifdef PRCM_CONFIG_I - ldr r1, =0x01837100 -#else - ldr r1, =0x01832100 -#endif - str r1, [r0] - - ldr r0, =PRCM_CLKCFG_CTRL - mov r1, #0x01 - str r1, [r0] - mov r6, #0x50 -loop1: - subs r6, r6, #0x01 - cmp r6, #0x01 - bne loop1 - - ldr r0, =CM_CLKEN_PLL - mov r1, #0x0f - str r1, [r0] - - mov r6, #0x100 -loop2: - subs r6, r6, #0x01 - cmp r6, #0x01 - bne loop2 - - ldr r0, =0x48008200 - ldr r1, =0xbfffffff - str r1, [r0] - - ldr r0, =0x48008210 - ldr r1, =0xfffffff9 - str r1, [r0] - - ldr r0, =0x4806a004 - ldr r1, =0x00 - strb r1, [r0] - - ldr r0, =0x4806a020 - ldr r1, =0x07 - strb r1, [r0] - - ldr r0, =0x4806a00c - ldr r1, =0x83 - strb r1, [r0] - - ldr r0, =0x4806a000 - ldr r1, =0x1a - strb r1, [r0] - - ldr r0, =0x4806a004 - ldr r1, =0x00 - strb r1, [r0] - - ldr r0, =0x4806a00c - ldr r1, =0x03 - strb r1, [r0] - - ldr r0, =0x4806a010 - ldr r1, =0x03 - strb r1, [r0] - - ldr r0, =0x4806a008 - ldr r1, =0x04 - strb r1, [r0] - - ldr r0, =0x4806a020 - ldr r1, =0x00 - strb r1, [r0] - -#if 0 - ldr r0, =0x4806a000 - mov r1, #'u' - strb r1, [r0] -#endif - -#if 0 - /* LED0 OFF */ - ldr r3, =0x480000E5 - mov r4, #0x0b - strb r4, [r3] -#endif - - ldr sp, SRAM_STACK - str ip, [sp] /* stash old link register */ - mov ip, lr /* save link reg across call */ - bl s_init /* go setup pll,mux,memory */ - ldr ip, [sp] /* restore save ip */ - mov lr, ip /* restore link reg */ - - /* map interrupt controller */ - ldr r0, VAL_INTH_SETUP - mcr p15, 0, r0, c15, c2, 4 - - /* back to arch calling code */ - mov pc, lr - - /* the literal pools origin */ - .ltorg - -VAL_INTH_SETUP: - .word PERIFERAL_PORT_BASE -SRAM_STACK: - .word LOW_LEVEL_SRAM_STACK diff --git a/board/apollon/mem.c b/board/apollon/mem.c deleted file mode 100644 index 36bf6e9..0000000 --- a/board/apollon/mem.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * (C) Copyright 2005-2007 - * Samsung Electronics, - * Kyungmin Park - * - * Derived from omap2420 - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mem.h" - -/************************************************************ - * sdelay() - simple spin loop. Will be constant time as - * its generally used in 12MHz bypass conditions only. This - * is necessary until timers are accessible. - * - * not inline to increase chances its in cache when called - *************************************************************/ -void sdelay(unsigned long loops) -{ - __asm__("1:\n" "subs %0, %1, #1\n" - "bne 1b":"=r" (loops):"0"(loops)); -} - -/******************************************************************** - * prcm_init() - inits clocks for PRCM as defined in clocks.h - * (config II default). - * -- called from SRAM, or Flash (using temp SRAM stack). - ********************************************************************/ -void prcm_init(void) { } - -/************************************************************************** - * make_cs1_contiguous() - for es2 and above remap cs1 behind cs0 to allow - * command line mem=xyz use all memory with out discontigious support - * compiled in. Could do it at the ATAG, but there really is two banks... - * Called as part of 2nd phase DDR init. - **************************************************************************/ -void make_cs1_contiguous(void) -{ - u32 size, a_add_low, a_add_high; - - size = get_sdr_cs_size(SDRC_CS0_OSET); - size /= SZ_32M; /* find size to offset CS1 */ - a_add_high = (size & 3) << 8; /* set up low field */ - a_add_low = (size & 0x3C) >> 2; /* set up high field */ - __raw_writel((a_add_high | a_add_low), SDRC_CS_CFG); - -} - -/******************************************************** - * mem_ok() - test used to see if timings are correct - * for a part. Helps in gussing which part - * we are currently using. - *******************************************************/ -u32 mem_ok(void) -{ - u32 val1, val2; - u32 pattern = 0x12345678; - - /* clear pos A */ - __raw_writel(0x0, OMAP2420_SDRC_CS0 + 0x400); - /* pattern to pos B */ - __raw_writel(pattern, OMAP2420_SDRC_CS0); - /* remove pattern off the bus */ - __raw_writel(0x0, OMAP2420_SDRC_CS0 + 4); - /* get pos A value */ - val1 = __raw_readl(OMAP2420_SDRC_CS0 + 0x400); - val2 = __raw_readl(OMAP2420_SDRC_CS0); /* get val2 */ - - /* see if pos A value changed */ - if ((val1 != 0) || (val2 != pattern)) - return (0); - else - return (1); -} - -/******************************************************** - * sdrc_init() - init the sdrc chip selects CS0 and CS1 - * - early init routines, called from flash or - * SRAM. - *******************************************************/ -void sdrc_init(void) -{ -#define EARLY_INIT 1 - /* only init up first bank here */ - do_sdrc_init(SDRC_CS0_OSET, EARLY_INIT); -} - -/************************************************************************* - * do_sdrc_init(): initialize the SDRAM for use. - * -called from low level code with stack only. - * -code sets up SDRAM timing and muxing for 2422 or 2420. - * -optimal settings can be placed here, or redone after i2c - * inspection of board info - * - * This is a bit ugly, but should handle all memory moduels - * used with the APOLLON. The first time though this code from s_init() - * we configure the first chip select. Later on we come back and - * will configure the 2nd chip select if it exists. - * - **************************************************************************/ -void do_sdrc_init(u32 offset, u32 early) -{ -} - -/***************************************************** - * gpmc_init(): init gpmc bus - * Init GPMC for x16, MuxMode (SDRAM in x32). - * This code can only be executed from SRAM or SDRAM. - *****************************************************/ -void gpmc_init(void) -{ - u32 mux = 0, mtype, mwidth, rev, tval; - - rev = get_cpu_rev(); - if (rev == CPU_2420_2422_ES1) - tval = 1; - else - tval = 0; /* disable bit switched meaning */ - - /* global settings */ - __raw_writel(0x10, GPMC_SYSCONFIG); /* smart idle */ - __raw_writel(0x0, GPMC_IRQENABLE); /* isr's sources masked */ - __raw_writel(tval, GPMC_TIMEOUT_CONTROL); /* timeout disable */ -#ifdef CONFIG_SYS_NAND_BOOT - /* set nWP, disable limited addr */ - __raw_writel(0x001, GPMC_CONFIG); -#else - /* set nWP, disable limited addr */ - __raw_writel(0x111, GPMC_CONFIG); -#endif - - /* discover bus connection from sysboot */ - if (is_gpmc_muxed() == GPMC_MUXED) - mux = BIT9; - mtype = get_gpmc0_type(); - mwidth = get_gpmc0_width(); - - /* setup cs0 */ - __raw_writel(0x0, GPMC_CONFIG7_0); /* disable current map */ - sdelay(1000); - -#ifdef CONFIG_SYS_NOR_BOOT - __raw_writel(APOLLON_24XX_GPMC_CONFIG1_3, GPMC_CONFIG1_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG2_3, GPMC_CONFIG2_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG3_3, GPMC_CONFIG3_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG4_3, GPMC_CONFIG4_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG5_3, GPMC_CONFIG5_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG6_3, GPMC_CONFIG6_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_3, GPMC_CONFIG7_0); -#else - __raw_writel(APOLLON_24XX_GPMC_CONFIG1_0 | mux | mtype | mwidth, - GPMC_CONFIG1_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG6_0, GPMC_CONFIG6_0); - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_0, GPMC_CONFIG7_0); -#endif - sdelay(2000); - - /* setup cs1 */ - __raw_writel(0, GPMC_CONFIG7_1); /* disable any mapping */ - sdelay(1000); - - __raw_writel(APOLLON_24XX_GPMC_CONFIG1_1, GPMC_CONFIG1_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG2_1, GPMC_CONFIG2_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG3_1, GPMC_CONFIG3_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG4_1, GPMC_CONFIG4_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG5_1, GPMC_CONFIG5_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG6_1, GPMC_CONFIG6_1); - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_1, GPMC_CONFIG7_1); - sdelay(2000); - - /* setup cs2 */ - __raw_writel(0x0, GPMC_CONFIG7_2); /* disable current map */ - sdelay(1000); - __raw_writel(APOLLON_24XX_GPMC_CONFIG1_0 | mux | mtype | mwidth, - GPMC_CONFIG1_2); - /* It's same as cs 0 */ - __raw_writel(APOLLON_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_2); - __raw_writel(APOLLON_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_2); - __raw_writel(APOLLON_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_2); - __raw_writel(APOLLON_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_2); - __raw_writel(APOLLON_24XX_GPMC_CONFIG6_0, GPMC_CONFIG6_2); -#ifdef CONFIG_SYS_NOR_BOOT - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_0, GPMC_CONFIG7_2); -#else - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_2, GPMC_CONFIG7_2); -#endif - -#ifndef CONFIG_SYS_NOR_BOOT - /* setup cs3 */ - __raw_writel(0, GPMC_CONFIG7_3); /* disable any mapping */ - sdelay(1000); - - __raw_writel(APOLLON_24XX_GPMC_CONFIG1_3, GPMC_CONFIG1_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG2_3, GPMC_CONFIG2_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG3_3, GPMC_CONFIG3_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG4_3, GPMC_CONFIG4_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG5_3, GPMC_CONFIG5_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG6_3, GPMC_CONFIG6_3); - __raw_writel(APOLLON_24XX_GPMC_CONFIG7_3, GPMC_CONFIG7_3); -#endif - -#ifndef ASYNC_NOR - __raw_writew(0xaa, (APOLLON_CS3_BASE + 0xaaa)); - __raw_writew(0x55, (APOLLON_CS3_BASE + 0x554)); - __raw_writew(0xc0, (APOLLON_CS3_BASE | SYNC_NOR_VALUE)); -#endif - sdelay(2000); -} diff --git a/board/apollon/mem.h b/board/apollon/mem.h deleted file mode 100644 index 09c4ea4..0000000 --- a/board/apollon/mem.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * (C) Copyright 2005-2007 - * Samsung Electronics, - * Kyungmin Park - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef _APOLLON_OMAP24XX_MEM_H_ -#define _APOLLON_OMAP24XX_MEM_H_ - -/* Slower full frequency range default timings for x32 operation*/ -#define APOLLON_2420_SDRC_SHARING 0x00000100 -#define APOLLON_2420_SDRC_MDCFG_0_DDR 0x00d04011 -#define APOLLON_2420_SDRC_MR_0_DDR 0x00000032 - -/* optimized timings good for current shipping parts */ -#define APOLLON_242X_SDRC_ACTIM_CTRLA_0_100MHz 0x4A59B485 -#define APOLLON_242X_SDRC_ACTIM_CTRLB_0_100MHz 0x0000000C - -#define APOLLON_242X_SDRC_ACTIM_CTRLA_0_166MHz 0x7BA35907 -#define APOLLON_242X_SDRC_ACTIM_CTRLB_0_166MHz 0x00000013 - -#define APOLLON_242X_SDRC_RFR_CTRL_100MHz 0x00030001 -#define APOLLON_242X_SDRC_RFR_CTRL_166MHz 0x00044C01 - -#define APOLLON_242x_SDRC_DLLAB_CTRL_100MHz 0x00007306 -#define APOLLON_242x_SDRC_DLLAB_CTRL_166MHz 0x00000506 - -#ifdef PRCM_CONFIG_I -#define APOLLON_2420_SDRC_ACTIM_CTRLA_0 APOLLON_242X_SDRC_ACTIM_CTRLA_0_166MHz -#define APOLLON_2420_SDRC_ACTIM_CTRLB_0 APOLLON_242X_SDRC_ACTIM_CTRLB_0_166MHz -#define APOLLON_2420_SDRC_RFR_CTRL APOLLON_242X_SDRC_RFR_CTRL_166MHz -#define APOLLON_2420_SDRC_DLLAB_CTRL APOLLON_242x_SDRC_DLLAB_CTRL_166MHz -#elif PRCM_CONFIG_II -#define APOLLON_2420_SDRC_ACTIM_CTRLA_0 APOLLON_242X_SDRC_ACTIM_CTRLA_0_100MHz -#define APOLLON_2420_SDRC_ACTIM_CTRLB_0 APOLLON_242X_SDRC_ACTIM_CTRLB_0_100MHz -#define APOLLON_2420_SDRC_RFR_CTRL APOLLON_242X_SDRC_RFR_CTRL_100MHz -#define APOLLON_2420_SDRC_DLLAB_CTRL APOLLON_242x_SDRC_DLLAB_CTRL_100MHz -#endif - -/* GPMC settings */ -#ifdef PRCM_CONFIG_I /* L3 at 165MHz */ -/* CS0: OneNAND */ -# define APOLLON_24XX_GPMC_CONFIG1_0 0x00000001 -# define APOLLON_24XX_GPMC_CONFIG2_0 0x000c1000 -# define APOLLON_24XX_GPMC_CONFIG3_0 0x00030400 -# define APOLLON_24XX_GPMC_CONFIG4_0 0x0b841006 -# define APOLLON_24XX_GPMC_CONFIG5_0 0x020f0c11 -# define APOLLON_24XX_GPMC_CONFIG6_0 0x00000000 -# define APOLLON_24XX_GPMC_CONFIG7_0 (0x00000e40|(APOLLON_CS0_BASE >> 24)) - -/* CS1: Ethernet */ -# define APOLLON_24XX_GPMC_CONFIG1_1 0x00011203 -# define APOLLON_24XX_GPMC_CONFIG2_1 0x001F1F01 -# define APOLLON_24XX_GPMC_CONFIG3_1 0x00080803 -# define APOLLON_24XX_GPMC_CONFIG4_1 0x1C0b1C0a -# define APOLLON_24XX_GPMC_CONFIG5_1 0x041F1F1F -# define APOLLON_24XX_GPMC_CONFIG6_1 0x000004C4 -# define APOLLON_24XX_GPMC_CONFIG7_1 (0x00000F40|(APOLLON_CS1_BASE >> 24)) - -/* CS2: OneNAND */ -/* It's same as CS0 */ -# define APOLLON_24XX_GPMC_CONFIG7_2 (0x00000e40|(APOLLON_CS2_BASE >> 24)) - -/* CS3: NOR */ -#ifdef ASYNC_NOR -# define APOLLON_24XX_GPMC_CONFIG1_3 0x00021201 -# define APOLLON_24XX_GPMC_CONFIG2_3 0x00121601 -# define APOLLON_24XX_GPMC_CONFIG3_3 0x00040401 -# define APOLLON_24XX_GPMC_CONFIG4_3 0x12061605 -# define APOLLON_24XX_GPMC_CONFIG5_3 0x01151317 -#else -# define SYNC_NOR_VALUE 0x24aaa -# define APOLLON_24XX_GPMC_CONFIG1_3 0xe5011211 -# define APOLLON_24XX_GPMC_CONFIG2_3 0x00090b01 -# define APOLLON_24XX_GPMC_CONFIG3_3 0x00020201 -# define APOLLON_24XX_GPMC_CONFIG4_3 0x09030b03 -# define APOLLON_24XX_GPMC_CONFIG5_3 0x010a0a0c -#endif /* ASYNC_NOR */ -# define APOLLON_24XX_GPMC_CONFIG6_3 0x00000000 -# define APOLLON_24XX_GPMC_CONFIG7_3 (0x00000e40|(APOLLON_CS3_BASE >> 24)) -#endif /* endif PRCM_CONFIG_I */ - -#ifdef PRCM_CONFIG_II /* L3 at 100MHz */ -/* CS0: OneNAND */ -# define APOLLON_24XX_GPMC_CONFIG1_0 0x00000001 -# define APOLLON_24XX_GPMC_CONFIG2_0 0x00081080 -# define APOLLON_24XX_GPMC_CONFIG3_0 0x00030300 -# define APOLLON_24XX_GPMC_CONFIG4_0 0x08041004 -# define APOLLON_24XX_GPMC_CONFIG5_0 0x020b0910 -# define APOLLON_24XX_GPMC_CONFIG6_0 0x00000000 -# define APOLLON_24XX_GPMC_CONFIG7_0 (0x00000C40|(APOLLON_CS0_BASE >> 24)) - -/* CS1: ethernet */ -# define APOLLON_24XX_GPMC_CONFIG1_1 0x00401203 -# define APOLLON_24XX_GPMC_CONFIG2_1 0x001F1F01 -# define APOLLON_24XX_GPMC_CONFIG3_1 0x00080803 -# define APOLLON_24XX_GPMC_CONFIG4_1 0x1C091C09 -# define APOLLON_24XX_GPMC_CONFIG5_1 0x041F1F1F -# define APOLLON_24XX_GPMC_CONFIG6_1 0x000004C4 -# define APOLLON_24XX_GPMC_CONFIG7_1 (0x00000F40|(APOLLON_CS1_BASE >> 24)) - -/* CS2: OneNAND */ -/* It's same as CS0 */ -# define APOLLON_24XX_GPMC_CONFIG7_2 (0x00000e40|(APOLLON_CS2_BASE >> 24)) - -/* CS3: NOR */ -#define ASYNC_NOR -#ifdef ASYNC_NOR -# define APOLLON_24XX_GPMC_CONFIG1_3 0x00021201 -# define APOLLON_24XX_GPMC_CONFIG2_3 0x00121601 -# define APOLLON_24XX_GPMC_CONFIG3_3 0x00040401 -# define APOLLON_24XX_GPMC_CONFIG4_3 0x12061605 -# define APOLLON_24XX_GPMC_CONFIG5_3 0x01151317 -#else -# define SYNC_NOR_VALUE 0x24aaa -# define APOLLON_24XX_GPMC_CONFIG1_3 0xe1001202 -# define APOLLON_24XX_GPMC_CONFIG2_3 0x00151501 -# define APOLLON_24XX_GPMC_CONFIG3_3 0x00050501 -# define APOLLON_24XX_GPMC_CONFIG4_3 0x0e070e07 -# define APOLLON_24XX_GPMC_CONFIG5_3 0x01131F1F -#endif /* ASYNC_NOR */ -# define APOLLON_24XX_GPMC_CONFIG6_3 0x00000000 -# define APOLLON_24XX_GPMC_CONFIG7_3 (0x00000C40|(APOLLON_CS3_BASE >> 24)) -#endif /* endif PRCM_CONFIG_II */ - -#ifdef PRCM_CONFIG_III /* L3 at 133MHz */ -# ifdef CONFIG_SYS_NAND_BOOT -# define APOLLON_24XX_GPMC_CONFIG1_0 0x0 -# define APOLLON_24XX_GPMC_CONFIG2_0 0x00141400 -# define APOLLON_24XX_GPMC_CONFIG3_0 0x00141400 -# define APOLLON_24XX_GPMC_CONFIG4_0 0x0F010F01 -# define APOLLON_24XX_GPMC_CONFIG5_0 0x010C1414 -# define APOLLON_24XX_GPMC_CONFIG6_0 0x00000A80 -# else /* NOR boot */ -# define APOLLON_24XX_GPMC_CONFIG1_0 0x3 -# define APOLLON_24XX_GPMC_CONFIG2_0 0x00151501 -# define APOLLON_24XX_GPMC_CONFIG3_0 0x00060602 -# define APOLLON_24XX_GPMC_CONFIG4_0 0x10081008 -# define APOLLON_24XX_GPMC_CONFIG5_0 0x01131F1F -# define APOLLON_24XX_GPMC_CONFIG6_0 0x000004c4 -# endif /* endif CONFIG_SYS_NAND_BOOT */ -# define APOLLON_24XX_GPMC_CONFIG7_0 (0x00000C40|(APOLLON_CS0_BASE >> 24)) -# define APOLLON_24XX_GPMC_CONFIG1_1 0x00011000 -# define APOLLON_24XX_GPMC_CONFIG2_1 0x001f1f01 -# define APOLLON_24XX_GPMC_CONFIG3_1 0x00080803 -# define APOLLON_24XX_GPMC_CONFIG4_1 0x1C091C09 -# define APOLLON_24XX_GPMC_CONFIG5_1 0x041f1F1F -# define APOLLON_24XX_GPMC_CONFIG6_1 0x000004C4 -# define APOLLON_24XX_GPMC_CONFIG7_1 (0x00000F40|(APOLLON_CS1_BASE >> 24)) -#endif /* endif CONFIG_SYS_PRCM_III */ - -#endif /* endif _APOLLON_OMAP24XX_MEM_H_ */ diff --git a/board/apollon/sys_info.c b/board/apollon/sys_info.c deleted file mode 100644 index 4f950ae..0000000 --- a/board/apollon/sys_info.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * (C) Copyright 2005-2007 - * Samsung Electronics, - * Kyungmin Park - * - * Derived from omap2420 - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include /* get mem tables */ -#include -#include -#include - -/************************************************************************** - * get_prod_id() - get id info from chips - ***************************************************************************/ -static u32 get_prod_id(void) -{ - u32 p; - p = __raw_readl(PRODUCTION_ID); /* get production ID */ - return ((p & CPU_242X_PID_MASK) >> 16); -} - -/************************************************************************** - * get_cpu_type() - low level get cpu type - * - no C globals yet. - * - just looking to say if this is a 2422 or 2420 or ... - * - to start with we will look at switch settings.. - * - 2422 id's same as 2420 for ES1 will rely on H4 board characteristics - * (mux for 2420, non-mux for 2422). - ***************************************************************************/ -u32 get_cpu_type(void) -{ - u32 v; - - switch (get_prod_id()) { - case 1:; /* 2420 */ - case 2: - return (CPU_2420); - break; /* 2420 pop */ - case 4: - return (CPU_2422); - break; - case 8: - return (CPU_2423); - break; - default: - break; /* early 2420/2422's unmarked */ - } - - v = __raw_readl(TAP_IDCODE_REG); - v &= CPU_24XX_ID_MASK; - /* currently 2420 and 2422 have same id */ - if (v == CPU_2420_CHIPID) { - if (is_gpmc_muxed() == GPMC_MUXED) /* if mux'ed */ - return (CPU_2420); - else - return (CPU_2422); - } else - return (CPU_2420); /* don't know, say 2420 */ -} - -/****************************************** - * get_cpu_rev(void) - extract version info - ******************************************/ -u32 get_cpu_rev(void) -{ - u32 v; - v = __raw_readl(TAP_IDCODE_REG); - v = v >> 28; - return (v + 1); /* currently 2422 and 2420 match up */ -} - -/**************************************************** - * is_mem_sdr() - return 1 if mem type in use is SDR - ****************************************************/ -u32 is_mem_sdr(void) -{ - volatile u32 *burst = (volatile u32 *)(SDRC_MR_0 + SDRC_CS0_OSET); - if (*burst == H4_2420_SDRC_MR_0_SDR) - return (1); - return (0); -} - -/*********************************************************** - * get_mem_type() - identify type of mDDR part used. - * 2422 uses stacked DDR, 2 parts CS0/CS1. - * 2420 may have 1 or 2, no good way to know...only init 1... - * when eeprom data is up we can select 1 more. - *************************************************************/ -u32 get_mem_type(void) -{ - u32 cpu, sdr = is_mem_sdr(); - - cpu = get_cpu_type(); - if (cpu == CPU_2422 || cpu == CPU_2423) - return (DDR_STACKED); - - if (get_prod_id() == 0x2) - return (XDR_POP); - - if (get_board_type() == BOARD_H4_MENELAUS) - if (sdr) - return (SDR_DISCRETE); - else - return (DDR_COMBO); - else if (sdr) /* SDP + SDR kit */ - return (SDR_DISCRETE); - else - return (DDR_DISCRETE); /* origional SDP */ -} - -/*********************************************************************** - * get_cs0_size() - get size of chip select 0/1 - ************************************************************************/ -u32 get_sdr_cs_size(u32 offset) -{ - u32 size; - size = __raw_readl(SDRC_MCFG_0 + offset) >> 8; /* get ram size field */ - size &= 0x2FF; /* remove unwanted bits */ - size *= SZ_2M; /* find size in MB */ - return (size); -} - -/*********************************************************************** - * get_board_type() - get board type based on current production stats. - * --- NOTE: 2 I2C EEPROMs will someday be populated with proper info. - * when they are available we can get info from there. This should - * be correct of all known boards up until today. - ************************************************************************/ -u32 get_board_type(void) -{ - return (BOARD_H4_SDP); -} - -/****************************************************************** - * get_sysboot_value() - get init word settings (dip switch on h4) - ******************************************************************/ -inline u32 get_sysboot_value(void) -{ - return (0x00000FFF & __raw_readl(CONTROL_STATUS)); -} - -/*************************************************************************** - * get_gpmc0_base() - Return current address hardware will be - * fetching from. The below effectively gives what is correct, its a bit - * mis-leading compared to the TRM. For the most general case the mask - * needs to be also taken into account this does work in practice. - * - for u-boot we currently map: - * -- 0 to nothing, - * -- 4 to flash - * -- 8 to enent - * -- c to wifi - ****************************************************************************/ -u32 get_gpmc0_base(void) -{ - u32 b; - - b = __raw_readl(GPMC_CONFIG7_0); - b &= 0x1F; /* keep base [5:0] */ - b = b << 24; /* ret 0x0b000000 */ - return (b); -} - -/***************************************************************** - * is_gpmc_muxed() - tells if address/data lines are multiplexed - *****************************************************************/ -u32 is_gpmc_muxed(void) -{ - u32 mux; - mux = get_sysboot_value(); - if ((mux & (BIT0 | BIT1 | BIT2 | BIT3)) == (BIT0 | BIT2 | BIT3)) - return (GPMC_MUXED); /* NAND Boot mode */ - if (mux & BIT1) /* if mux'ed */ - return (GPMC_MUXED); - else - return (GPMC_NONMUXED); -} - -/************************************************************************ - * get_gpmc0_type() - read sysboot lines to see type of memory attached - ************************************************************************/ -u32 get_gpmc0_type(void) -{ - u32 type; - type = get_sysboot_value(); - if ((type & (BIT3 | BIT2)) == (BIT3 | BIT2)) - return (TYPE_NAND); - else - return (TYPE_NOR); -} - -/******************************************************************* - * get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand) - *******************************************************************/ -u32 get_gpmc0_width(void) -{ - u32 width; - width = get_sysboot_value(); - if ((width & 0xF) == (BIT3 | BIT2)) - return (WIDTH_8BIT); - else - return (WIDTH_16BIT); -} - -/********************************************************************* - * wait_on_value() - common routine to allow waiting for changes in - * volatile regs. - *********************************************************************/ -u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) -{ - u32 i = 0, val; - do { - ++i; - val = __raw_readl(read_addr) & read_bit_mask; - if (val == match_value) - return (1); - if (i == bound) - return (0); - } while (1); -} - -/********************************************************************* - * display_board_info() - print banner with board info. - *********************************************************************/ -void display_board_info(u32 btype) -{ - char cpu_2420[] = "2420"; /* cpu type */ - char cpu_2422[] = "2422"; - char cpu_2423[] = "2423"; - char mem_sdr[] = "mSDR"; /* memory type */ - char mem_ddr[] = "mDDR"; - char t_tst[] = "TST"; /* security level */ - char t_emu[] = "EMU"; - char t_hs[] = "HS"; - char t_gp[] = "GP"; - char unk[] = "?"; - - char *cpu_s, *mem_s, *sec_s; - u32 cpu, rev, sec; - - rev = get_cpu_rev(); - cpu = get_cpu_type(); - sec = get_device_type(); - - if (is_mem_sdr()) - mem_s = mem_sdr; - else - mem_s = mem_ddr; - - if (cpu == CPU_2423) - cpu_s = cpu_2423; - else if (cpu == CPU_2422) - cpu_s = cpu_2422; - else - cpu_s = cpu_2420; - - switch (sec) { - case TST_DEVICE: - sec_s = t_tst; - break; - case EMU_DEVICE: - sec_s = t_emu; - break; - case HS_DEVICE: - sec_s = t_hs; - break; - case GP_DEVICE: - sec_s = t_gp; - break; - default: - sec_s = unk; - } - - printf("OMAP%s-%s revision %d\n", cpu_s, sec_s, rev - 1); - printf("Samsung Apollon SDP Base Board + %s \n", mem_s); -} - -/************************************************************************* - * get_board_rev() - setup to pass kernel board revision information - * 0 = 242x IP platform (first 2xx boards) - * 1 = 242x Menelaus platfrom. - *************************************************************************/ -u32 get_board_rev(void) -{ - u32 rev = 0; - u32 btype = get_board_type(); - - if (btype == BOARD_H4_MENELAUS) - rev = 1; - return (rev); -} - -/******************************************************** - * get_base(); get upper addr of current execution - *******************************************************/ -u32 get_base(void) -{ - u32 val; - __asm__ __volatile__("mov %0, pc \n":"=r"(val)::"memory"); - val &= 0xF0000000; - val >>= 28; - return (val); -} - -/******************************************************** - * get_base2(); get 2upper addr of current execution - *******************************************************/ -u32 get_base2(void) -{ - u32 val; - __asm__ __volatile__("mov %0, pc \n":"=r"(val)::"memory"); - val &= 0xFF000000; - val >>= 24; - return (val); -} - -/******************************************************** - * running_in_flash() - tell if currently running in - * flash. - *******************************************************/ -u32 running_in_flash(void) -{ - if (get_base() < 4) - return (1); /* in flash */ - return (0); /* running in SRAM or SDRAM */ -} - -/******************************************************** - * running_in_sram() - tell if currently running in - * sram. - *******************************************************/ -u32 running_in_sram(void) -{ - if (get_base() == 4) - return (1); /* in SRAM */ - return (0); /* running in FLASH or SDRAM */ -} - -/******************************************************** - * running_in_sdram() - tell if currently running in - * flash. - *******************************************************/ -u32 running_in_sdram(void) -{ - if (get_base() > 4) - return (1); /* in sdram */ - return (0); /* running in SRAM or FLASH */ -} - -/************************************************************* - * running_from_internal_boot() - am I a signed NOR image. - *************************************************************/ -u32 running_from_internal_boot(void) -{ - u32 v, base; - - v = get_sysboot_value() & BIT3; - base = get_base2(); - /* if running at mask rom flash address and - * sysboot3 says this was an internal boot - */ - if ((base == 0x08) && v) - return (1); - else - return (0); -} - -/************************************************************* - * get_device_type(): tell if GP/HS/EMU/TST - *************************************************************/ -u32 get_device_type(void) -{ - int mode; - mode = __raw_readl(CONTROL_STATUS) & (BIT10 | BIT9 | BIT8); - return (mode >>= 8); -} diff --git a/boards.cfg b/boards.cfg index ea5c7a9..b4e0d3c 100644 --- a/boards.cfg +++ b/boards.cfg @@ -50,7 +50,6 @@ tt01 arm arm1136 - hale imx31_litekit arm arm1136 - logicpd mx31 flea3 arm arm1136 - CarMediaLab mx35 mx35pdk arm arm1136 - freescale mx35 -apollon arm arm1136 apollon - omap24xx omap2420h4 arm arm1136 - ti omap24xx tnetv107x_evm arm arm1176 tnetv107xevm ti tnetv107x rpi_b arm arm1176 rpi_b raspberrypi bcm2835 diff --git a/doc/README.scrapyard b/doc/README.scrapyard index 4b5558d..5929a8e 100644 --- a/doc/README.scrapyard +++ b/doc/README.scrapyard @@ -11,6 +11,7 @@ easily if here is something they might want to dig for... Board Arch CPU removed Commit last known maintainer/contact ============================================================================= +apollon arm omap24xx - 2012-09-06 Kyungmin Park tb0229 mips mips32 - 2011-12-12 rmu powerpc MPC850 fb82fd7 2011-12-07 Wolfgang Denk OXC powerpc MPC8240 309a292 2011-12-07 diff --git a/include/configs/apollon.h b/include/configs/apollon.h deleted file mode 100644 index b8ca8a8..0000000 --- a/include/configs/apollon.h +++ /dev/null @@ -1,261 +0,0 @@ -/* - * (C) Copyright 2005-2008 - * Samsung Electronics, - * Kyungmin Park - * - * Configuration settings for the 2420 Samsung Apollon board. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef __CONFIG_H -#define __CONFIG_H - -/* - * High Level Configuration Options - */ -#define CONFIG_ARM1136 1 /* This is an arm1136 CPU core */ -#define CONFIG_OMAP 1 /* in a TI OMAP core */ -#define CONFIG_OMAP2420 1 /* which is in a 2420 */ -#define CONFIG_OMAP2420_APOLLON 1 -#define CONFIG_APOLLON 1 -#define CONFIG_APOLLON_PLUS 1 /* If you have apollon plus 1.x */ - -#define CONFIG_ONENAND_U_BOOT y - -/* Clock config to target*/ -#define PRCM_CONFIG_I 1 -/* #define PRCM_CONFIG_II 1 */ - -/* Boot method */ -/* uncomment if you use NOR boot */ -/* #define CONFIG_SYS_NOR_BOOT 1 */ - -/* uncomment if you use NOR on CS3 */ -/* #define CONFIG_SYS_USE_NOR 1 */ - -#ifdef CONFIG_SYS_NOR_BOOT -#undef CONFIG_SYS_USE_NOR -#define CONFIG_SYS_USE_NOR 1 -#endif - -/* uncommnet if you want to use UBI */ -#define CONFIG_SYS_USE_UBI - -#include /* get chip and board defs */ - -#define V_SCLK 12000000 - -/* input clock of PLL */ -/* the OMAP2420 H4 has 12MHz, 13MHz, or 19.2Mhz crystal input */ -#define CONFIG_SYS_CLK_FREQ V_SCLK - -#define CONFIG_MISC_INIT_R - -#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ -#define CONFIG_SETUP_MEMORY_TAGS 1 -#define CONFIG_INITRD_TAG 1 -#define CONFIG_REVISION_TAG 1 - -/* - * Size of malloc() pool - */ -#define CONFIG_ENV_SIZE SZ_128K /* Total Size of Environment Sector */ -#define CONFIG_ENV_SIZE_FLEX SZ_256K -#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_1M) - -/* - * Hardware drivers - */ - -/* - * SMC91c96 Etherent - */ -#define CONFIG_LAN91C96 -#define CONFIG_LAN91C96_BASE (APOLLON_CS1_BASE+0x300) -#define CONFIG_LAN91C96_EXT_PHY - -/* - * NS16550 Configuration - */ -#define V_NS16550_CLK (48000000) /* 48MHz (APLL96/2) */ - -#define CONFIG_SYS_NS16550 -#define CONFIG_SYS_NS16550_SERIAL -#define CONFIG_SYS_NS16550_REG_SIZE (-4) -#define CONFIG_SYS_NS16550_CLK V_NS16550_CLK /* 3MHz (1.5MHz*2) */ -#define CONFIG_SYS_NS16550_COM1 OMAP2420_UART1 - -/* - * select serial console configuration - */ -#define CONFIG_SERIAL1 1 /* UART1 on H4 */ - -/* allow to overwrite serial and ethaddr */ -#define CONFIG_ENV_OVERWRITE -#define CONFIG_CONS_INDEX 1 -#define CONFIG_BAUDRATE 115200 - -/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ -#include - -#define CONFIG_CMD_DHCP -#define CONFIG_CMD_DIAG -#define CONFIG_CMD_ONENAND - -#ifdef CONFIG_SYS_USE_UBI -#define CONFIG_CMD_JFFS2 -#define CONFIG_CMD_UBI -#define CONFIG_RBTREE -#define CONFIG_MTD_DEVICE /* needed for mtdparts commands */ -#define CONFIG_MTD_PARTITIONS -#endif - -#undef CONFIG_CMD_SOURCE - -#ifndef CONFIG_SYS_USE_NOR -# undef CONFIG_CMD_FLASH -# undef CONFIG_CMD_IMLS -#endif - -#define CONFIG_BOOTP_MASK CONFIG_BOOTP_DEFAULT - -#define CONFIG_BOOTDELAY 1 - -#define CONFIG_NETMASK 255.255.255.0 -#define CONFIG_IPADDR 192.168.116.25 -#define CONFIG_SERVERIP 192.168.116.1 -#define CONFIG_BOOTFILE "uImage" -#define CONFIG_ETHADDR 00:0E:99:00:24:20 - -#ifdef CONFIG_APOLLON_PLUS -#define CONFIG_SYS_MEM "mem=64M" -#else -#define CONFIG_SYS_MEM "mem=128" -#endif - -#ifdef CONFIG_SYS_USE_UBI -#define CONFIG_SYS_UBI "ubi.mtd=4" -#else -#define CONFIG_SYS_UBI "" -#endif - -#define CONFIG_BOOTARGS "root=/dev/nfs rw " CONFIG_SYS_MEM \ - " console=ttyS0,115200n8" \ - " ip=192.168.116.25:192.168.116.1:192.168.116.1:255.255.255.0:" \ - "apollon:eth0:off nfsroot=/tftpboot/nfsroot profile=2 " \ - CONFIG_SYS_UBI - -#define CONFIG_EXTRA_ENV_SETTINGS \ - "Image=tftp 0x80008000 Image; go 0x80008000\0" \ - "zImage=tftp 0x80180000 zImage; go 0x80180000\0" \ - "uImage=tftp 0x80180000 uImage; bootm 0x80180000\0" \ - "uboot=tftp 0x80008000 u-boot.bin; go 0x80008000\0" \ - "xloader=tftp 0x80180000 x-load.bin; " \ - " cp.w 0x80180000 0x00000400 0x1000; go 0x00000400\0" \ - "syncmode50=mw.w 0x1e442 0xc0c4; mw 0x6800a060 0xe30d1201\0" \ - "syncmode=mw.w 0x1e442 0xe0f4; mw 0x6800a060 0xe30d1201\0" \ - "norboot=cp32 0x18040000 0x80008000 0x200000; go 0x80008000\0" \ - "oneboot=onenand read 0x80008000 0x40000 0x200000; go 0x80008000\0" \ - "onesyncboot=run syncmode oneboot\0" \ - "updateb=tftp 0x80180000 u-boot-onenand.bin; " \ - " onenand erase 0x0 0x20000; onenand write 0x80180000 0x0 0x20000\0" \ - "ubi=setenv bootargs ${bootargs} ubi.mtd=4 ${mtdparts}; run uImage\0" \ - "bootcmd=run uboot\0" - -/* - * Miscellaneous configurable options - */ -#define CONFIG_SYS_LONGHELP /* undef to save memory */ -#define CONFIG_SYS_PROMPT "Apollon # " -#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ -/* Print Buffer Size */ -#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) -#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ -/* Boot Argument Buffer Size */ -#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE -/* memtest works on */ -#define CONFIG_SYS_MEMTEST_START (OMAP2420_SDRC_CS0) -#define CONFIG_SYS_MEMTEST_END (OMAP2420_SDRC_CS0+SZ_31M) - -/* default load address */ -#define CONFIG_SYS_LOAD_ADDR (OMAP2420_SDRC_CS0) - -/* The 2420 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) - * or by 32KHz clk, or from external sig. This rate is divided by a local - * divisor. - */ -#define CONFIG_SYS_TIMERBASE OMAP2420_GPT2 -#define CONFIG_SYS_PTV 7 /* 2^(PTV+1) */ -#define CONFIG_SYS_HZ ((CONFIG_SYS_CLK_FREQ)/(2 << CONFIG_SYS_PTV)) - -/*----------------------------------------------------------------------- - * Physical Memory Map - */ -#define CONFIG_NR_DRAM_BANKS 1 /* CS1 may or may not be populated */ -#define PHYS_SDRAM_1 OMAP2420_SDRC_CS0 -#define PHYS_SDRAM_1_SIZE SZ_128M -#define PHYS_SDRAM_2 OMAP2420_SDRC_CS1 - -/*----------------------------------------------------------------------- - * FLASH and environment organization - */ -#ifdef CONFIG_SYS_USE_NOR -/* OneNAND boot, NOR has CS3, But NOR has CS0 when NOR boot */ -# define CONFIG_SYS_FLASH_BASE 0x18000000 -# define CONFIG_SYS_MAX_FLASH_BANKS 1 -# define CONFIG_SYS_MAX_FLASH_SECT 1024 -/*----------------------------------------------------------------------- - * CFI FLASH driver setup - */ -/* Flash memory is CFI compliant */ -# define CONFIG_SYS_FLASH_CFI 1 -# define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ -/* Use buffered writes (~10x faster) */ -/* #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1 */ -/* Use h/w sector protection*/ -# define CONFIG_SYS_FLASH_PROTECTION 1 - -#else /* !CONFIG_SYS_USE_NOR */ -# define CONFIG_SYS_NO_FLASH 1 -#endif /* CONFIG_SYS_USE_NOR */ - -/* OneNAND boot, OneNAND has CS0, NOR boot ONeNAND has CS2 */ -#define CONFIG_SYS_ONENAND_BASE 0x00000000 -#define CONFIG_SYS_MONITOR_LEN SZ_256K /* U-Boot image size */ -#define CONFIG_ENV_IS_IN_ONENAND 1 -#define CONFIG_ENV_ADDR 0x00020000 -#define CONFIG_ENV_ADDR_FLEX 0x00040000 - -#ifdef CONFIG_SYS_USE_UBI -#define CONFIG_CMD_MTDPARTS -#define MTDIDS_DEFAULT "onenand0=onenand" -#define MTDPARTS_DEFAULT "mtdparts=onenand:128k(bootloader)," \ - "128k(params)," \ - "2m(kernel)," \ - "16m(rootfs)," \ - "32m(fs)," \ - "-(ubifs)" -#endif - -#define PHYS_SRAM 0x4020F800 -#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 -#define CONFIG_SYS_INIT_SP_ADDR PHYS_SRAM - -#endif /* __CONFIG_H */ diff --git a/onenand_ipl/board/apollon/Makefile b/onenand_ipl/board/apollon/Makefile deleted file mode 100644 index 3bc9920..0000000 --- a/onenand_ipl/board/apollon/Makefile +++ /dev/null @@ -1,87 +0,0 @@ - -include $(TOPDIR)/config.mk -include $(TOPDIR)/onenand_ipl/board/$(BOARDDIR)/config.mk - -LDSCRIPT= $(TOPDIR)/onenand_ipl/board/$(BOARDDIR)/u-boot.onenand.lds -LDFLAGS = -Bstatic -T $(onenandobj)u-boot.lds -Ttext $(CONFIG_SYS_TEXT_BASE) $(PLATFORM_LDFLAGS) -AFLAGS += -DCONFIG_SPL_BUILD -DCONFIG_ONENAND_IPL -CFLAGS += -DCONFIG_SPL_BUILD -DCONFIG_ONENAND_IPL -OBJCFLAGS += --gap-fill=0x00 - -SOBJS := low_levelinit.o -SOBJS += start.o -COBJS := apollon.o -COBJS += onenand_read.o -COBJS += onenand_boot.o - -SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -__OBJS := $(SOBJS) $(COBJS) -LNDIR := $(OBJTREE)/onenand_ipl/board/$(BOARDDIR) - -onenandobj := $(OBJTREE)/onenand_ipl/ - -ALL = $(onenandobj)onenand-ipl $(onenandobj)onenand-ipl.bin $(onenandobj)onenand-ipl-2k.bin $(onenandobj)onenand-ipl-4k.bin - -all: $(obj).depend $(ALL) - -$(onenandobj)onenand-ipl-2k.bin: $(onenandobj)onenand-ipl - $(OBJCOPY) ${OBJCFLAGS} --pad-to=0x800 -O binary $< $@ - -$(onenandobj)onenand-ipl-4k.bin: $(onenandobj)onenand-ipl - $(OBJCOPY) ${OBJCFLAGS} --pad-to=0x1000 -O binary $< $@ - -$(onenandobj)onenand-ipl.bin: $(onenandobj)onenand-ipl - $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ - -$(onenandobj)onenand-ipl: $(OBJS) $(onenandobj)u-boot.lds - cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \ - -Map $@.map -o $@ - -$(onenandobj)u-boot.lds: $(LDSCRIPT) - $(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@ - -# create symbolic links from common files - -# from cpu directory -$(obj)start.S: - @rm -f $@ - ln -s $(SRCTREE)/$(CPUDIR)/start.S $@ - -# from onenand_ipl directory -$(obj)onenand_ipl.h: - @rm -f $@ - ln -s $(SRCTREE)/onenand_ipl/onenand_ipl.h $@ - -$(obj)onenand_boot.c: $(obj)onenand_ipl.h - @rm -f $@ - ln -s $(SRCTREE)/onenand_ipl/onenand_boot.c $@ - -$(obj)onenand_read.c: $(obj)onenand_ipl.h - @rm -f $@ - ln -s $(SRCTREE)/onenand_ipl/onenand_read.c $@ - -ifneq ($(OBJTREE), $(SRCTREE)) -$(obj)apollon.c: - @rm -f $@ - ln -s $(SRCTREE)/onenand_ipl/board/$(BOARDDIR)/apollon.c $@ - -$(obj)low_levelinit.S: - @rm -f $@ - ln -s $(SRCTREE)/onenand_ipl/board/$(BOARDDIR)/low_levelinit.S $@ -endif - -######################################################################### - -$(obj)%.o: $(obj)%.S - $(CC) $(AFLAGS) -c -o $@ $< - -$(obj)%.o: $(obj)$.c - $(CC) $(CFLAGS) -c -o $@ $< - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/onenand_ipl/board/apollon/apollon.c b/onenand_ipl/board/apollon/apollon.c deleted file mode 100644 index 4936e00..0000000 --- a/onenand_ipl/board/apollon/apollon.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * (C) Copyright 2005-2008 Samsung Electronics - * Kyungmin Park - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include -#include - -#define write_config_reg(reg, value) \ -do { \ - writeb(value, reg); \ -} while (0) - -/***************************************** - * Routine: board_init - * Description: Early hardware init. - *****************************************/ -int board_init(void) -{ - return 0; -} - -#ifdef CONFIG_SYS_PRINTF -/* Pin Muxing registers used for UART1 */ -/**************************************** - * Routine: muxSetupUART1 (ostboot) - * Description: Set up uart1 muxing - *****************************************/ -static void muxSetupUART1(void) -{ - /* UART1_CTS pin configuration, PIN = D21 */ - write_config_reg(CONTROL_PADCONF_UART1_CTS, 0); - /* UART1_RTS pin configuration, PIN = H21 */ - write_config_reg(CONTROL_PADCONF_UART1_RTS, 0); - /* UART1_TX pin configuration, PIN = L20 */ - write_config_reg(CONTROL_PADCONF_UART1_TX, 0); - /* UART1_RX pin configuration, PIN = T21 */ - write_config_reg(CONTROL_PADCONF_UART1_RX, 0); -} -#endif - -/********************************************************** - * Routine: s_init - * Description: Does early system init of muxing and clocks. - * - Called at time when only stack is available. - **********************************************************/ -int s_init(int skip) -{ -#ifdef CONFIG_SYS_PRINTF - muxSetupUART1(); -#endif - return 0; -} diff --git a/onenand_ipl/board/apollon/config.mk b/onenand_ipl/board/apollon/config.mk deleted file mode 100644 index 62956e8..0000000 --- a/onenand_ipl/board/apollon/config.mk +++ /dev/null @@ -1,14 +0,0 @@ -# -# (C) Copyright 2005-2008 Samsung Electronics -# Kyungmin Park -# -# Samsung Apollon board with OMAP2420 (ARM1136) cpu -# -# Apollon has 1 bank of 128MB mDDR-SDRAM on CS0 -# Physical Address: -# 8000'0000 (bank0) -# 8800'0000 (bank1) -# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 -# (mem base + reserved) - -CONFIG_SYS_TEXT_BASE = 0x00000000 diff --git a/onenand_ipl/board/apollon/low_levelinit.S b/onenand_ipl/board/apollon/low_levelinit.S deleted file mode 100644 index cab4227..0000000 --- a/onenand_ipl/board/apollon/low_levelinit.S +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Board specific setup info - * - * (C) Copyright 2005-2008 Samsung Electronics - * Kyungmin Park - * - * Derived from board/omap2420h4/platform.S - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#define APOLLON_CS0_BASE 0x00000000 - -#ifdef PRCM_CONFIG_I -#define SDRC_ACTIM_CTRLA_0_VAL 0x7BA35907 -#define SDRC_ACTIM_CTRLB_0_VAL 0x00000013 -#define SDRC_RFR_CTRL_0_VAL 0x00044C01 - -/* GPMC */ -#define APOLLON_GPMC_CONFIG1_0 0xe30d1201 -#define APOLLON_GPMC_CONFIG2_0 0x000c1000 -#define APOLLON_GPMC_CONFIG3_0 0x00030400 -#define APOLLON_GPMC_CONFIG4_0 0x0B841006 -#define APOLLON_GPMC_CONFIG5_0 0x020F0C11 -#define APOLLON_GPMC_CONFIG6_0 0x00000000 -#define APOLLON_GPMC_CONFIG7_0 (0x00000e40 | (APOLLON_CS0_BASE >> 24)) - -#elif defined(PRCM_CONFIG_II) -#define SDRC_ACTIM_CTRLA_0_VAL 0x4A59B485 -#define SDRC_ACTIM_CTRLB_0_VAL 0x0000000C -#define SDRC_RFR_CTRL_0_VAL 0x00030001 - -/* GPMC */ -#define APOLLON_GPMC_CONFIG1_0 0xe30d1201 -#define APOLLON_GPMC_CONFIG2_0 0x00080E81 -#define APOLLON_GPMC_CONFIG3_0 0x00030400 -#define APOLLON_GPMC_CONFIG4_0 0x08041586 -#define APOLLON_GPMC_CONFIG5_0 0x020C090E -#define APOLLON_GPMC_CONFIG6_0 0x00000000 -#define APOLLON_GPMC_CONFIG7_0 (0x00000e40 | (APOLLON_CS0_BASE >> 24)) - -#else -#error "Please configure PRCM schecm" -#endif - -_TEXT_BASE: - .word CONFIG_SYS_TEXT_BASE /* sdram load addr from config.mk */ - -.globl lowlevel_init -lowlevel_init: - mov r3, r0 /* save skip information */ - - /* Disable watchdog */ - ldr r0, =WD2_BASE - ldr r1, =WD_UNLOCK1 - str r1, [r0, #WSPR] - - ldr r1, =WD_UNLOCK2 - str r1, [r0, #WSPR] - -#ifdef DEBUG_LED - /* LED0 OFF */ - ldr r0, =0x480000E5 /* ball AA10, mode 3 */ - mov r1, #0x0b - strb r1, [r0] -#endif - - /* Pin muxing for SDRC */ - mov r1, #0x00 - ldr r0, =0x480000A1 /* ball C12, mode 0 */ - strb r1, [r0] - - ldr r0, =0x48000032 /* ball D11, mode 0 */ - strb r1, [r0] - - ldr r0, =0x480000A3 /* ball B13, mode 0 */ - strb r1, [r0] - - /* SDRC setting */ - ldr r0, =OMAP2420_SDRC_BASE - ldr r1, =0x00000010 - str r1, [r0, #0x10] - - ldr r1, =0x00000100 - str r1, [r0, #0x44] - - /* SDRC CS0 configuration */ -#ifdef CONFIG_APOLLON_PLUS - ldr r1, =0x01702011 -#else - ldr r1, =0x00d04011 -#endif - str r1, [r0, #0x80] - - ldr r1, =SDRC_ACTIM_CTRLA_0_VAL - str r1, [r0, #0x9C] - - ldr r1, =SDRC_ACTIM_CTRLB_0_VAL - str r1, [r0, #0xA0] - - ldr r1, =SDRC_RFR_CTRL_0_VAL - str r1, [r0, #0xA4] - - ldr r1, =0x00000041 - str r1, [r0, #0x70] - - /* Manual command sequence */ - ldr r1, =0x00000007 - str r1, [r0, #0xA8] - - ldr r1, =0x00000000 - str r1, [r0, #0xA8] - - ldr r1, =0x00000001 - str r1, [r0, #0xA8] - - ldr r1, =0x00000002 - str r1, [r0, #0xA8] - str r1, [r0, #0xA8] - - /* - * CS0 SDRC Mode register - * Burst length = 4 - DDR memory - * Serial mode - * CAS latency = 3 - */ - ldr r1, =0x00000032 - str r1, [r0, #0x84] - - /* Note: You MUST set EMR values */ - /* EMR1 & EMR2 */ - ldr r1, =0x00000000 - str r1, [r0, #0x88] - str r1, [r0, #0x8C] - -#ifdef OLD_SDRC_DLLA_CTRL - /* SDRC_DLLA_CTRL */ - ldr r1, =0x00007306 - str r1, [r0, #0x60] - - ldr r1, =0x00007303 - str r1, [r0, #0x60] -#else - /* SDRC_DLLA_CTRL */ - ldr r1, =0x00000506 - str r1, [r0, #0x60] - - ldr r1, =0x00000503 - str r1, [r0, #0x60] -#endif - -#ifdef __BROKEN_FEATURE__ - /* SDRC_DLLB_CTRL */ - ldr r1, =0x00000506 - str r1, [r0, #0x68] - - ldr r1, =0x00000503 - str r1, [r0, #0x68] -#endif - - /* little delay after init */ - mov r2, #0x1800 -1: - subs r2, r2, #0x1 - bne 1b - - ldr sp, SRAM_STACK - str ip, [sp] /* stash old link register */ - mov ip, lr /* save link reg across call */ - mov r0, r3 /* pass skip info to s_init */ - - bl s_init /* go setup pll,mux,memory */ - - ldr ip, [sp] /* restore save ip */ - mov lr, ip /* restore link reg */ - - /* back to arch calling code */ - mov pc, lr - - /* the literal pools origin */ - .ltorg - -SRAM_STACK: - .word LOW_LEVEL_SRAM_STACK diff --git a/onenand_ipl/board/apollon/u-boot.onenand.lds b/onenand_ipl/board/apollon/u-boot.onenand.lds deleted file mode 100644 index 721d2f5..0000000 --- a/onenand_ipl/board/apollon/u-boot.onenand.lds +++ /dev/null @@ -1,53 +0,0 @@ -/* - * (C) Copyright 2005-2008 Samsung Electronics - * Kyungmin Park - * - * Derived from X-loader - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_start) -SECTIONS -{ - . = 0x00000000; - - . = ALIGN(4); - .text : - { - start.o (.text) - *(.text) - } - - . = ALIGN(4); - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } - - . = ALIGN(4); - .data : { *(.data) } - - . = ALIGN(4); - .got : { *(.got) } - - . = ALIGN(4); - __bss_start = .; - .bss : { *(.bss) . = ALIGN(4); } - __bss_end__ = .; -} -- cgit v1.1 From 78b2de802f5f996d1e6d9383d1e05194351c429b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 7 Sep 2012 09:15:33 +0000 Subject: env_nand: fix incorrect size parameter to ALLOC_CACHE_ALIGN_BUFFER The third parameter to ALLOC_CACHE_ALIGN_BUFFER is not size (as named), but rather count (number of elements of the type to allocate). The current code ends up allocating one copy of env_t for each byte in its size, which quite possibly ends up overflowing RAM. This fixes a bug in commit 3801a15 "env_nand: align NAND buffers". Reported-by: Prabhakar Lad Signed-off-by: Stephen Warren Reported-by: Prabhakar Lad --- common/env_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/env_nand.c b/common/env_nand.c index e635472..79e8033 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -226,7 +226,7 @@ int saveenv(void) int saveenv(void) { int ret = 0; - ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, sizeof(env_t)); + ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); ssize_t len; char *res; nand_erase_options_t nand_erase_options; -- cgit v1.1 From b8496cced856ff411f1eb2e4eff20f5abe7080b0 Mon Sep 17 00:00:00 2001 From: Iwo Mergler Date: Sun, 9 Sep 2012 20:16:58 +0000 Subject: memsize: Fix for bug in memory sizing code The original memory sizing code in get_ram_size clobbers the word at the base address, but forgets to restore it. Signed-off-by: Iwo Mergler --- common/memsize.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/memsize.c b/common/memsize.c index 963e4f3..74cf075 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -73,6 +73,7 @@ long get_ram_size(long *base, long maxsize) } return (0); } + *addr = save[i]; for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) { addr = base + cnt; /* pointer arith! */ -- cgit v1.1 From 4796bc4bbc895c4ee045e4299daa04beb096cbb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 07:45:44 +0000 Subject: env import/export: Remove from help if disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk Acked-by: Mike Frysinger --- common/cmd_nvedit.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index fd05e72..0f320cc 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -954,11 +954,15 @@ U_BOOT_CMD( #if defined(CONFIG_CMD_EDITENV) "env edit name - edit environment variable\n" #endif +#if defined(CONFIG_CMD_EXPORTENV) "env export [-t | -b | -c] [-s size] addr [var ...] - export environment\n" +#endif #if defined(CONFIG_CMD_GREPENV) "env grep string [...] - search environment\n" #endif +#if defined(CONFIG_CMD_IMPORTENV) "env import [-d] [-t | -b | -c] addr [size] - import environment\n" +#endif "env print [name ...] - print environment\n" #if defined(CONFIG_CMD_RUN) "env run var [...] - run commands in an environment variable\n" -- cgit v1.1 From 84209afb87d10300a326589b5ce6e9e56bd5195b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 07:45:31 +0000 Subject: env_common: Add missing ethprime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ethprime env var was missing from env_common. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- common/env_common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/env_common.c b/common/env_common.c index d9e990d..911a6af 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -80,6 +80,9 @@ const uchar default_environment[] = { #ifdef CONFIG_ETH5ADDR "eth5addr=" MK_STR(CONFIG_ETH5ADDR) "\0" #endif +#ifdef CONFIG_ETHPRIME + "ethprime=" CONFIG_ETHPRIME "\0" +#endif #ifdef CONFIG_IPADDR "ipaddr=" MK_STR(CONFIG_IPADDR) "\0" #endif -- cgit v1.1 From 8ae51ae172b89e198e33779403338fb41926950b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 07:45:15 +0000 Subject: fw_env: Add env vars describing U-Boot target board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 5e724ca did the same thing for env_common and env_embedded, but forgot fw_env. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- tools/env/fw_env.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index e292d2b..1a2c227 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -203,6 +203,17 @@ static char default_environment[] = { #if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0) "pcidelay=" MK_STR (CONFIG_PCI_BOOTDELAY) "\0" #endif +#ifdef CONFIG_ENV_VARS_UBOOT_CONFIG + "arch=" CONFIG_SYS_ARCH "\0" + "cpu=" CONFIG_SYS_CPU "\0" + "board=" CONFIG_SYS_BOARD "\0" +#ifdef CONFIG_SYS_VENDOR + "vendor=" CONFIG_SYS_VENDOR "\0" +#endif +#ifdef CONFIG_SYS_SOC + "soc=" CONFIG_SYS_SOC "\0" +#endif +#endif #ifdef CONFIG_EXTRA_ENV_SETTINGS CONFIG_EXTRA_ENV_SETTINGS #endif -- cgit v1.1 From c2ba2ff51101cdcfabdc0bdc961e37cc51cb7d23 Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Fri, 24 Aug 2012 00:11:36 +0000 Subject: env: cosmetic: drop assignment i = iomux_doenv() iomux_doenv() can only return 0 or 1. So there is no need to save its return value in variable i, as checking its truth value within an if statement is enough. Signed-off-by: Gerlando Falauto Reviewed-by: Marek Vasut --- common/cmd_nvedit.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 0f320cc..eef6c10 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -239,9 +239,8 @@ int _do_env_set(int flag, int argc, char * const argv[]) } #ifdef CONFIG_CONSOLE_MUX - i = iomux_doenv(console, argv[2]); - if (i) - return i; + if (iomux_doenv(console, argv[2])) + return 1; #else /* Try assigning specified device */ if (console_assign(console, argv[2]) < 0) -- cgit v1.1 From c3f6525854bbc664ce9fbed9754af1daf56ba08e Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Fri, 24 Aug 2012 00:11:37 +0000 Subject: env: unify logic to check and apply changes The logic of checking special parameters (e.g. baudrate, stdin, stdout, for a valid value and/or whether can be overwritten) and applying the new value to the running system is now all within a single function env_check_apply() which can be called whenever changes are made to the environment, no matter if by set, default or import. With this patch env_check_apply() is only called by "env set", retaining previous behavior. Signed-off-by: Gerlando Falauto Reviewed-by: Marek Vasut --- common/cmd_nvedit.c | 141 ++++++++++++++++++++++++++++++++++------------------ include/search.h | 3 +- 2 files changed, 94 insertions(+), 50 deletions(-) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index eef6c10..86518d4 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -198,31 +198,19 @@ static int do_env_grep(cmd_tbl_t *cmdtp, int flag, #endif /* - * Set a new environment variable, - * or replace or delete an existing one. + * Perform consistency checking before setting, replacing, or deleting an + * environment variable, then (if successful) apply the changes to internals so + * to make them effective. Code for this function was taken out of + * _do_env_set(), which now calls it instead. + * Returns 0 in case of success, 1 in case of failure. + * When (flag & H_FORCE) is set, do not print out any error message and force + * overwriting of write-once variables. */ -int _do_env_set(int flag, int argc, char * const argv[]) + +int env_check_apply(const char *name, const char *oldval, + const char *newval, int flag) { - int i, len; int console = -1; - char *name, *value, *s; - ENTRY e, *ep; - - name = argv[1]; - - if (strchr(name, '=')) { - printf("## Error: illegal character '=' in variable name" - "\"%s\"\n", name); - return 1; - } - - env_id++; - /* - * search if variable with this name already exists - */ - e.key = name; - e.data = NULL; - hsearch_r(e, FIND, &ep, &env_htab); /* Check for console redirection */ if (strcmp(name, "stdin") == 0) @@ -233,59 +221,75 @@ int _do_env_set(int flag, int argc, char * const argv[]) console = stderr; if (console != -1) { - if (argc < 3) { /* Cannot delete it! */ - printf("Can't delete \"%s\"\n", name); + if ((newval == NULL) || (*newval == '\0')) { + /* We cannot delete stdin/stdout/stderr */ + if ((flag & H_FORCE) == 0) + printf("Can't delete \"%s\"\n", name); return 1; } #ifdef CONFIG_CONSOLE_MUX - if (iomux_doenv(console, argv[2])) + if (iomux_doenv(console, newval)) return 1; #else /* Try assigning specified device */ - if (console_assign(console, argv[2]) < 0) + if (console_assign(console, newval) < 0) return 1; #ifdef CONFIG_SERIAL_MULTI - if (serial_assign(argv[2]) < 0) + if (serial_assign(newval) < 0) return 1; #endif #endif /* CONFIG_CONSOLE_MUX */ } /* - * Some variables like "ethaddr" and "serial#" can be set only - * once and cannot be deleted; also, "ver" is readonly. + * Some variables like "ethaddr" and "serial#" can be set only once and + * cannot be deleted, unless CONFIG_ENV_OVERWRITE is defined. */ - if (ep) { /* variable exists */ #ifndef CONFIG_ENV_OVERWRITE + if (oldval != NULL && /* variable exists */ + (flag & H_FORCE) == 0) { /* and we are not forced */ if (strcmp(name, "serial#") == 0 || (strcmp(name, "ethaddr") == 0 #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR) - && strcmp(ep->data, MK_STR(CONFIG_ETHADDR)) != 0 + && strcmp(oldval, MK_STR(CONFIG_ETHADDR)) != 0 #endif /* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */ )) { printf("Can't overwrite \"%s\"\n", name); return 1; } + } #endif + /* + * When we change baudrate, or we are doing an env default -a + * (which will erase all variables prior to calling this), + * we want the baudrate to actually change - for real. + */ + if (oldval != NULL || /* variable exists */ + (flag & H_NOCLEAR) == 0) { /* or env is clear */ /* * Switch to new baudrate if new baudrate is supported */ if (strcmp(name, "baudrate") == 0) { - int baudrate = simple_strtoul(argv[2], NULL, 10); + int baudrate = simple_strtoul(newval, NULL, 10); int i; for (i = 0; i < N_BAUDRATES; ++i) { if (baudrate == baudrate_table[i]) break; } if (i == N_BAUDRATES) { - printf("## Baudrate %d bps not supported\n", - baudrate); + if ((flag & H_FORCE) == 0) + printf("## Baudrate %d bps not " + "supported\n", baudrate); return 1; } + if (gd->baudrate == baudrate) { + /* If unchanged, we just say it's OK */ + return 0; + } printf("## Switch baudrate to %d bps and" - "press ENTER ...\n", baudrate); + "press ENTER ...\n", baudrate); udelay(50000); gd->baudrate = baudrate; #if defined(CONFIG_PPC) || defined(CONFIG_MCF52x2) @@ -299,6 +303,59 @@ int _do_env_set(int flag, int argc, char * const argv[]) } } + /* + * Some variables should be updated when the corresponding + * entry in the environment is changed + */ + if (strcmp(name, "loadaddr") == 0) { + load_addr = simple_strtoul(newval, NULL, 16); + return 0; + } +#if defined(CONFIG_CMD_NET) + else if (strcmp(name, "bootfile") == 0) { + copy_filename(BootFile, newval, sizeof(BootFile)); + return 0; + } +#endif + return 0; +} + +/* + * Set a new environment variable, + * or replace or delete an existing one. +*/ +int _do_env_set(int flag, int argc, char * const argv[]) +{ + int i, len; + char *name, *value, *s; + ENTRY e, *ep; + + name = argv[1]; + value = argv[2]; + + if (strchr(name, '=')) { + printf("## Error: illegal character '='" + "in variable name \"%s\"\n", name); + return 1; + } + + env_id++; + /* + * search if variable with this name already exists + */ + e.key = name; + e.data = NULL; + hsearch_r(e, FIND, &ep, &env_htab); + + /* + * Perform requested checks. Notice how since we are overwriting + * a single variable, we need to set H_NOCLEAR + */ + if (env_check_apply(name, ep ? ep->data : NULL, value, H_NOCLEAR)) { + debug("check function did not approve, refusing\n"); + return 1; + } + /* Delete only ? */ if (argc < 3 || argv[2] == NULL) { int rc = hdelete_r(name, &env_htab); @@ -336,20 +393,6 @@ int _do_env_set(int flag, int argc, char * const argv[]) return 1; } - /* - * Some variables should be updated when the corresponding - * entry in the environment is changed - */ - if (strcmp(argv[1], "loadaddr") == 0) { - load_addr = simple_strtoul(argv[2], NULL, 16); - return 0; - } -#if defined(CONFIG_CMD_NET) - else if (strcmp(argv[1], "bootfile") == 0) { - copy_filename(BootFile, argv[2], sizeof(BootFile)); - return 0; - } -#endif return 0; } diff --git a/include/search.h b/include/search.h index ef53edb..a4a5ef4 100644 --- a/include/search.h +++ b/include/search.h @@ -99,6 +99,7 @@ extern int himport_r(struct hsearch_data *__htab, int __flag); /* Flags for himport_r() */ -#define H_NOCLEAR 1 /* do not clear hash table before importing */ +#define H_NOCLEAR (1 << 0) /* do not clear hash table before importing */ +#define H_FORCE (1 << 1) /* overwrite read-only/write-once variables */ #endif /* search.h */ -- cgit v1.1 From 348b1f1c6064990210a6797c86514fd358b73062 Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Fri, 24 Aug 2012 00:11:38 +0000 Subject: env: make himport_r() selective on variables Add 2 new arguments to himport_r(): o "nvars", "vars": number and list of variables to take into account (0 means ALL) NOTE: This patch does not change the current behaviour. Signed-off-by: Gerlando Falauto Reviewed-by: Marek Vasut --- common/cmd_nvedit.c | 3 ++- common/env_common.c | 6 ++++-- include/search.h | 6 +++++- lib/hashtable.c | 27 ++++++++++++++++++++++++++- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 86518d4..c601b3a 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -914,7 +914,8 @@ static int do_env_import(cmd_tbl_t *cmdtp, int flag, addr = (char *)ep->data; } - if (himport_r(&env_htab, addr, size, sep, del ? 0 : H_NOCLEAR) == 0) { + if (himport_r(&env_htab, addr, size, sep, del ? 0 : H_NOCLEAR, + 0, NULL) == 0) { error("Environment import failed: errno = %d\n", errno); return 1; } diff --git a/common/env_common.c b/common/env_common.c index 911a6af..c5cefd8 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -196,7 +196,8 @@ void set_default_env(const char *s) } if (himport_r(&env_htab, (char *)default_environment, - sizeof(default_environment), '\0', 0) == 0) + sizeof(default_environment), '\0', 0, + 0, NULL) == 0) error("Environment import failed: errno = %d\n", errno); gd->flags |= GD_FLG_ENV_READY; @@ -221,7 +222,8 @@ int env_import(const char *buf, int check) } } - if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0)) { + if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, + 0, NULL)) { gd->flags |= GD_FLG_ENV_READY; return 1; } diff --git a/include/search.h b/include/search.h index a4a5ef4..94d75fc 100644 --- a/include/search.h +++ b/include/search.h @@ -94,9 +94,13 @@ extern ssize_t hexport_r(struct hsearch_data *__htab, const char __sep, char **__resp, size_t __size, int argc, char * const argv[]); +/* + * nvars: length of vars array + * vars: array of strings (variable names) to import (nvars == 0 means all) + */ extern int himport_r(struct hsearch_data *__htab, const char *__env, size_t __size, const char __sep, - int __flag); + int __flag, int nvars, char * const vars[]); /* Flags for himport_r() */ #define H_NOCLEAR (1 << 0) /* do not clear hash table before importing */ diff --git a/lib/hashtable.c b/lib/hashtable.c index abd61c8..0610e86 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -603,6 +603,24 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, * himport() */ +/* Check whether variable name is amongst vars[] */ +static int is_var_in_set(const char *name, int nvars, char * const vars[]) +{ + int i = 0; + + /* No variables specified means process all of them */ + if (nvars == 0) + return 1; + + for (i = 0; i < nvars; i++) { + if (!strcmp(name, vars[i])) + return 1; + } + debug("Skipping non-listed variable %s\n", name); + + return 0; +} + /* * Import linearized data into hash table. * @@ -639,7 +657,8 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, */ int himport_r(struct hsearch_data *htab, - const char *env, size_t size, const char sep, int flag) + const char *env, size_t size, const char sep, int flag, + int nvars, char * const vars[]) { char *data, *sp, *dp, *name, *value; @@ -726,6 +745,8 @@ int himport_r(struct hsearch_data *htab, *dp++ = '\0'; /* terminate name */ debug("DELETE CANDIDATE: \"%s\"\n", name); + if (!is_var_in_set(name, nvars, vars)) + continue; if (hdelete_r(name, htab) == 0) debug("DELETE ERROR ##############################\n"); @@ -743,6 +764,10 @@ int himport_r(struct hsearch_data *htab, *sp++ = '\0'; /* terminate value */ ++dp; + /* Skip variables which are not supposed to be processed */ + if (!is_var_in_set(name, nvars, vars)) + continue; + /* enter into hash table */ e.key = name; e.data = value; -- cgit v1.1 From c5983592e912835fe9ed00b9d98b05580c460eae Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Fri, 24 Aug 2012 00:11:39 +0000 Subject: env: add check/apply logic to himport_r() Change hashtable so that a callback function will decide whether a variable can be overwritten, and possibly apply the changes. So add a new field to struct hsearch_data: o "apply" callback function to check whether a variable can be overwritten, and possibly immediately apply the changes; when NULL, no check is performed. And a new argument to himport_r(): o "do_apply": whether to call the apply callback function NOTE: This patch does not change the current behavior. Signed-off-by: Gerlando Falauto Reviewed-by: Marek Vasut --- common/cmd_nvedit.c | 3 ++- common/env_common.c | 8 +++++--- include/environment.h | 9 +++++++++ include/search.h | 14 +++++++++++++- lib/hashtable.c | 20 +++++++++++++++++++- 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index c601b3a..ddf3b8d 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -202,6 +202,7 @@ static int do_env_grep(cmd_tbl_t *cmdtp, int flag, * environment variable, then (if successful) apply the changes to internals so * to make them effective. Code for this function was taken out of * _do_env_set(), which now calls it instead. + * Also called as a callback function by himport_r(). * Returns 0 in case of success, 1 in case of failure. * When (flag & H_FORCE) is set, do not print out any error message and force * overwriting of write-once variables. @@ -915,7 +916,7 @@ static int do_env_import(cmd_tbl_t *cmdtp, int flag, } if (himport_r(&env_htab, addr, size, sep, del ? 0 : H_NOCLEAR, - 0, NULL) == 0) { + 0, NULL, 0 /* do_apply */) == 0) { error("Environment import failed: errno = %d\n", errno); return 1; } diff --git a/common/env_common.c b/common/env_common.c index c5cefd8..b9865bf 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -136,7 +136,9 @@ const uchar default_environment[] = { "\0" }; -struct hsearch_data env_htab; +struct hsearch_data env_htab = { + .apply = env_check_apply, +}; static uchar __env_get_char_spec(int index) { @@ -197,7 +199,7 @@ void set_default_env(const char *s) if (himport_r(&env_htab, (char *)default_environment, sizeof(default_environment), '\0', 0, - 0, NULL) == 0) + 0, NULL, 0 /* do_apply */) == 0) error("Environment import failed: errno = %d\n", errno); gd->flags |= GD_FLG_ENV_READY; @@ -223,7 +225,7 @@ int env_import(const char *buf, int check) } if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, - 0, NULL)) { + 0, NULL, 0 /* do_apply */)) { gd->flags |= GD_FLG_ENV_READY; return 1; } diff --git a/include/environment.h b/include/environment.h index ae3f7b6..90fb130 100644 --- a/include/environment.h +++ b/include/environment.h @@ -184,6 +184,15 @@ void set_default_env(const char *s); /* Import from binary representation into hash table */ int env_import(const char *buf, int check); +/* + * Check if variable "name" can be changed from oldval to newval, + * and if so, apply the changes (e.g. baudrate). + * When (flag & H_FORCE) is set, it does not print out any error + * message and forces overwriting of write-once variables. + */ +int env_check_apply(const char *name, const char *oldval, + const char *newval, int flag); + #endif /* DO_DEPS_ONLY */ #endif /* _ENVIRONMENT_H_ */ diff --git a/include/search.h b/include/search.h index 94d75fc..721c8ac 100644 --- a/include/search.h +++ b/include/search.h @@ -57,6 +57,16 @@ struct hsearch_data { struct _ENTRY *table; unsigned int size; unsigned int filled; +/* + * Callback function which will check whether the given change for variable + * "name" from "oldval" to "newval" may be applied or not, and possibly apply + * such change. + * When (flag & H_FORCE) is set, it shall not print out any error message and + * shall force overwriting of write-once variables. +.* Must return 0 for approval, 1 for denial. + */ + int (*apply)(const char *name, const char *oldval, + const char *newval, int flag); }; /* Create a new hashing table which will at most contain NEL elements. */ @@ -97,10 +107,12 @@ extern ssize_t hexport_r(struct hsearch_data *__htab, /* * nvars: length of vars array * vars: array of strings (variable names) to import (nvars == 0 means all) + * do_apply: whether to call callback function to check the new argument, + * and possibly apply changes (false means accept everything) */ extern int himport_r(struct hsearch_data *__htab, const char *__env, size_t __size, const char __sep, - int __flag, int nvars, char * const vars[]); + int __flag, int nvars, char * const vars[], int do_apply); /* Flags for himport_r() */ #define H_NOCLEAR (1 << 0) /* do not clear hash table before importing */ diff --git a/lib/hashtable.c b/lib/hashtable.c index 0610e86..6cfba56 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -658,7 +658,7 @@ static int is_var_in_set(const char *name, int nvars, char * const vars[]) int himport_r(struct hsearch_data *htab, const char *env, size_t size, const char sep, int flag, - int nvars, char * const vars[]) + int nvars, char * const vars[], int do_apply) { char *data, *sp, *dp, *name, *value; @@ -772,6 +772,24 @@ int himport_r(struct hsearch_data *htab, e.key = name; e.data = value; + /* if there is an apply function, check what it has to say */ + if (do_apply && htab->apply != NULL) { + debug("searching before calling cb function" + " for %s\n", name); + /* + * Search for variable in existing env, so to pass + * its previous value to the apply callback + */ + hsearch_r(e, FIND, &rv, htab); + debug("previous value was %s\n", rv ? rv->data : ""); + if (htab->apply(name, rv ? rv->data : NULL, + value, flag)) { + debug("callback function refused to set" + " variable %s, skipping it!\n", name); + continue; + } + } + hsearch_r(e, ENTER, &rv, htab); if (rv == NULL) { printf("himport_r: can't insert \"%s=%s\" into hash table\n", -- cgit v1.1 From 152874b65b8060e7b026933ce332a9687256e28c Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Fri, 24 Aug 2012 00:11:40 +0000 Subject: env: check and apply changes on delete/destroy Signed-off-by: Gerlando Falauto Reviewed-by: Marek Vasut --- common/cmd_nvedit.c | 2 +- include/search.h | 5 +++-- lib/hashtable.c | 16 ++++++++++------ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index ddf3b8d..310ca16 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -359,7 +359,7 @@ int _do_env_set(int flag, int argc, char * const argv[]) /* Delete only ? */ if (argc < 3 || argv[2] == NULL) { - int rc = hdelete_r(name, &env_htab); + int rc = hdelete_r(name, &env_htab, 0); return !rc; } diff --git a/include/search.h b/include/search.h index 721c8ac..93e1cbc 100644 --- a/include/search.h +++ b/include/search.h @@ -73,7 +73,7 @@ struct hsearch_data { extern int hcreate_r(size_t __nel, struct hsearch_data *__htab); /* Destroy current internal hashing table. */ -extern void hdestroy_r(struct hsearch_data *__htab); +extern void hdestroy_r(struct hsearch_data *__htab, int do_apply); /* * Search for entry matching ITEM.key in internal hash table. If @@ -98,7 +98,8 @@ extern int hstrstr_r(const char *__match, int __last_idx, ENTRY ** __retval, struct hsearch_data *__htab); /* Search and delete entry matching ITEM.key in internal hash table. */ -extern int hdelete_r(const char *__key, struct hsearch_data *__htab); +extern int hdelete_r(const char *__key, struct hsearch_data *__htab, + int do_apply); extern ssize_t hexport_r(struct hsearch_data *__htab, const char __sep, char **__resp, size_t __size, diff --git a/lib/hashtable.c b/lib/hashtable.c index 6cfba56..f3f47de 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -142,7 +142,7 @@ int hcreate_r(size_t nel, struct hsearch_data *htab) * be freed and the local static variable can be marked as not used. */ -void hdestroy_r(struct hsearch_data *htab) +void hdestroy_r(struct hsearch_data *htab, int do_apply) { int i; @@ -156,7 +156,10 @@ void hdestroy_r(struct hsearch_data *htab) for (i = 1; i <= htab->size; ++i) { if (htab->table[i].used > 0) { ENTRY *ep = &htab->table[i].entry; - + if (do_apply && htab->apply != NULL) { + /* deletion is always forced */ + htab->apply(ep->key, ep->data, NULL, H_FORCE); + } free((void *)ep->key); free(ep->data); } @@ -401,7 +404,7 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, * do that. */ -int hdelete_r(const char *key, struct hsearch_data *htab) +int hdelete_r(const char *key, struct hsearch_data *htab, int do_apply) { ENTRY e, *ep; int idx; @@ -417,7 +420,8 @@ int hdelete_r(const char *key, struct hsearch_data *htab) /* free used ENTRY */ debug("hdelete: DELETING key \"%s\"\n", key); - + if (do_apply && htab->apply != NULL) + htab->apply(ep->key, ep->data, NULL, H_FORCE); free((void *)ep->key); free(ep->data); htab->table[idx].used = -1; @@ -682,7 +686,7 @@ int himport_r(struct hsearch_data *htab, debug("Destroy Hash Table: %p table = %p\n", htab, htab->table); if (htab->table) - hdestroy_r(htab); + hdestroy_r(htab, do_apply); } /* @@ -748,7 +752,7 @@ int himport_r(struct hsearch_data *htab, if (!is_var_in_set(name, nvars, vars)) continue; - if (hdelete_r(name, htab) == 0) + if (hdelete_r(name, htab, do_apply) == 0) debug("DELETE ERROR ##############################\n"); continue; -- cgit v1.1 From b64b7c3df7906342ca8abe8ae31c0c12ced3f401 Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Fri, 24 Aug 2012 00:11:41 +0000 Subject: env: make "env default" selective, check and apply Change the syntax (user API) for "env default": -f: override write-once variables var... : accept individual variable(s) -a: all (resetting the whole env is NOT the default behavior) Enable variable checking and make changes effective by enabling do_apply argument to himport_r(). Signed-off-by: Gerlando Falauto --- common/cmd_nvedit.c | 40 ++++++++++++++++++++++++++++++++++------ common/env_common.c | 28 +++++++++++++++++++++++++++- include/environment.h | 3 +++ 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 310ca16..3474bc6 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -656,14 +656,41 @@ int envmatch(uchar *s1, int i2) return -1; } -static int do_env_default(cmd_tbl_t *cmdtp, int flag, +static int do_env_default(cmd_tbl_t *cmdtp, int __flag, int argc, char * const argv[]) { - if (argc != 2 || strcmp(argv[1], "-f") != 0) - return CMD_RET_USAGE; + int all = 0, flag = 0; - set_default_env("## Resetting to default environment\n"); - return 0; + debug("Initial value for argc=%d\n", argc); + while (--argc > 0 && **++argv == '-') { + char *arg = *argv; + + while (*++arg) { + switch (*arg) { + case 'a': /* default all */ + all = 1; + break; + case 'f': /* force */ + flag |= H_FORCE; + break; + default: + return cmd_usage(cmdtp); + } + } + } + debug("Final value for argc=%d\n", argc); + if (all && (argc == 0)) { + /* Reset the whole environment */ + set_default_env("## Resetting to default environment\n"); + return 0; + } + if (!all && (argc > 0)) { + /* Reset individual variables */ + set_default_vars(argc, argv); + return 0; + } + + return cmd_usage(cmdtp); } static int do_env_delete(cmd_tbl_t *cmdtp, int flag, @@ -994,7 +1021,8 @@ U_BOOT_CMD( #if defined(CONFIG_CMD_ASKENV) "ask name [message] [size] - ask for environment variable\nenv " #endif - "default -f - reset default environment\n" + "default [-f] -a - [forcibly] reset default environment\n" + "env default [-f] var [...] - [forcibly] reset variable(s) to their default values\n" #if defined(CONFIG_CMD_EDITENV) "env edit name - edit environment variable\n" #endif diff --git a/common/env_common.c b/common/env_common.c index b9865bf..3e46c26 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -180,6 +180,11 @@ const uchar *env_get_addr(int index) void set_default_env(const char *s) { + /* + * By default, do not apply changes as they will eventually + * be applied by someone else + */ + int do_apply = 0; if (sizeof(default_environment) > ENV_SIZE) { puts("*** Error - default environment is too large\n\n"); return; @@ -191,6 +196,14 @@ void set_default_env(const char *s) "using default environment\n\n", s + 1); } else { + /* + * This set_to_default was explicitly asked for + * by the user, as opposed to being a recovery + * mechanism. Therefore we check every single + * variable and apply changes to the system + * right away (e.g. baudrate, console). + */ + do_apply = 1; puts(s); } } else { @@ -199,12 +212,25 @@ void set_default_env(const char *s) if (himport_r(&env_htab, (char *)default_environment, sizeof(default_environment), '\0', 0, - 0, NULL, 0 /* do_apply */) == 0) + 0, NULL, do_apply) == 0) error("Environment import failed: errno = %d\n", errno); gd->flags |= GD_FLG_ENV_READY; } + +/* [re]set individual variables to their value in the default environment */ +int set_default_vars(int nvars, char * const vars[]) +{ + /* + * Special use-case: import from default environment + * (and use \0 as a separator) + */ + return himport_r(&env_htab, (const char *)default_environment, + sizeof(default_environment), '\0', H_NOCLEAR, + nvars, vars, 1 /* do_apply */); +} + /* * Check if CRC is valid and (if yes) import the environment. * Note that "buf" may or may not be aligned. diff --git a/include/environment.h b/include/environment.h index 90fb130..e8ab703 100644 --- a/include/environment.h +++ b/include/environment.h @@ -181,6 +181,9 @@ void env_crc_update(void); /* [re]set to the default environment */ void set_default_env(const char *s); +/* [re]set individual variables to their value in the default environment */ +int set_default_vars(int nvars, char * const vars[]); + /* Import from binary representation into hash table */ int env_import(const char *buf, int check); -- cgit v1.1 From d5370febbcbcee3f554df13ed72b7e2b91e5f66c Mon Sep 17 00:00:00 2001 From: Gerlando Falauto Date: Sun, 26 Aug 2012 21:53:00 +0000 Subject: env: delete selected vars not present in imported env When variables explicitly specified on the command line are not present in the imported env, delete them from the running env. If the variable is also missing from the running env, issue a warning. Signed-off-by: Gerlando Falauto Reviewed-by: Marek Vasut --- lib/hashtable.c | 50 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/lib/hashtable.c b/lib/hashtable.c index f3f47de..670a704 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -607,22 +607,32 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, * himport() */ -/* Check whether variable name is amongst vars[] */ -static int is_var_in_set(const char *name, int nvars, char * const vars[]) +/* + * Check whether variable 'name' is amongst vars[], + * and remove all instances by setting the pointer to NULL + */ +static int drop_var_from_set(const char *name, int nvars, char * vars[]) { int i = 0; + int res = 0; /* No variables specified means process all of them */ if (nvars == 0) return 1; for (i = 0; i < nvars; i++) { - if (!strcmp(name, vars[i])) - return 1; + if (vars[i] == NULL) + continue; + /* If we found it, delete all of them */ + if (!strcmp(name, vars[i])) { + vars[i] = NULL; + res = 1; + } } - debug("Skipping non-listed variable %s\n", name); + if (!res) + debug("Skipping non-listed variable %s\n", name); - return 0; + return res; } /* @@ -665,6 +675,8 @@ int himport_r(struct hsearch_data *htab, int nvars, char * const vars[], int do_apply) { char *data, *sp, *dp, *name, *value; + char *localvars[nvars]; + int i; /* Test for correct arguments. */ if (htab == NULL) { @@ -681,6 +693,10 @@ int himport_r(struct hsearch_data *htab, memcpy(data, env, size); dp = data; + /* make a local copy of the list of variables */ + if (nvars) + memcpy(localvars, vars, sizeof(vars[0]) * nvars); + if ((flag & H_NOCLEAR) == 0) { /* Destroy old hash table if one exists */ debug("Destroy Hash Table: %p table = %p\n", htab, @@ -749,7 +765,7 @@ int himport_r(struct hsearch_data *htab, *dp++ = '\0'; /* terminate name */ debug("DELETE CANDIDATE: \"%s\"\n", name); - if (!is_var_in_set(name, nvars, vars)) + if (!drop_var_from_set(name, nvars, localvars)) continue; if (hdelete_r(name, htab, do_apply) == 0) @@ -769,7 +785,7 @@ int himport_r(struct hsearch_data *htab, ++dp; /* Skip variables which are not supposed to be processed */ - if (!is_var_in_set(name, nvars, vars)) + if (!drop_var_from_set(name, nvars, localvars)) continue; /* enter into hash table */ @@ -809,6 +825,24 @@ int himport_r(struct hsearch_data *htab, debug("INSERT: free(data = %p)\n", data); free(data); + /* process variables which were not considered */ + for (i = 0; i < nvars; i++) { + if (localvars[i] == NULL) + continue; + /* + * All variables which were not deleted from the variable list + * were not present in the imported env + * This could mean two things: + * a) if the variable was present in current env, we delete it + * b) if the variable was not present in current env, we notify + * it might be a typo + */ + if (hdelete_r(localvars[i], htab, do_apply) == 0) + printf("WARNING: '%s' neither in running nor in imported env!\n", localvars[i]); + else + printf("WARNING: '%s' not in imported env, deleting it!\n", localvars[i]); + } + debug("INSERT: done\n"); return 1; /* everything OK */ } -- cgit v1.1 From 7ee46cebcbee82e3522b84a82041e4aa86760e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 20 Jul 2012 03:20:29 +0000 Subject: FAT: Fix file contents listed as directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With: fatls mmc 0 /dir/file dir: regular directory file: regular file The previous code read the contents of file as if it were directory entries to list. This patch refuses to list file contents as if it were a folder. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk --- fs/fat/fat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index f7bb1da..19f6a8c 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -1109,11 +1109,11 @@ rootdir_done: goto exit; } - if (idx >= 0) { - if (!(dentptr->attr & ATTR_DIR)) - goto exit; + if (isdir && !(dentptr->attr & ATTR_DIR)) + goto exit; + + if (idx >= 0) subname = nextname; - } } ret = get_contents(mydata, dentptr, buffer, maxsize); -- cgit v1.1 From f138ca1373d7ec9fca33ae21f1b5ff3898fd493f Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Wed, 12 Sep 2012 14:17:31 -0700 Subject: mpc8xxx_spi: fix SPI support on MPC8308RDB The MPC8308RDB Reference Manual states that no bits in the SPMODE register are allowed to change while the enable (EN) bit is set. This driver changes the character length bits (LEN) while the enable (EN) bit is set. Clearing the EN bit while changing the LEN bits makes the driver work correctly on MPC8308RDB. Signed-off-by: Ira W. Snyder Signed-off-by: Kim Phillips --- drivers/spi/mpc8xxx_spi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/spi/mpc8xxx_spi.c b/drivers/spi/mpc8xxx_spi.c index 44ab39d..4e46041 100644 --- a/drivers/spi/mpc8xxx_spi.c +++ b/drivers/spi/mpc8xxx_spi.c @@ -124,6 +124,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, * len > 16 0 */ + spi->mode &= ~SPI_MODE_EN; + if (bitlen <= 16) { if (bitlen <= 4) spi->mode = (spi->mode & 0xff0fffff) | @@ -138,6 +140,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, dout += 4; } + spi->mode |= SPI_MODE_EN; + spi->tx = tmpdout; /* Write the data out */ debug("*** spi_xfer: ... %08x written\n", tmpdout); -- cgit v1.1 From ea1ea54e35e64386cc9eefbf0d96091430a7482a Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Wed, 12 Sep 2012 14:17:32 -0700 Subject: mpc8308rdb: add support for Spansion SPI flash on header J8 The SPI pins are routed to header J8 for testing SPI functionality. A Spansion flash has been wired up and tested on this header. This patch breaks support for the second TSEC interface, since the GPIO pin used as a chip select is pinmuxed with some of the TSEC pins. Signed-off-by: Ira W. Snyder Signed-off-by: Kim Phillips --- board/freescale/mpc8308rdb/mpc8308rdb.c | 49 +++++++++++++++++++++++++++++++++ include/configs/MPC8308RDB.h | 13 +++++++++ 2 files changed, 62 insertions(+) diff --git a/board/freescale/mpc8308rdb/mpc8308rdb.c b/board/freescale/mpc8308rdb/mpc8308rdb.c index 5c54357..b97cdc1 100644 --- a/board/freescale/mpc8308rdb/mpc8308rdb.c +++ b/board/freescale/mpc8308rdb/mpc8308rdb.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,35 @@ DECLARE_GLOBAL_DATA_PTR; +/* + * The following are used to control the SPI chip selects for the SPI command. + */ +#ifdef CONFIG_MPC8XXX_SPI + +#define SPI_CS_MASK 0x00400000 + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return bus == 0 && cs == 0; +} + +void spi_cs_activate(struct spi_slave *slave) +{ + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + + /* active low */ + clrbits_be32(&immr->gpio[0].dat, SPI_CS_MASK); +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + + /* inactive high */ + setbits_be32(&immr->gpio[0].dat, SPI_CS_MASK); +} +#endif /* CONFIG_MPC8XXX_SPI */ + static u8 read_board_info(void) { u8 val8; @@ -109,6 +139,25 @@ void pci_init_board(void) */ int misc_init_r(void) { +#ifdef CONFIG_MPC8XXX_SPI + immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + sysconf83xx_t *sysconf = &immr->sysconf; + + /* + * Set proper bits in SICRH to allow SPI on header J8 + * + * NOTE: this breaks the TSEC2 interface, attached to the Vitesse + * switch. The pinmux configuration does not have a fine enough + * granularity to support both simultaneously. + */ + clrsetbits_be32(&sysconf->sicrh, SICRH_GPIO_A_TSEC2, SICRH_GPIO_A_GPIO); + puts("WARNING: SPI enabled, TSEC2 support is broken\n"); + + /* Set header J8 SPI chip select output, disabled */ + setbits_be32(&immr->gpio[0].dir, SPI_CS_MASK); + setbits_be32(&immr->gpio[0].dat, SPI_CS_MASK); +#endif + #ifdef CONFIG_VSC7385_IMAGE if (vsc7385_upload_firmware((void *) CONFIG_VSC7385_IMAGE, CONFIG_VSC7385_IMAGE_SIZE)) { diff --git a/include/configs/MPC8308RDB.h b/include/configs/MPC8308RDB.h index 7f2761c..a24538a 100644 --- a/include/configs/MPC8308RDB.h +++ b/include/configs/MPC8308RDB.h @@ -340,6 +340,19 @@ #define CONFIG_SYS_I2C_OFFSET 0x3000 #define CONFIG_SYS_I2C2_OFFSET 0x3100 +/* + * SPI on header J8 + * + * WARNING: enabling this will break TSEC2 (connected to the Vitesse switch) + * due to a pinmux conflict between GPIO9 (SPI chip select )and the TSEC2 pins. + */ +#ifdef CONFIG_MPC8XXX_SPI +#define CONFIG_CMD_SPI +#define CONFIG_USE_SPIFLASH +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_SPANSION +#define CONFIG_CMD_SF +#endif /* * Board info - revision and where boot from -- cgit v1.1 From 40775e9676f23adddc4aa47d8281d4a4b22f4c17 Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Wed, 12 Sep 2012 14:17:34 -0700 Subject: mpc8308rdb: add support for FIT images This is very useful on a modern system. Signed-off-by: Ira W. Snyder Signed-off-by: Kim Phillips --- include/configs/MPC8308RDB.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/configs/MPC8308RDB.h b/include/configs/MPC8308RDB.h index a24538a..c65635f 100644 --- a/include/configs/MPC8308RDB.h +++ b/include/configs/MPC8308RDB.h @@ -37,6 +37,10 @@ #define CONFIG_MISC_INIT_R +/* new uImage format support */ +#define CONFIG_FIT 1 +#define CONFIG_FIT_VERBOSE 1 + /* * On-board devices * -- cgit v1.1 From db1fc7d28e8947c402149ded4597970fdb3e5571 Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Wed, 12 Sep 2012 14:17:35 -0700 Subject: mpc8308rdb: add support for eSDHC MMC controller Add support for the onboard eSDHC MMC controller. The hardware on the MPC8308RDB has the following errata: - ESDHC111: manual asynchronous CMD12 is broken - DMA is broken (PIO works) Signed-off-by: Ira W. Snyder [added include fsl_esdhc header to prevent implicit declarations of fsl_esdhc_mmc_init() and fdt_fixup_esdhc()] Signed-off-by: Kim Phillips --- board/freescale/mpc8308rdb/mpc8308rdb.c | 9 +++++++++ include/configs/MPC8308RDB.h | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/board/freescale/mpc8308rdb/mpc8308rdb.c b/board/freescale/mpc8308rdb/mpc8308rdb.c index b97cdc1..7e3fa1a 100644 --- a/board/freescale/mpc8308rdb/mpc8308rdb.c +++ b/board/freescale/mpc8308rdb/mpc8308rdb.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,13 @@ void spi_cs_deactivate(struct spi_slave *slave) } #endif /* CONFIG_MPC8XXX_SPI */ +#ifdef CONFIG_FSL_ESDHC +int board_mmc_init(bd_t *bd) +{ + return fsl_esdhc_mmc_init(bd); +} +#endif + static u8 read_board_info(void) { u8 val8; @@ -173,6 +181,7 @@ void ft_board_setup(void *blob, bd_t *bd) { ft_cpu_setup(blob, bd); fdt_fixup_dr_usb(blob, bd); + fdt_fixup_esdhc(blob, bd); } #endif diff --git a/include/configs/MPC8308RDB.h b/include/configs/MPC8308RDB.h index c65635f..2d48dde 100644 --- a/include/configs/MPC8308RDB.h +++ b/include/configs/MPC8308RDB.h @@ -41,6 +41,20 @@ #define CONFIG_FIT 1 #define CONFIG_FIT_VERBOSE 1 +#define CONFIG_MMC 1 + +#ifdef CONFIG_MMC +#define CONFIG_FSL_ESDHC +#define CONFIG_SYS_FSL_ESDHC_ADDR CONFIG_SYS_MPC83xx_ESDHC_ADDR +#define CONFIG_SYS_FSL_ERRATUM_ESDHC111 +#define CONFIG_SYS_FSL_ESDHC_USE_PIO + +#define CONFIG_CMD_MMC +#define CONFIG_GENERIC_MMC +#define CONFIG_CMD_FAT +#define CONFIG_DOS_PARTITION +#endif + /* * On-board devices * -- cgit v1.1 From 2ee03c6e23237a29729b27457f69b22b2d7d4fe1 Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Sun, 25 Mar 2012 19:18:14 +0000 Subject: ColdFire: Rename NANDFLASH_SIZE into CONFIG_NANDFLASH_SIZE for MCF537x This patch fixes the build error for MCF537x. As the NANDFLASH_SIZE is redefined in boards.cfg, it is needed to rename NANDFLASH_SIZE into CONFIG_NANDFLASH_SIZE in include/configs/M5373EVB.h. Signed-off-by: Alison Wang --- include/configs/M5373EVB.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/configs/M5373EVB.h b/include/configs/M5373EVB.h index 0d09f0e..45d1064 100644 --- a/include/configs/M5373EVB.h +++ b/include/configs/M5373EVB.h @@ -1,7 +1,7 @@ /* * Configuation settings for the Freescale MCF5373 FireEngine board. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -59,7 +59,7 @@ #define CONFIG_CMD_PING #define CONFIG_CMD_REGINFO -#ifdef NANDFLASH_SIZE +#ifdef CONFIG_NANDFLASH_SIZE # define CONFIG_CMD_NAND #endif @@ -208,7 +208,7 @@ # define CONFIG_SYS_FLASH_PROTECTION /* "Real" (hardware) sectors protection */ #endif -#ifdef NANDFLASH_SIZE +#ifdef CONFIG_NANDFLASH_SIZE # define CONFIG_SYS_MAX_NAND_DEVICE 1 # define CONFIG_SYS_NAND_BASE CONFIG_SYS_CS2_BASE # define CONFIG_SYS_NAND_SIZE 1 @@ -264,9 +264,9 @@ #define CONFIG_SYS_CS1_MASK 0x001f0001 #define CONFIG_SYS_CS1_CTRL 0x002A3780 -#ifdef NANDFLASH_SIZE +#ifdef CONFIG_NANDFLASH_SIZE #define CONFIG_SYS_CS2_BASE 0x20000000 -#define CONFIG_SYS_CS2_MASK ((NANDFLASH_SIZE << 20) | 1) +#define CONFIG_SYS_CS2_MASK ((CONFIG_NANDFLASH_SIZE << 20) | 1) #define CONFIG_SYS_CS2_CTRL 0x00001f60 #endif -- cgit v1.1 From f7799a1175d1538ddaabc49fbd30660a926bb32f Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Sun, 25 Mar 2012 19:18:49 +0000 Subject: ColdFire: Update the bitops for ColdFire platform This patch uses the general ffs definition to replace the platform ffs definition. This patch also fixes the build error by adding hweightN definition for m5329evb and m5373evb. Signed-off-by: Jason Jin Signed-off-by: Alison Wang --- arch/m68k/include/asm/bitops.h | 59 +++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/arch/m68k/include/asm/bitops.h b/arch/m68k/include/asm/bitops.h index ad971b4..525d90c 100644 --- a/arch/m68k/include/asm/bitops.h +++ b/arch/m68k/include/asm/bitops.h @@ -17,41 +17,36 @@ extern int test_and_change_bit(int nr, volatile void *addr); #ifdef __KERNEL__ -/* - * ffs: find first bit set. This is defined the same way as - * the libc and compiler builtin ffs routines, therefore - * differs in spirit from the above ffz (man ffs). - */ -extern __inline__ int ffs(int x) + +extern inline int test_bit(int nr, __const__ volatile void *addr) { - int r = 1; - - if (!x) - return 0; - if (!(x & 0xffff)) { - x >>= 16; - r += 16; - } - if (!(x & 0xff)) { - x >>= 8; - r += 8; - } - if (!(x & 0xf)) { - x >>= 4; - r += 4; - } - if (!(x & 3)) { - x >>= 2; - r += 2; - } - if (!(x & 1)) { - x >>= 1; - r += 1; - } - return r; + __const__ unsigned int *p = (__const__ unsigned int *) addr; + + return (p[nr >> 5] & (1UL << (nr & 31))) != 0; } + +extern inline int test_and_set_bit(int nr, volatile void *vaddr) +{ + char retval; + + volatile char *p = &((volatile char *)vaddr)[(nr^31) >> 3]; + __asm__ __volatile__ ("bset %2,(%4); sne %0" + : "=d" (retval), "=m" (*p) + : "di" (nr & 7), "m" (*p), "a" (p)); + + return retval; +} + #define __ffs(x) (ffs(x) - 1) -#define PLATFORM_FFS + +/* + * * hweightN: returns the hamming weight (i.e. the number + * * of bits set) of a N-bit word + * */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) #endif /* __KERNEL__ */ -- cgit v1.1 From 33d4411931423a0524b968e44e068ac6c38e23e0 Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Mon, 26 Mar 2012 21:49:02 +0000 Subject: ColdFire: Add clear and set bits macros for ColdFire platform Signed-off-by: Alison Wang --- arch/m68k/include/asm/io.h | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/arch/m68k/include/asm/io.h b/arch/m68k/include/asm/io.h index d86eaf9..50ed749 100644 --- a/arch/m68k/include/asm/io.h +++ b/arch/m68k/include/asm/io.h @@ -1,7 +1,7 @@ /* * IO header file * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -225,6 +225,42 @@ extern inline void out_be32(volatile unsigned *addr, int val) *addr = val; } +/* Clear and set bits in one shot. These macros can be used to clear and + * set multiple bits in a register using a single call. These macros can + * also be used to set a multiple-bit bit pattern using a mask, by + * specifying the mask in the 'clear' parameter and the new bit pattern + * in the 'set' parameter. + */ + +#define clrbits(type, addr, clear) \ + out_##type((addr), in_##type(addr) & ~(clear)) + +#define setbits(type, addr, set) \ + out_##type((addr), in_##type(addr) | (set)) + +#define clrsetbits(type, addr, clear, set) \ + out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) + +#define clrbits_be32(addr, clear) clrbits(be32, addr, clear) +#define setbits_be32(addr, set) setbits(be32, addr, set) +#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) + +#define clrbits_le32(addr, clear) clrbits(le32, addr, clear) +#define setbits_le32(addr, set) setbits(le32, addr, set) +#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) + +#define clrbits_be16(addr, clear) clrbits(be16, addr, clear) +#define setbits_be16(addr, set) setbits(be16, addr, set) +#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) + +#define clrbits_le16(addr, clear) clrbits(le16, addr, clear) +#define setbits_le16(addr, set) setbits(le16, addr, set) +#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) + +#define clrbits_8(addr, clear) clrbits(8, addr, clear) +#define setbits_8(addr, set) setbits(8, addr, set) +#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) + static inline void sync(void) { /* This sync function is for PowerPC or other architecture instruction -- cgit v1.1 From 849fc424713d176f90af0b05f6161bc3803ca887 Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Mon, 26 Mar 2012 21:49:03 +0000 Subject: ColdFire: Clean up checkpatch warnings for MCF5227x Signed-off-by: Alison Wang --- arch/m68k/cpu/mcf5227x/cpu.c | 13 ++-- arch/m68k/cpu/mcf5227x/cpu_init.c | 140 +++++++++++++++++----------------- arch/m68k/cpu/mcf5227x/interrupts.c | 15 ++-- arch/m68k/cpu/mcf5227x/speed.c | 40 +++++----- board/freescale/m52277evb/m52277evb.c | 30 ++++---- 5 files changed, 123 insertions(+), 115 deletions(-) diff --git a/arch/m68k/cpu/mcf5227x/cpu.c b/arch/m68k/cpu/mcf5227x/cpu.c index 09ef1d2..3a0ab97 100644 --- a/arch/m68k/cpu/mcf5227x/cpu.c +++ b/arch/m68k/cpu/mcf5227x/cpu.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -30,14 +30,15 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM); + rcm_t *rcm = (rcm_t *) (MMAP_RCM); udelay(1000); - rcm->rcr |= RCM_RCR_SOFTRST; + setbits_8(&rcm->rcr, RCM_RCR_SOFTRST); /* we don't return! */ return 0; @@ -45,14 +46,14 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int checkcpu(void) { - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; u16 msk; u16 id = 0; u8 ver; puts("CPU: "); - msk = (ccm->cir >> 6); - ver = (ccm->cir & 0x003f); + msk = (in_be16(&ccm->cir) >> 6); + ver = (in_be16(&ccm->cir) & 0x003f); switch (msk) { case 0x6c: id = 52277; diff --git a/arch/m68k/cpu/mcf5227x/cpu_init.c b/arch/m68k/cpu/mcf5227x/cpu_init.c index beb78f5..e23b20d 100644 --- a/arch/m68k/cpu/mcf5227x/cpu_init.c +++ b/arch/m68k/cpu/mcf5227x/cpu_init.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2004-2007 Freescale Semiconductor, Inc. + * (C) Copyright 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -29,6 +29,7 @@ #include #include +#include #include /* @@ -40,70 +41,70 @@ */ void cpu_init_f(void) { - volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + pll_t *pll = (pll_t *)MMAP_PLL; #if !defined(CONFIG_CF_SBF) /* Workaround, must place before fbcs */ - pll->psr = 0x12; - - scm1->mpr = 0x77777777; - scm1->pacra = 0; - scm1->pacrb = 0; - scm1->pacrc = 0; - scm1->pacrd = 0; - scm1->pacre = 0; - scm1->pacrf = 0; - scm1->pacrg = 0; - scm1->pacri = 0; + out_be32(&pll->psr, 0x12); + + out_be32(&scm1->mpr, 0x77777777); + out_be32(&scm1->pacra, 0); + out_be32(&scm1->pacrb, 0); + out_be32(&scm1->pacrc, 0); + out_be32(&scm1->pacrd, 0); + out_be32(&scm1->pacre, 0); + out_be32(&scm1->pacrf, 0); + out_be32(&scm1->pacrg, 0); + out_be32(&scm1->pacri, 0); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #endif /* CONFIG_CF_SBF */ #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ && defined(CONFIG_SYS_CS1_CTRL)) - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ && defined(CONFIG_SYS_CS2_CTRL)) - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ && defined(CONFIG_SYS_CS3_CTRL)) - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ && defined(CONFIG_SYS_CS4_CTRL)) - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ && defined(CONFIG_SYS_CS5_CTRL)) - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #ifdef CONFIG_FSL_I2C - gpio->par_i2c = GPIO_PAR_I2C_SCL_SCL | GPIO_PAR_I2C_SDA_SDA; + out_8(&gpio->par_i2c, GPIO_PAR_I2C_SCL_SCL | GPIO_PAR_I2C_SDA_SDA); #endif icache_enable(); @@ -115,11 +116,11 @@ void cpu_init_f(void) int cpu_init_r(void) { #ifdef CONFIG_MCFRTC - volatile rtc_t *rtc = (volatile rtc_t *)(CONFIG_SYS_MCFRTC_BASE); - volatile rtcex_t *rtcex = (volatile rtcex_t *)&rtc->extended; + rtc_t *rtc = (rtc_t *)(CONFIG_SYS_MCFRTC_BASE); + rtcex_t *rtcex = (rtcex_t *)&rtc->extended; - rtcex->gocu = (CONFIG_SYS_RTC_OSCILLATOR >> 16) & 0xFFFF; - rtcex->gocl = CONFIG_SYS_RTC_OSCILLATOR & 0xFFFF; + out_be32(&rtcex->gocu, (CONFIG_SYS_RTC_OSCILLATOR >> 16) & 0xffff); + out_be32(&rtcex->gocl, CONFIG_SYS_RTC_OSCILLATOR & 0xffff); #endif return (0); @@ -127,27 +128,27 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= - (GPIO_PAR_UART_U0TXD_UNMASK & GPIO_PAR_UART_U0RXD_UNMASK); - gpio->par_uart |= - (GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); + clrbits_be16(&gpio->par_uart, + ~(GPIO_PAR_UART_U0TXD_UNMASK & GPIO_PAR_UART_U0RXD_UNMASK)); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); break; case 1: - gpio->par_uart &= - (GPIO_PAR_UART_U1TXD_UNMASK & GPIO_PAR_UART_U1RXD_UNMASK); - gpio->par_uart |= - (GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); + clrbits_be16(&gpio->par_uart, + ~(GPIO_PAR_UART_U1TXD_UNMASK & GPIO_PAR_UART_U1RXD_UNMASK)); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); break; case 2: - gpio->par_dspi &= - (GPIO_PAR_DSPI_SIN_UNMASK & GPIO_PAR_DSPI_SOUT_UNMASK); - gpio->par_dspi = - (GPIO_PAR_DSPI_SIN_U2RXD | GPIO_PAR_DSPI_SOUT_U2TXD); + clrbits_8(&gpio->par_dspi, + ~(GPIO_PAR_DSPI_SIN_UNMASK & GPIO_PAR_DSPI_SOUT_UNMASK)); + out_8(&gpio->par_dspi, + GPIO_PAR_DSPI_SIN_U2RXD | GPIO_PAR_DSPI_SOUT_U2TXD); break; } } @@ -155,32 +156,32 @@ void uart_port_conf(int port) #ifdef CONFIG_CF_DSPI void cfspi_port_conf(void) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - gpio->par_dspi = - GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT | - GPIO_PAR_DSPI_SCK_SCK; + out_8(&gpio->par_dspi, + GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT | + GPIO_PAR_DSPI_SCK_SCK); } int cfspi_claim_bus(uint bus, uint cs) { - volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + dspi_t *dspi = (dspi_t *) MMAP_DSPI; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - if ((dspi->sr & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) + if ((in_be32(&dspi->sr) & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) return -1; /* Clear FIFO and resume transfer */ - dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); + clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF); switch (cs) { case 0: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_UNMASK; - gpio->par_dspi |= GPIO_PAR_DSPI_PCS0_PCS0; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_UNMASK); + setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0); break; case 2: - gpio->par_timer &= GPIO_PAR_TIMER_T2IN_UNMASK; - gpio->par_timer |= GPIO_PAR_TIMER_T2IN_DSPIPCS2; + clrbits_8(&gpio->par_timer, ~GPIO_PAR_TIMER_T2IN_UNMASK); + setbits_8(&gpio->par_timer, GPIO_PAR_TIMER_T2IN_DSPIPCS2); break; } @@ -189,17 +190,18 @@ int cfspi_claim_bus(uint bus, uint cs) void cfspi_release_bus(uint bus, uint cs) { - volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + dspi_t *dspi = (dspi_t *) MMAP_DSPI; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); /* Clear FIFO */ + /* Clear FIFO */ + clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF); switch (cs) { case 0: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0); break; case 2: - gpio->par_timer &= GPIO_PAR_TIMER_T2IN_UNMASK; + clrbits_8(&gpio->par_timer, ~GPIO_PAR_TIMER_T2IN_UNMASK); break; } } diff --git a/arch/m68k/cpu/mcf5227x/interrupts.c b/arch/m68k/cpu/mcf5227x/interrupts.c index 85828a6..a2cf519 100644 --- a/arch/m68k/cpu/mcf5227x/interrupts.c +++ b/arch/m68k/cpu/mcf5227x/interrupts.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,14 +28,15 @@ /* CPU specific interrupt routine */ #include #include +#include int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ - intp->imrh0 |= 0xFFFFFFFF; - intp->imrl0 |= 0xFFFFFFFF; + setbits_be32(&intp->imrh0, 0xffffffff); + setbits_be32(&intp->imrl0, 0xffffffff); enable_interrupts(); return 0; @@ -44,9 +45,9 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrh0, CONFIG_SYS_TMRINTR_MASK); } #endif diff --git a/arch/m68k/cpu/mcf5227x/speed.c b/arch/m68k/cpu/mcf5227x/speed.c index 7e385d3..b94a9ed 100644 --- a/arch/m68k/cpu/mcf5227x/speed.c +++ b/arch/m68k/cpu/mcf5227x/speed.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -26,6 +26,7 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -44,7 +45,7 @@ DECLARE_GLOBAL_DATA_PTR; void clock_enter_limp(int lpdiv) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; + ccm_t *ccm = (ccm_t *)MMAP_CCM; int i, j; /* Check bounds of divider */ @@ -57,10 +58,10 @@ void clock_enter_limp(int lpdiv) for (i = 0, j = lpdiv; j != 1; j >>= 1, i++) ; /* Apply the divider to the system clock */ - ccm->cdr = (ccm->cdr & 0xF0FF) | CCM_CDR_LPDIV(i); + clrsetbits_be16(&ccm->cdr, 0x0f00, CCM_CDR_LPDIV(i)); /* Enable Limp Mode */ - ccm->misccr |= CCM_MISCCR_LIMP; + setbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); } /* @@ -69,14 +70,15 @@ void clock_enter_limp(int lpdiv) */ void clock_exit_limp(void) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; - volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + ccm_t *ccm = (ccm_t *)MMAP_CCM; + pll_t *pll = (pll_t *)MMAP_PLL; /* Exit Limp mode */ - ccm->misccr &= ~CCM_MISCCR_LIMP; + clrbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); /* Wait for the PLL to lock */ - while (!(pll->psr & PLL_PSR_LOCK)) ; + while (!(in_be32(&pll->psr) & PLL_PSR_LOCK)) + ; } /* @@ -85,12 +87,12 @@ void clock_exit_limp(void) int get_clocks(void) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; - volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + ccm_t *ccm = (ccm_t *)MMAP_CCM; + pll_t *pll = (pll_t *)MMAP_PLL; int vco, temp, pcrvalue, pfdr; u8 bootmode; - pcrvalue = pll->pcr & 0xFF0F0FFF; + pcrvalue = in_be32(&pll->pcr) & 0xFF0F0FFF; pfdr = pcrvalue >> 24; if (pfdr == 0x1E) @@ -102,32 +104,32 @@ int get_clocks(void) if (bootmode == 0) { /* Normal mode */ - vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; if ((vco < CLOCK_PLL_FVCO_MIN) || (vco > CLOCK_PLL_FVCO_MAX)) { /* Default value */ - pcrvalue = (pll->pcr & 0x00FFFFFF); + pcrvalue = (in_be32(&pll->pcr) & 0x00FFFFFF); pcrvalue |= 0x1E << 24; - pll->pcr = pcrvalue; + out_be32(&pll->pcr, pcrvalue); vco = - ((pll->pcr & 0xFF000000) >> 24) * + ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; } gd->vco_clk = vco; /* Vco clock */ } else if (bootmode == 3) { /* serial mode */ - vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; gd->vco_clk = vco; /* Vco clock */ } - if ((ccm->ccr & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { + if ((in_be16(&ccm->ccr) & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { /* Limp mode */ } else { gd->inp_clk = CONFIG_SYS_INPUT_CLKSRC; /* Input clock */ - temp = (pll->pcr & PLL_PCR_OUTDIV1_MASK) + 1; + temp = (in_be32(&pll->pcr) & PLL_PCR_OUTDIV1_MASK) + 1; gd->cpu_clk = vco / temp; /* cpu clock */ - temp = ((pll->pcr & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; + temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; gd->flb_clk = vco / temp; /* flexbus clock */ gd->bus_clk = gd->flb_clk; } diff --git a/board/freescale/m52277evb/m52277evb.c b/board/freescale/m52277evb/m52277evb.c index 9109edb..a9bec58 100644 --- a/board/freescale/m52277evb/m52277evb.c +++ b/board/freescale/m52277evb/m52277evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -26,6 +26,7 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -47,8 +48,8 @@ phys_size_t initdram(int board_type) */ dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; #else - volatile sdramc_t *sdram = (volatile sdramc_t *)(MMAP_SDRAM); - volatile gpio_t *gpio = (volatile gpio_t *)(MMAP_GPIO); + sdramc_t *sdram = (sdramc_t *)(MMAP_SDRAM); + gpio_t *gpio = (gpio_t *)(MMAP_GPIO); u32 i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; @@ -59,36 +60,37 @@ phys_size_t initdram(int board_type) } i--; - gpio->mscr_sdram = CONFIG_SYS_SDRAM_DRV_STRENGTH; + out_8(&gpio->mscr_sdram, CONFIG_SYS_SDRAM_DRV_STRENGTH); - sdram->sdcs0 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->sdcs0, CONFIG_SYS_SDRAM_BASE | i); - sdram->sdcfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->sdcfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->sdcfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->sdcfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 2); __asm__("nop"); /* Issue LEMR */ - sdram->sdmr = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_MODE); __asm__("nop"); - sdram->sdmr = CONFIG_SYS_SDRAM_EMOD; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_EMOD); __asm__("nop"); udelay(1000); /* Issue PALL */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 2); __asm__("nop"); /* Perform two refresh cycles */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); __asm__("nop"); - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); __asm__("nop"); - sdram->sdcr = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000C00; + out_be32(&sdram->sdcr, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00); udelay(100); #endif -- cgit v1.1 From 32dbaafa5a1fda97dbf99e6627309e7570dc14ca Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Mon, 26 Mar 2012 21:49:04 +0000 Subject: ColdFire: Clean up checkpatch warnings for MCF52x2 Signed-off-by: Alison Wang --- arch/m68k/cpu/mcf52x2/cpu.c | 115 +++++++++------- arch/m68k/cpu/mcf52x2/cpu_init.c | 252 +++++++++++++++++----------------- arch/m68k/cpu/mcf52x2/interrupts.c | 40 +++--- arch/m68k/cpu/mcf52x2/speed.c | 19 +-- board/freescale/m5208evbe/m5208evbe.c | 28 ++-- board/freescale/m5253demo/m5253demo.c | 29 ++-- board/freescale/m5253evbe/m5253evbe.c | 30 ++-- board/freescale/m5272c3/m5272c3.c | 9 +- board/freescale/m5275evb/m5275evb.c | 50 +++---- 9 files changed, 310 insertions(+), 262 deletions(-) diff --git a/arch/m68k/cpu/mcf52x2/cpu.c b/arch/m68k/cpu/mcf52x2/cpu.c index 571d078..7c6100c 100644 --- a/arch/m68k/cpu/mcf52x2/cpu.c +++ b/arch/m68k/cpu/mcf52x2/cpu.c @@ -9,6 +9,8 @@ * MCF5275 additions * Copyright (C) 2008 Arthur Shipkowski (art@videon-central.com) * + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * * See file CREDITS for list of people who contributed to this * project. * @@ -32,6 +34,7 @@ #include #include #include +#include #include #include "cpu.h" @@ -40,11 +43,11 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_M5208 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile rcm_t *rcm = (rcm_t *)(MMAP_RCM); + rcm_t *rcm = (rcm_t *)(MMAP_RCM); udelay(1000); - rcm->rcr = RCM_RCR_SOFTRST; + out_8(&rcm->rcr, RCM_RCR_SOFTRST); /* we don't return! */ return 0; @@ -65,18 +68,21 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void watchdog_reset(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); - wdt->sr = 0x5555; - wdt->sr = 0xAAAA; + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); + + out_be16(&wdt->sr, 0x5555); + out_be16(&wdt->sr, 0xaaaa); } int watchdog_disable(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->sr = 0x5555; /* reset watchdog counter */ - wdt->sr = 0xAAAA; - wdt->cr = 0; /* disable watchdog timer */ + /* reset watchdog counter */ + out_be16(&wdt->sr, 0x5555); + out_be16(&wdt->sr, 0xaaaa); + /* disable watchdog timer */ + out_be16(&wdt->cr, 0); puts("WATCHDOG:disabled\n"); return (0); @@ -84,15 +90,18 @@ int watchdog_disable(void) int watchdog_init(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->cr = 0; /* disable watchdog */ + /* disable watchdog */ + out_be16(&wdt->cr, 0); /* set timeout and enable watchdog */ - wdt->mr = - ((CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000)) - 1; - wdt->sr = 0x5555; /* reset watchdog counter */ - wdt->sr = 0xAAAA; + out_be16(&wdt->mr, + (CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000) - 1); + + /* reset watchdog counter */ + out_be16(&wdt->sr, 0x5555); + out_be16(&wdt->sr, 0xaaaa); puts("WATCHDOG:enabled\n"); return (0); @@ -178,13 +187,13 @@ int watchdog_init(void) #ifdef CONFIG_M5272 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); - wdp->wdog_wrrr = 0; + out_be16(&wdp->wdog_wrrr, 0); udelay(1000); /* enable watchdog, set timeout to 0 and wait */ - wdp->wdog_wrrr = 1; + out_be16(&wdp->wdog_wrrr, 1); while (1) ; /* we don't return! */ @@ -193,12 +202,12 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int checkcpu(void) { - volatile sysctrl_t *sysctrl = (sysctrl_t *) (MMAP_CFG); + sysctrl_t *sysctrl = (sysctrl_t *) (MMAP_CFG); uchar msk; char *suf; puts("CPU: "); - msk = (sysctrl->sc_dir > 28) & 0xf; + msk = (in_be32(&sysctrl->sc_dir) > 28) & 0xf; switch (msk) { case 0x2: suf = "1K75N"; @@ -221,17 +230,21 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void watchdog_reset(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); - wdt->wdog_wcr = 0; + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); + + out_be16(&wdt->wdog_wcr, 0); } int watchdog_disable(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->wdog_wcr = 0; /* reset watchdog counter */ - wdt->wdog_wirr = 0; /* disable watchdog interrupt */ - wdt->wdog_wrrr = 0; /* disable watchdog timer */ + /* reset watchdog counter */ + out_be16(&wdt->wdog_wcr, 0); + /* disable watchdog interrupt */ + out_be16(&wdt->wdog_wirr, 0); + /* disable watchdog timer */ + out_be16(&wdt->wdog_wrrr, 0); puts("WATCHDOG:disabled\n"); return (0); @@ -239,14 +252,17 @@ int watchdog_disable(void) int watchdog_init(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->wdog_wirr = 0; /* disable watchdog interrupt */ + /* disable watchdog interrupt */ + out_be16(&wdt->wdog_wirr, 0); /* set timeout and enable watchdog */ - wdt->wdog_wrrr = - ((CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000)) - 1; - wdt->wdog_wcr = 0; /* reset watchdog counter */ + out_be16(&wdt->wdog_wrrr, + (CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000) - 1); + + /* reset watchdog counter */ + out_be16(&wdt->wdog_wcr, 0); puts("WATCHDOG:enabled\n"); return (0); @@ -258,11 +274,11 @@ int watchdog_init(void) #ifdef CONFIG_M5275 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile rcm_t *rcm = (rcm_t *)(MMAP_RCM); + rcm_t *rcm = (rcm_t *)(MMAP_RCM); udelay(1000); - rcm->rcr = RCM_RCR_SOFTRST; + out_8(&rcm->rcr, RCM_RCR_SOFTRST); /* we don't return! */ return 0; @@ -282,18 +298,22 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void watchdog_reset(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); - wdt->wsr = 0x5555; - wdt->wsr = 0xAAAA; + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); + + out_be16(&wdt->wsr, 0x5555); + out_be16(&wdt->wsr, 0xaaaa); } int watchdog_disable(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->wsr = 0x5555; /* reset watchdog counter */ - wdt->wsr = 0xAAAA; - wdt->wcr = 0; /* disable watchdog timer */ + /* reset watchdog counter */ + out_be16(&wdt->wsr, 0x5555); + out_be16(&wdt->wsr, 0xaaaa); + + /* disable watchdog timer */ + out_be16(&wdt->wcr, 0); puts("WATCHDOG:disabled\n"); return (0); @@ -301,15 +321,18 @@ int watchdog_disable(void) int watchdog_init(void) { - volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG); + wdog_t *wdt = (wdog_t *)(MMAP_WDOG); - wdt->wcr = 0; /* disable watchdog */ + /* disable watchdog */ + out_be16(&wdt->wcr, 0); /* set timeout and enable watchdog */ - wdt->wmr = - ((CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000)) - 1; - wdt->wsr = 0x5555; /* reset watchdog counter */ - wdt->wsr = 0xAAAA; + out_be16(&wdt->wmr, + (CONFIG_WATCHDOG_TIMEOUT * CONFIG_SYS_HZ) / (32768 * 1000) - 1); + + /* reset watchdog counter */ + out_be16(&wdt->wsr, 0x5555); + out_be16(&wdt->wsr, 0xaaaa); puts("WATCHDOG:enabled\n"); return (0); diff --git a/arch/m68k/cpu/mcf52x2/cpu_init.c b/arch/m68k/cpu/mcf52x2/cpu_init.c index a98a926..a221420 100644 --- a/arch/m68k/cpu/mcf52x2/cpu_init.c +++ b/arch/m68k/cpu/mcf52x2/cpu_init.c @@ -8,7 +8,7 @@ * (c) Copyright 2010 * Arcturus Networks Inc. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * Hayden Fraser (Hayden.Fraser@freescale.com) * @@ -37,6 +37,7 @@ #include #include #include +#include #if defined(CONFIG_CMD_NET) #include @@ -48,57 +49,57 @@ /* Only 5272 Flexbus chipselect is different from the rest */ void init_fbcs(void) { - volatile fbcs_t *fbcs = (fbcs_t *) (MMAP_FBCS); + fbcs_t *fbcs = (fbcs_t *) (MMAP_FBCS); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #else #warning "Chip Select 0 are not initialized/used" #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ && defined(CONFIG_SYS_CS1_CTRL)) - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ && defined(CONFIG_SYS_CS2_CTRL)) - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ && defined(CONFIG_SYS_CS3_CTRL)) - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ && defined(CONFIG_SYS_CS4_CTRL)) - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ && defined(CONFIG_SYS_CS5_CTRL)) - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #if (defined(CONFIG_SYS_CS6_BASE) && defined(CONFIG_SYS_CS6_MASK) \ && defined(CONFIG_SYS_CS6_CTRL)) - fbcs->csar6 = CONFIG_SYS_CS6_BASE; - fbcs->cscr6 = CONFIG_SYS_CS6_CTRL; - fbcs->csmr6 = CONFIG_SYS_CS6_MASK; + out_be32(&fbcs->csar6, CONFIG_SYS_CS6_BASE); + out_be32(&fbcs->cscr6, CONFIG_SYS_CS6_CTRL); + out_be32(&fbcs->csmr6, CONFIG_SYS_CS6_MASK); #endif #if (defined(CONFIG_SYS_CS7_BASE) && defined(CONFIG_SYS_CS7_MASK) \ && defined(CONFIG_SYS_CS7_CTRL)) - fbcs->csar7 = CONFIG_SYS_CS7_BASE; - fbcs->cscr7 = CONFIG_SYS_CS7_CTRL; - fbcs->csmr7 = CONFIG_SYS_CS7_MASK; + out_be32(&fbcs->csar7, CONFIG_SYS_CS7_BASE); + out_be32(&fbcs->cscr7, CONFIG_SYS_CS7_CTRL); + out_be32(&fbcs->csmr7, CONFIG_SYS_CS7_MASK); #endif } #endif @@ -106,22 +107,22 @@ void init_fbcs(void) #if defined(CONFIG_M5208) void cpu_init_f(void) { - volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + scm1_t *scm1 = (scm1_t *) MMAP_SCM1; #ifndef CONFIG_WATCHDOG - volatile wdog_t *wdg = (wdog_t *) MMAP_WDOG; + wdog_t *wdg = (wdog_t *) MMAP_WDOG; /* Disable the watchdog if we aren't using it */ - wdg->cr = 0; + out_be16(&wdg->cr, 0); #endif - scm1->mpr = 0x77777777; - scm1->pacra = 0; - scm1->pacrb = 0; - scm1->pacrc = 0; - scm1->pacrd = 0; - scm1->pacre = 0; - scm1->pacrf = 0; + out_be32(&scm1->mpr, 0x77777777); + out_be32(&scm1->pacra, 0); + out_be32(&scm1->pacrb, 0); + out_be32(&scm1->pacrc, 0); + out_be32(&scm1->pacrd, 0); + out_be32(&scm1->pacre, 0); + out_be32(&scm1->pacrf, 0); /* FlexBus Chipselect */ init_fbcs(); @@ -137,36 +138,36 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= GPIO_PAR_UART0_UNMASK; - gpio->par_uart |= (GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); + clrbits_be16(&gpio->par_uart, ~GPIO_PAR_UART0_UNMASK); + setbits_be16(&gpio->par_uart, GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); break; case 1: - gpio->par_uart &= GPIO_PAR_UART0_UNMASK; - gpio->par_uart |= (GPIO_PAR_UART_U1TXD | GPIO_PAR_UART_U1RXD); + clrbits_be16(&gpio->par_uart, ~GPIO_PAR_UART0_UNMASK); + setbits_be16(&gpio->par_uart, GPIO_PAR_UART_U1TXD | GPIO_PAR_UART_U1RXD); break; case 2: #ifdef CONFIG_SYS_UART2_PRI_GPIO - gpio->par_timer &= - (GPIO_PAR_TMR_TIN0_UNMASK | GPIO_PAR_TMR_TIN1_UNMASK); - gpio->par_timer |= - (GPIO_PAR_TMR_TIN0_U2TXD | GPIO_PAR_TMR_TIN1_U2RXD); + clrbits_8(&gpio->par_timer, + ~(GPIO_PAR_TMR_TIN0_UNMASK | GPIO_PAR_TMR_TIN1_UNMASK)); + setbits_8(&gpio->par_timer, + GPIO_PAR_TMR_TIN0_U2TXD | GPIO_PAR_TMR_TIN1_U2RXD); #endif #ifdef CONFIG_SYS_UART2_ALT1_GPIO - gpio->par_feci2c &= - (GPIO_PAR_FECI2C_MDC_UNMASK | GPIO_PAR_FECI2C_MDIO_UNMASK); - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_MDC_U2TXD | GPIO_PAR_FECI2C_MDIO_U2RXD); + clrbits_8(&gpio->par_feci2c, + ~(GPIO_PAR_FECI2C_MDC_UNMASK | GPIO_PAR_FECI2C_MDIO_UNMASK)); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC_U2TXD | GPIO_PAR_FECI2C_MDIO_U2RXD); #endif #ifdef CONFIG_SYS_UART2_ALT1_GPIO - gpio->par_feci2c &= - (GPIO_PAR_FECI2C_SDA_UNMASK | GPIO_PAR_FECI2C_SCL_UNMASK); - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_SDA_U2TXD | GPIO_PAR_FECI2C_SCL_U2RXD); + clrbits_8(&gpio->par_feci2c, + ~(GPIO_PAR_FECI2C_SDA_UNMASK | GPIO_PAR_FECI2C_SCL_UNMASK)); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SDA_U2TXD | GPIO_PAR_FECI2C_SCL_U2RXD); #endif break; } @@ -175,17 +176,17 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; if (setclear) { - gpio->par_fec |= - GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC; - gpio->par_feci2c |= - GPIO_PAR_FECI2C_MDC_MDC | GPIO_PAR_FECI2C_MDIO_MDIO; + setbits_8(&gpio->par_fec, + GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC_MDC | GPIO_PAR_FECI2C_MDIO_MDIO); } else { - gpio->par_fec &= - (GPIO_PAR_FEC_7W_UNMASK & GPIO_PAR_FEC_MII_UNMASK); - gpio->par_feci2c &= GPIO_PAR_FECI2C_RMII_UNMASK; + clrbits_8(&gpio->par_fec, + ~(GPIO_PAR_FEC_7W_UNMASK & GPIO_PAR_FEC_MII_UNMASK)); + clrbits_8(&gpio->par_feci2c, ~GPIO_PAR_FECI2C_RMII_UNMASK); } return 0; } @@ -249,17 +250,17 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile u32 *par = (u32 *) MMAP_PAR; + u32 *par = (u32 *) MMAP_PAR; /* Setup Ports: */ switch (port) { case 1: - *par &= 0xFFE7FFFF; - *par |= 0x00180000; + clrbits_be32(par, 0x00180000); + setbits_be32(par, 0x00180000); break; case 2: - *par &= 0xFFFFFFFC; - *par &= 0x00000003; + clrbits_be32(par, 0x00000003); + clrbits_be32(par, 0xFFFFFFFC); break; } } @@ -348,59 +349,59 @@ void cpu_init_f(void) * already initialized. */ #ifndef CONFIG_MONITOR_IS_IN_RAM - volatile sysctrl_t *sysctrl = (sysctrl_t *) (CONFIG_SYS_MBAR); - volatile gpio_t *gpio = (gpio_t *) (MMAP_GPIO); - volatile csctrl_t *csctrl = (csctrl_t *) (MMAP_FBCS); + sysctrl_t *sysctrl = (sysctrl_t *) (CONFIG_SYS_MBAR); + gpio_t *gpio = (gpio_t *) (MMAP_GPIO); + csctrl_t *csctrl = (csctrl_t *) (MMAP_FBCS); - sysctrl->sc_scr = CONFIG_SYS_SCR; - sysctrl->sc_spr = CONFIG_SYS_SPR; + out_be16(&sysctrl->sc_scr, CONFIG_SYS_SCR); + out_be16(&sysctrl->sc_spr, CONFIG_SYS_SPR); /* Setup Ports: */ - gpio->gpio_pacnt = CONFIG_SYS_PACNT; - gpio->gpio_paddr = CONFIG_SYS_PADDR; - gpio->gpio_padat = CONFIG_SYS_PADAT; - gpio->gpio_pbcnt = CONFIG_SYS_PBCNT; - gpio->gpio_pbddr = CONFIG_SYS_PBDDR; - gpio->gpio_pbdat = CONFIG_SYS_PBDAT; - gpio->gpio_pdcnt = CONFIG_SYS_PDCNT; + out_be32(&gpio->gpio_pacnt, CONFIG_SYS_PACNT); + out_be16(&gpio->gpio_paddr, CONFIG_SYS_PADDR); + out_be16(&gpio->gpio_padat, CONFIG_SYS_PADAT); + out_be32(&gpio->gpio_pbcnt, CONFIG_SYS_PBCNT); + out_be16(&gpio->gpio_pbddr, CONFIG_SYS_PBDDR); + out_be16(&gpio->gpio_pbdat, CONFIG_SYS_PBDAT); + out_be32(&gpio->gpio_pdcnt, CONFIG_SYS_PDCNT); /* Memory Controller: */ - csctrl->cs_br0 = CONFIG_SYS_BR0_PRELIM; - csctrl->cs_or0 = CONFIG_SYS_OR0_PRELIM; + out_be32(&csctrl->cs_br0, CONFIG_SYS_BR0_PRELIM); + out_be32(&csctrl->cs_or0, CONFIG_SYS_OR0_PRELIM); #if (defined(CONFIG_SYS_OR1_PRELIM) && defined(CONFIG_SYS_BR1_PRELIM)) - csctrl->cs_br1 = CONFIG_SYS_BR1_PRELIM; - csctrl->cs_or1 = CONFIG_SYS_OR1_PRELIM; + out_be32(&csctrl->cs_br1, CONFIG_SYS_BR1_PRELIM); + out_be32(&csctrl->cs_or1, CONFIG_SYS_OR1_PRELIM); #endif #if defined(CONFIG_SYS_OR2_PRELIM) && defined(CONFIG_SYS_BR2_PRELIM) - csctrl->cs_br2 = CONFIG_SYS_BR2_PRELIM; - csctrl->cs_or2 = CONFIG_SYS_OR2_PRELIM; + out_be32(&csctrl->cs_br2, CONFIG_SYS_BR2_PRELIM); + out_be32(&csctrl->cs_or2, CONFIG_SYS_OR2_PRELIM); #endif #if defined(CONFIG_SYS_OR3_PRELIM) && defined(CONFIG_SYS_BR3_PRELIM) - csctrl->cs_br3 = CONFIG_SYS_BR3_PRELIM; - csctrl->cs_or3 = CONFIG_SYS_OR3_PRELIM; + out_be32(&csctrl->cs_br3, CONFIG_SYS_BR3_PRELIM); + out_be32(&csctrl->cs_or3, CONFIG_SYS_OR3_PRELIM); #endif #if defined(CONFIG_SYS_OR4_PRELIM) && defined(CONFIG_SYS_BR4_PRELIM) - csctrl->cs_br4 = CONFIG_SYS_BR4_PRELIM; - csctrl->cs_or4 = CONFIG_SYS_OR4_PRELIM; + out_be32(&csctrl->cs_br4, CONFIG_SYS_BR4_PRELIM); + out_be32(&csctrl->cs_or4, CONFIG_SYS_OR4_PRELIM); #endif #if defined(CONFIG_SYS_OR5_PRELIM) && defined(CONFIG_SYS_BR5_PRELIM) - csctrl->cs_br5 = CONFIG_SYS_BR5_PRELIM; - csctrl->cs_or5 = CONFIG_SYS_OR5_PRELIM; + out_be32(&csctrl->cs_br5, CONFIG_SYS_BR5_PRELIM); + out_be32(&csctrl->cs_or5, CONFIG_SYS_OR5_PRELIM); #endif #if defined(CONFIG_SYS_OR6_PRELIM) && defined(CONFIG_SYS_BR6_PRELIM) - csctrl->cs_br6 = CONFIG_SYS_BR6_PRELIM; - csctrl->cs_or6 = CONFIG_SYS_OR6_PRELIM; + out_be32(&csctrl->cs_br6, CONFIG_SYS_BR6_PRELIM); + out_be32(&csctrl->cs_or6, CONFIG_SYS_OR6_PRELIM); #endif #if defined(CONFIG_SYS_OR7_PRELIM) && defined(CONFIG_SYS_BR7_PRELIM) - csctrl->cs_br7 = CONFIG_SYS_BR7_PRELIM; - csctrl->cs_or7 = CONFIG_SYS_OR7_PRELIM; + out_be32(&csctrl->cs_br7, CONFIG_SYS_BR7_PRELIM); + out_be32(&csctrl->cs_or7, CONFIG_SYS_OR7_PRELIM); #endif #endif /* #ifndef CONFIG_MONITOR_IS_IN_RAM */ @@ -420,17 +421,21 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->gpio_pbcnt &= ~(GPIO_PBCNT_PB0MSK | GPIO_PBCNT_PB1MSK); - gpio->gpio_pbcnt |= (GPIO_PBCNT_URT0_TXD | GPIO_PBCNT_URT0_RXD); + clrbits_be32(&gpio->gpio_pbcnt, + GPIO_PBCNT_PB0MSK | GPIO_PBCNT_PB1MSK); + setbits_be32(&gpio->gpio_pbcnt, + GPIO_PBCNT_URT0_TXD | GPIO_PBCNT_URT0_RXD); break; case 1: - gpio->gpio_pdcnt &= ~(GPIO_PDCNT_PD1MSK | GPIO_PDCNT_PD4MSK); - gpio->gpio_pdcnt |= (GPIO_PDCNT_URT1_RXD | GPIO_PDCNT_URT1_TXD); + clrbits_be32(&gpio->gpio_pdcnt, + GPIO_PDCNT_PD1MSK | GPIO_PDCNT_PD4MSK); + setbits_be32(&gpio->gpio_pdcnt, + GPIO_PDCNT_URT1_RXD | GPIO_PDCNT_URT1_TXD); break; } } @@ -438,13 +443,14 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; if (setclear) { - gpio->gpio_pbcnt |= GPIO_PBCNT_E_MDC | GPIO_PBCNT_E_RXER | - GPIO_PBCNT_E_RXD1 | GPIO_PBCNT_E_RXD2 | - GPIO_PBCNT_E_RXD3 | GPIO_PBCNT_E_TXD1 | - GPIO_PBCNT_E_TXD2 | GPIO_PBCNT_E_TXD3; + setbits_be32(&gpio->gpio_pbcnt, + GPIO_PBCNT_E_MDC | GPIO_PBCNT_E_RXER | + GPIO_PBCNT_E_RXD1 | GPIO_PBCNT_E_RXD2 | + GPIO_PBCNT_E_RXD3 | GPIO_PBCNT_E_TXD1 | + GPIO_PBCNT_E_TXD2 | GPIO_PBCNT_E_TXD3); } else { } return 0; @@ -469,11 +475,11 @@ void cpu_init_f(void) */ #ifndef CONFIG_MONITOR_IS_IN_RAM - volatile wdog_t *wdog_reg = (wdog_t *) (MMAP_WDOG); - volatile gpio_t *gpio_reg = (gpio_t *) (MMAP_GPIO); + wdog_t *wdog_reg = (wdog_t *) (MMAP_WDOG); + gpio_t *gpio_reg = (gpio_t *) (MMAP_GPIO); /* Kill watchdog so we can initialize the PLL */ - wdog_reg->wcr = 0; + out_be16(&wdog_reg->wcr, 0); /* FlexBus Chipselect */ init_fbcs(); @@ -498,21 +504,21 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= ~UART0_ENABLE_MASK; - gpio->par_uart |= UART0_ENABLE_MASK; + clrbits_be16(&gpio->par_uart, UART0_ENABLE_MASK); + setbits_be16(&gpio->par_uart, UART0_ENABLE_MASK); break; case 1: - gpio->par_uart &= ~UART1_ENABLE_MASK; - gpio->par_uart |= UART1_ENABLE_MASK; + clrbits_be16(&gpio->par_uart, UART1_ENABLE_MASK); + setbits_be16(&gpio->par_uart, UART1_ENABLE_MASK); break; case 2: - gpio->par_uart &= ~UART2_ENABLE_MASK; - gpio->par_uart |= UART2_ENABLE_MASK; + clrbits_be16(&gpio->par_uart, UART2_ENABLE_MASK); + setbits_be16(&gpio->par_uart, UART2_ENABLE_MASK); break; } } @@ -521,24 +527,24 @@ void uart_port_conf(int port) int fecpin_setclear(struct eth_device *dev, int setclear) { struct fec_info_s *info = (struct fec_info_s *) dev->priv; - volatile gpio_t *gpio = (gpio_t *)MMAP_GPIO; + gpio_t *gpio = (gpio_t *)MMAP_GPIO; if (setclear) { /* Enable Ethernet pins */ if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { - gpio->par_feci2c |= 0x0F00; - gpio->par_fec0hl |= 0xC0; + setbits_be16(&gpio->par_feci2c, 0x0f00); + setbits_8(&gpio->par_fec0hl, 0xc0); } else { - gpio->par_feci2c |= 0x00A0; - gpio->par_fec1hl |= 0xC0; + setbits_be16(&gpio->par_feci2c, 0x00a0); + setbits_8(&gpio->par_fec1hl, 0xc0); } } else { if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { - gpio->par_feci2c &= ~0x0F00; - gpio->par_fec0hl &= ~0xC0; + clrbits_be16(&gpio->par_feci2c, 0x0f00); + clrbits_8(&gpio->par_fec0hl, 0xc0); } else { - gpio->par_feci2c &= ~0x00A0; - gpio->par_fec1hl &= ~0xC0; + clrbits_be16(&gpio->par_feci2c, 0x00a0); + clrbits_8(&gpio->par_fec1hl, 0xc0); } } diff --git a/arch/m68k/cpu/mcf52x2/interrupts.c b/arch/m68k/cpu/mcf52x2/interrupts.c index dff8c6a..915eb70 100644 --- a/arch/m68k/cpu/mcf52x2/interrupts.c +++ b/arch/m68k/cpu/mcf52x2/interrupts.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,20 +28,22 @@ #include #include #include +#include #ifdef CONFIG_M5272 int interrupt_init(void) { - volatile intctrl_t *intp = (intctrl_t *) (MMAP_INTC); + intctrl_t *intp = (intctrl_t *) (MMAP_INTC); /* disable all external interrupts */ - intp->int_icr1 = 0x88888888; - intp->int_icr2 = 0x88888888; - intp->int_icr3 = 0x88888888; - intp->int_icr4 = 0x88888888; - intp->int_pitr = 0x00000000; + out_be32(&intp->int_icr1, 0x88888888); + out_be32(&intp->int_icr2, 0x88888888); + out_be32(&intp->int_icr3, 0x88888888); + out_be32(&intp->int_icr4, 0x88888888); + out_be32(&intp->int_pitr, 0x00000000); + /* initialize vector register */ - intp->int_pivr = 0x40; + out_8(&intp->int_pivr, 0x40); enable_interrupts(); @@ -51,10 +53,10 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile intctrl_t *intp = (intctrl_t *) (CONFIG_SYS_INTR_BASE); + intctrl_t *intp = (intctrl_t *) (CONFIG_SYS_INTR_BASE); - intp->int_icr1 &= ~INT_ICR1_TMR3MASK; - intp->int_icr1 |= CONFIG_SYS_TMRINTR_PRI; + clrbits_be32(&intp->int_icr1, INT_ICR1_TMR3MASK); + setbits_be32(&intp->int_icr1, CONFIG_SYS_TMRINTR_PRI); } #endif /* CONFIG_MCFTMR */ #endif /* CONFIG_M5272 */ @@ -63,14 +65,14 @@ void dtimer_intr_setup(void) defined(CONFIG_M5271) || defined(CONFIG_M5275) int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ #if defined(CONFIG_M5208) - intp->imrl0 = 0xFFFFFFFF; - intp->imrh0 = 0xFFFFFFFF; + out_be32(&intp->imrl0, 0xffffffff); + out_be32(&intp->imrh0, 0xffffffff); #else - intp->imrl0 |= 0x1; + setbits_be32(&intp->imrl0, 0x1); #endif enable_interrupts(); @@ -80,11 +82,11 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrl0 &= 0xFFFFFFFE; - intp->imrl0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrl0, 0x00000001); + clrbits_be32(&intp->imrl0, CONFIG_SYS_TMRINTR_MASK); } #endif /* CONFIG_MCFTMR */ #endif /* CONFIG_M5282 | CONFIG_M5271 | CONFIG_M5275 */ diff --git a/arch/m68k/cpu/mcf52x2/speed.c b/arch/m68k/cpu/mcf52x2/speed.c index b485e1c..70abed2 100644 --- a/arch/m68k/cpu/mcf52x2/speed.c +++ b/arch/m68k/cpu/mcf52x2/speed.c @@ -2,7 +2,7 @@ * (C) Copyright 2003 * Josef Baumgartner * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * Hayden Fraser (Hayden.Fraser@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -34,10 +35,10 @@ DECLARE_GLOBAL_DATA_PTR; int get_clocks (void) { #if defined(CONFIG_M5208) - volatile pll_t *pll = (pll_t *) MMAP_PLL; + pll_t *pll = (pll_t *) MMAP_PLL; - pll->odr = CONFIG_SYS_PLL_ODR; - pll->fdr = CONFIG_SYS_PLL_FDR; + out_8(&pll->odr, CONFIG_SYS_PLL_ODR); + out_8(&pll->fdr, CONFIG_SYS_PLL_FDR); #endif #if defined(CONFIG_M5249) || defined(CONFIG_M5253) @@ -70,14 +71,14 @@ int get_clocks (void) #endif /* CONFIG_M5249 || CONFIG_M5253 */ #if defined(CONFIG_M5275) - volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + pll_t *pll = (pll_t *)(MMAP_PLL); /* Setup PLL */ - pll->syncr = 0x01080000; - while (!(pll->synsr & FMPLL_SYNSR_LOCK)) + out_be32(&pll->syncr, 0x01080000); + while (!(in_be32(&pll->synsr) & FMPLL_SYNSR_LOCK)) ; - pll->syncr = 0x01000000; - while (!(pll->synsr & FMPLL_SYNSR_LOCK)) + out_be32(&pll->syncr, 0x01000000); + while (!(in_be32(&pll->synsr) & FMPLL_SYNSR_LOCK)) ; #endif diff --git a/board/freescale/m5208evbe/m5208evbe.c b/board/freescale/m5208evbe/m5208evbe.c index 5f99e2f..355cfed 100644 --- a/board/freescale/m5208evbe/m5208evbe.c +++ b/board/freescale/m5208evbe/m5208evbe.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -39,7 +40,7 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; @@ -50,34 +51,35 @@ phys_size_t initdram(int board_type) } i--; - sdram->cs0 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cs0, CONFIG_SYS_SDRAM_BASE | i); #ifdef CONFIG_SYS_SDRAM_BASE1 - sdram->cs1 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cs1, CONFIG_SYS_SDRAM_BASE | i); #endif - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); asm("nop"); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); asm("nop"); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); asm("nop"); - sdram->mode = CONFIG_SYS_SDRAM_EMOD; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); asm("nop"); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); asm("nop"); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00); asm("nop"); udelay(100); diff --git a/board/freescale/m5253demo/m5253demo.c b/board/freescale/m5253demo/m5253demo.c index 8ffb2cc..052993d 100644 --- a/board/freescale/m5253demo/m5253demo.c +++ b/board/freescale/m5253demo/m5253demo.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * Hayden Fraser (Hayden.Fraser@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -109,7 +109,7 @@ int ide_preinit(void) void ide_set_reset(int idereset) { - volatile atac_t *ata = (atac_t *) CONFIG_SYS_ATA_BASE_ADDR; + atac_t *ata = (atac_t *) CONFIG_SYS_ATA_BASE_ADDR; long period; /* t1, t2, t3, t4, t5, t6, t9, tRD, tA */ int piotms[5][9] = { {70, 165, 60, 30, 50, 5, 20, 0, 35}, /* PIO 0 */ @@ -120,7 +120,8 @@ void ide_set_reset(int idereset) }; if (idereset) { - ata->cr = 0; /* control reset */ + /* control reset */ + out_8(&ata->cr, 0); udelay(100); } else { mbar2_writeLong(CIM_MISCCR, CIM_MISCCR_CPUEND); @@ -129,17 +130,19 @@ void ide_set_reset(int idereset) period = 1000000000 / (CONFIG_SYS_CLK / 2); /* period in ns */ /*ata->ton = CALC_TIMING (180); */ - ata->t1 = CALC_TIMING(piotms[2][0]); - ata->t2w = CALC_TIMING(piotms[2][1]); - ata->t2r = CALC_TIMING(piotms[2][1]); - ata->ta = CALC_TIMING(piotms[2][8]); - ata->trd = CALC_TIMING(piotms[2][7]); - ata->t4 = CALC_TIMING(piotms[2][3]); - ata->t9 = CALC_TIMING(piotms[2][6]); - - ata->cr = 0x40; /* IORDY enable */ + out_8(&ata->t1, CALC_TIMING(piotms[2][0])); + out_8(&ata->t2w, CALC_TIMING(piotms[2][1])); + out_8(&ata->t2r, CALC_TIMING(piotms[2][1])); + out_8(&ata->ta, CALC_TIMING(piotms[2][8])); + out_8(&ata->trd, CALC_TIMING(piotms[2][7])); + out_8(&ata->t4, CALC_TIMING(piotms[2][3])); + out_8(&ata->t9, CALC_TIMING(piotms[2][6])); + + /* IORDY enable */ + out_8(&ata->cr, 0x40); udelay(2000); - ata->cr |= 0x01; /* IORDY enable */ + /* IORDY enable */ + setbits_8(&ata->cr, 0x01); } } #endif /* CONFIG_CMD_IDE */ diff --git a/board/freescale/m5253evbe/m5253evbe.c b/board/freescale/m5253evbe/m5253evbe.c index ae69f67..658748b 100644 --- a/board/freescale/m5253evbe/m5253evbe.c +++ b/board/freescale/m5253evbe/m5253evbe.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * Hayden Fraser (Hayden.Fraser@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -26,6 +26,7 @@ #include #include +#include int checkboard(void) { @@ -101,7 +102,7 @@ int ide_preinit(void) void ide_set_reset(int idereset) { - volatile atac_t *ata = (atac_t *) CONFIG_SYS_ATA_BASE_ADDR; + atac_t *ata = (atac_t *) CONFIG_SYS_ATA_BASE_ADDR; long period; /* t1, t2, t3, t4, t5, t6, t9, tRD, tA */ int piotms[5][9] = { {70, 165, 60, 30, 50, 5, 20, 0, 35}, /* PIO 0 */ @@ -112,7 +113,8 @@ void ide_set_reset(int idereset) }; if (idereset) { - ata->cr = 0; /* control reset */ + /* control reset */ + out_8(&ata->cr, 0); udelay(100); } else { mbar2_writeLong(CIM_MISCCR, CIM_MISCCR_CPUEND); @@ -121,17 +123,19 @@ void ide_set_reset(int idereset) period = 1000000000 / (CONFIG_SYS_CLK / 2); /* period in ns */ /*ata->ton = CALC_TIMING (180); */ - ata->t1 = CALC_TIMING(piotms[2][0]); - ata->t2w = CALC_TIMING(piotms[2][1]); - ata->t2r = CALC_TIMING(piotms[2][1]); - ata->ta = CALC_TIMING(piotms[2][8]); - ata->trd = CALC_TIMING(piotms[2][7]); - ata->t4 = CALC_TIMING(piotms[2][3]); - ata->t9 = CALC_TIMING(piotms[2][6]); - - ata->cr = 0x40; /* IORDY enable */ + out_8(&ata->t1, CALC_TIMING(piotms[2][0])); + out_8(&ata->t2w, CALC_TIMING(piotms[2][1])); + out_8(&ata->t2r, CALC_TIMING(piotms[2][1])); + out_8(&ata->ta, CALC_TIMING(piotms[2][8])); + out_8(&ata->trd, CALC_TIMING(piotms[2][7])); + out_8(&ata->t4, CALC_TIMING(piotms[2][3])); + out_8(&ata->t9, CALC_TIMING(piotms[2][6])); + + /* IORDY enable */ + out_8(&ata->cr, 0x40); udelay(2000); - ata->cr |= 0x01; /* IORDY enable */ + /* IORDY enable */ + setbits_8(&ata->cr, 0x01); } } #endif /* CONFIG_CMD_IDE */ diff --git a/board/freescale/m5272c3/m5272c3.c b/board/freescale/m5272c3/m5272c3.c index 902ca3a..c3160ce 100644 --- a/board/freescale/m5272c3/m5272c3.c +++ b/board/freescale/m5272c3/m5272c3.c @@ -2,6 +2,8 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * * See file CREDITS for list of people who contributed to this * project. * @@ -23,6 +25,7 @@ #include #include +#include int checkboard (void) { @@ -32,10 +35,10 @@ int checkboard (void) { }; phys_size_t initdram (int board_type) { - volatile sdramctrl_t * sdp = (sdramctrl_t *)(MMAP_SDRAM); + sdramctrl_t * sdp = (sdramctrl_t *)(MMAP_SDRAM); - sdp->sdram_sdtr = 0xf539; - sdp->sdram_sdcr = 0x4211; + out_be16(&sdp->sdram_sdtr, 0xf539); + out_be16(&sdp->sdram_sdcr, 0x4211); /* Dummy write to start SDRAM */ *((volatile unsigned long *)0) = 0; diff --git a/board/freescale/m5275evb/m5275evb.c b/board/freescale/m5275evb/m5275evb.c index 35c9b20..1bbe5a3 100644 --- a/board/freescale/m5275evb/m5275evb.c +++ b/board/freescale/m5275evb/m5275evb.c @@ -4,6 +4,8 @@ * * Copyright (C) 2005-2008 Arthur Shipkowski (art@videon-central.com) * + * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * * See file CREDITS for list of people who contributed to this * project. * @@ -25,6 +27,7 @@ #include #include +#include #define PERIOD 13 /* system bus period in ns */ #define SDRAM_TREFI 7800 /* in ns */ @@ -38,67 +41,68 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdramctrl_t *sdp = (sdramctrl_t *)(MMAP_SDRAM); - volatile gpio_t *gpio_reg = (gpio_t *)(MMAP_GPIO); + sdramctrl_t *sdp = (sdramctrl_t *)(MMAP_SDRAM); + gpio_t *gpio_reg = (gpio_t *)(MMAP_GPIO); - gpio_reg->par_sdram = 0x3FF; /* Enable SDRAM */ + /* Enable SDRAM */ + out_be16(&gpio_reg->par_sdram, 0x3FF); /* Set up chip select */ - sdp->sdbar0 = CONFIG_SYS_SDRAM_BASE; - sdp->sdbmr0 = MCF_SDRAMC_SDMRn_BAM_32M | MCF_SDRAMC_SDMRn_V; + out_be32(&sdp->sdbar0, CONFIG_SYS_SDRAM_BASE); + out_be32(&sdp->sdbmr0, MCF_SDRAMC_SDMRn_BAM_32M | MCF_SDRAMC_SDMRn_V); /* Set up timing */ - sdp->sdcfg1 = 0x83711630; - sdp->sdcfg2 = 0x46770000; + out_be32(&sdp->sdcfg1, 0x83711630); + out_be32(&sdp->sdcfg2, 0x46770000); /* Enable clock */ - sdp->sdcr = MCF_SDRAMC_SDCR_MODE_EN | MCF_SDRAMC_SDCR_CKE; + out_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_MODE_EN | MCF_SDRAMC_SDCR_CKE); /* Set precharge */ - sdp->sdcr |= MCF_SDRAMC_SDCR_IPALL; + setbits_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_IPALL); /* Dummy write to start SDRAM */ *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; /* Send LEMR */ - sdp->sdmr = MCF_SDRAMC_SDMR_BNKAD_LEMR - | MCF_SDRAMC_SDMR_AD(0x0) - | MCF_SDRAMC_SDMR_CMD; + setbits_be32(&sdp->sdmr, + MCF_SDRAMC_SDMR_BNKAD_LEMR | MCF_SDRAMC_SDMR_AD(0x0) | + MCF_SDRAMC_SDMR_CMD); *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; /* Send LMR */ - sdp->sdmr = 0x058d0000; + out_be32(&sdp->sdmr, 0x058d0000); *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; /* Stop sending commands */ - sdp->sdmr &= ~(MCF_SDRAMC_SDMR_CMD); + clrbits_be32(&sdp->sdmr, MCF_SDRAMC_SDMR_CMD); /* Set precharge */ - sdp->sdcr |= MCF_SDRAMC_SDCR_IPALL; + setbits_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_IPALL); *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; /* Stop manual precharge, send 2 IREF */ - sdp->sdcr &= ~(MCF_SDRAMC_SDCR_IPALL); - sdp->sdcr |= MCF_SDRAMC_SDCR_IREF; + clrbits_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_IPALL); + setbits_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_IREF); *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; - /* Write mode register, clear reset DLL */ - sdp->sdmr = 0x018d0000; + + out_be32(&sdp->sdmr, 0x018d0000); *((volatile unsigned long *)CONFIG_SYS_SDRAM_BASE) = 0xa5a59696; /* Stop sending commands */ - sdp->sdmr &= ~(MCF_SDRAMC_SDMR_CMD); - sdp->sdcr &= ~(MCF_SDRAMC_SDCR_MODE_EN); + clrbits_be32(&sdp->sdmr, MCF_SDRAMC_SDMR_CMD); + clrbits_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_MODE_EN); /* Turn on auto refresh, lock SDMR */ - sdp->sdcr = + out_be32(&sdp->sdcr, MCF_SDRAMC_SDCR_CKE | MCF_SDRAMC_SDCR_REF | MCF_SDRAMC_SDCR_MUX(1) /* 1 added to round up */ | MCF_SDRAMC_SDCR_RCNT((SDRAM_TREFI/(PERIOD*64)) - 1 + 1) - | MCF_SDRAMC_SDCR_DQS_OE(0x3); + | MCF_SDRAMC_SDCR_DQS_OE(0x3)); return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; }; -- cgit v1.1 From aa0d99fc285a0b4ca71245c0c3ba8c00f8b51983 Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Mon, 26 Mar 2012 21:49:05 +0000 Subject: ColdFire: Clean up checkpatch warnings for MCF532x/MCF537x/MCF5301x Signed-off-by: Alison Wang --- arch/m68k/cpu/mcf532x/cpu.c | 33 ++-- arch/m68k/cpu/mcf532x/cpu_init.c | 304 ++++++++++++++++++---------------- arch/m68k/cpu/mcf532x/interrupts.c | 15 +- arch/m68k/cpu/mcf532x/speed.c | 77 ++++----- board/freescale/m53017evb/m53017evb.c | 28 ++-- board/freescale/m5329evb/m5329evb.c | 28 ++-- board/freescale/m5329evb/nand.c | 14 +- board/freescale/m5373evb/m5373evb.c | 28 ++-- board/freescale/m5373evb/nand.c | 18 +- 9 files changed, 287 insertions(+), 258 deletions(-) diff --git a/arch/m68k/cpu/mcf532x/cpu.c b/arch/m68k/cpu/mcf532x/cpu.c index 3346784..4f160a6 100644 --- a/arch/m68k/cpu/mcf532x/cpu.c +++ b/arch/m68k/cpu/mcf532x/cpu.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -31,15 +31,16 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM); + rcm_t *rcm = (rcm_t *) (MMAP_RCM); udelay(1000); - rcm->rcr |= RCM_RCR_SOFTRST; + setbits_8(&rcm->rcr, RCM_RCR_SOFTRST); /* we don't return! */ return 0; @@ -47,14 +48,14 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int checkcpu(void) { - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; u16 msk; u16 id = 0; u8 ver; puts("CPU: "); - msk = (ccm->cir >> 6); - ver = (ccm->cir & 0x003f); + msk = (in_be16(&ccm->cir) >> 6); + ver = (in_be16(&ccm->cir) & 0x003f); switch (msk) { #ifdef CONFIG_MCF5301x case 0x78: @@ -115,18 +116,20 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void watchdog_reset(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); - wdp->sr = 0x5555; /* Count register */ - wdp->sr = 0xAAAA; /* Count register */ + /* Count register */ + out_be16(&wdp->sr, 0x5555); + out_be16(&wdp->sr, 0xaaaa); } int watchdog_disable(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); /* UserManual, once the wdog is disabled, wdog cannot be re-enabled */ - wdp->cr |= WTM_WCR_HALTED; /* halted watchdog timer */ + /* halted watchdog timer */ + setbits_be16(&wdp->cr, WTM_WCR_HALTED); puts("WATCHDOG:disabled\n"); return (0); @@ -134,18 +137,18 @@ int watchdog_disable(void) int watchdog_init(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); u32 wdog_module = 0; /* set timeout and enable watchdog */ wdog_module = ((CONFIG_SYS_CLK / 1000) * CONFIG_WATCHDOG_TIMEOUT); #ifdef CONFIG_M5329 - wdp->mr = (wdog_module / 8192); + out_be16(&wdp->mr, wdog_module / 8192); #else - wdp->mr = (wdog_module / 4096); + out_be16(&wdp->mr, wdog_module / 4096); #endif - wdp->cr = WTM_WCR_EN; + out_be16(&wdp->cr, WTM_WCR_EN); puts("WATCHDOG:enabled\n"); return (0); diff --git a/arch/m68k/cpu/mcf532x/cpu_init.c b/arch/m68k/cpu/mcf532x/cpu_init.c index 6f551b6..f571fad 100644 --- a/arch/m68k/cpu/mcf532x/cpu_init.c +++ b/arch/m68k/cpu/mcf532x/cpu_init.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2004-2008 Freescale Semiconductor, Inc. + * (C) Copyright 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,6 +28,7 @@ #include #include #include +#include #if defined(CONFIG_CMD_NET) #include @@ -38,72 +39,68 @@ #ifdef CONFIG_MCF5301x void cpu_init_f(void) { - volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - - /* watchdog is enabled by default - disable the watchdog */ -#ifndef CONFIG_WATCHDOG - /*wdog->cr = 0; */ -#endif - - scm1->mpr = 0x77777777; - scm1->pacra = 0; - scm1->pacrb = 0; - scm1->pacrc = 0; - scm1->pacrd = 0; - scm1->pacre = 0; - scm1->pacrf = 0; - scm1->pacrg = 0; + scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + + out_be32(&scm1->mpr, 0x77777777); + out_be32(&scm1->pacra, 0); + out_be32(&scm1->pacrb, 0); + out_be32(&scm1->pacrc, 0); + out_be32(&scm1->pacrd, 0); + out_be32(&scm1->pacre, 0); + out_be32(&scm1->pacrf, 0); + out_be32(&scm1->pacrg, 0); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ && defined(CONFIG_SYS_CS0_CTRL)) - gpio->par_cs |= GPIO_PAR_CS0_CS0; - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS0_CS0); + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ && defined(CONFIG_SYS_CS1_CTRL)) - gpio->par_cs |= GPIO_PAR_CS1_CS1; - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS1_CS1); + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ && defined(CONFIG_SYS_CS2_CTRL)) - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ && defined(CONFIG_SYS_CS3_CTRL)) - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ && defined(CONFIG_SYS_CS4_CTRL)) - gpio->par_cs |= GPIO_PAR_CS4; - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS4); + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ && defined(CONFIG_SYS_CS5_CTRL)) - gpio->par_cs |= GPIO_PAR_CS5; - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS5); + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #ifdef CONFIG_FSL_I2C - gpio->par_feci2c = GPIO_PAR_FECI2C_SDA_SDA | GPIO_PAR_FECI2C_SCL_SCL; + out_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SDA_SDA | GPIO_PAR_FECI2C_SCL_SCL); #endif icache_enable(); @@ -113,21 +110,21 @@ void cpu_init_f(void) int cpu_init_r(void) { #ifdef CONFIG_MCFFEC - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; #endif #ifdef CONFIG_MCFRTC - volatile rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE); - volatile rtcex_t *rtcex = (rtcex_t *) & rtc->extended; + rtc_t *rtc = (rtc_t *) (CONFIG_SYS_MCFRTC_BASE); + rtcex_t *rtcex = (rtcex_t *) &rtc->extended; - rtcex->gocu = CONFIG_SYS_RTC_CNT; - rtcex->gocl = CONFIG_SYS_RTC_SETUP; + out_be32(&rtcex->gocu, CONFIG_SYS_RTC_CNT); + out_be32(&rtcex->gocl, CONFIG_SYS_RTC_SETUP); #endif #ifdef CONFIG_MCFFEC if (CONFIG_SYS_FEC0_MIIBASE != CONFIG_SYS_FEC1_MIIBASE) - ccm->misccr |= CCM_MISCCR_FECM; + setbits_be16(&ccm->misccr, CCM_MISCCR_FECM); else - ccm->misccr &= ~CCM_MISCCR_FECM; + clrbits_be16(&ccm->misccr, CCM_MISCCR_FECM); #endif return (0); @@ -135,41 +132,52 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= ~(GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); - gpio->par_uart |= (GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); + clrbits_8(&gpio->par_uart, + GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); + setbits_8(&gpio->par_uart, + GPIO_PAR_UART_U0TXD | GPIO_PAR_UART_U0RXD); break; case 1: #ifdef CONFIG_SYS_UART1_ALT1_GPIO - gpio->par_simp1h &= - ~(GPIO_PAR_SIMP1H_DATA1_UNMASK | - GPIO_PAR_SIMP1H_VEN1_UNMASK); - gpio->par_simp1h |= - (GPIO_PAR_SIMP1H_DATA1_U1TXD | GPIO_PAR_SIMP1H_VEN1_U1RXD); + clrbits_8(&gpio->par_simp1h, + GPIO_PAR_SIMP1H_DATA1_UNMASK | + GPIO_PAR_SIMP1H_VEN1_UNMASK); + setbits_8(&gpio->par_simp1h, + GPIO_PAR_SIMP1H_DATA1_U1TXD | + GPIO_PAR_SIMP1H_VEN1_U1RXD); #elif defined(CONFIG_SYS_UART1_ALT2_GPIO) - gpio->par_ssih &= - ~(GPIO_PAR_SSIH_RXD_UNMASK | GPIO_PAR_SSIH_TXD_UNMASK); - gpio->par_ssih |= - (GPIO_PAR_SSIH_RXD_U1RXD | GPIO_PAR_SSIH_TXD_U1TXD); + clrbits_8(&gpio->par_ssih, + GPIO_PAR_SSIH_RXD_UNMASK | + GPIO_PAR_SSIH_TXD_UNMASK); + setbits_8(&gpio->par_ssih, + GPIO_PAR_SSIH_RXD_U1RXD | + GPIO_PAR_SSIH_TXD_U1TXD); #endif break; case 2: #ifdef CONFIG_SYS_UART2_PRI_GPIO - gpio->par_uart |= (GPIO_PAR_UART_U2TXD | GPIO_PAR_UART_U2RXD); + setbits_8(&gpio->par_uart, + GPIO_PAR_UART_U2TXD | + GPIO_PAR_UART_U2RXD); #elif defined(CONFIG_SYS_UART2_ALT1_GPIO) - gpio->par_dspih &= - ~(GPIO_PAR_DSPIH_SIN_UNMASK | GPIO_PAR_DSPIH_SOUT_UNMASK); - gpio->par_dspih |= - (GPIO_PAR_DSPIH_SIN_U2RXD | GPIO_PAR_DSPIH_SOUT_U2TXD); + clrbits_8(&gpio->par_dspih, + GPIO_PAR_DSPIH_SIN_UNMASK | + GPIO_PAR_DSPIH_SOUT_UNMASK); + setbits_8(&gpio->par_dspih, + GPIO_PAR_DSPIH_SIN_U2RXD | + GPIO_PAR_DSPIH_SOUT_U2TXD); #elif defined(CONFIG_SYS_UART2_ALT2_GPIO) - gpio->par_feci2c &= - ~(GPIO_PAR_FECI2C_SDA_UNMASK | GPIO_PAR_FECI2C_SCL_UNMASK); - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_SDA_U2TXD | GPIO_PAR_FECI2C_SCL_U2RXD); + clrbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SDA_UNMASK | + GPIO_PAR_FECI2C_SCL_UNMASK); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SDA_U2TXD | + GPIO_PAR_FECI2C_SCL_U2RXD); #endif break; } @@ -178,30 +186,30 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; struct fec_info_s *info = (struct fec_info_s *)dev->priv; if (setclear) { if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { - gpio->par_fec |= - GPIO_PAR_FEC0_7W_FEC | GPIO_PAR_FEC0_RMII_FEC; - gpio->par_feci2c |= - GPIO_PAR_FECI2C_MDC0 | GPIO_PAR_FECI2C_MDIO0; + setbits_8(&gpio->par_fec, + GPIO_PAR_FEC0_7W_FEC | GPIO_PAR_FEC0_RMII_FEC); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC0 | GPIO_PAR_FECI2C_MDIO0); } else { - gpio->par_fec |= - GPIO_PAR_FEC1_7W_FEC | GPIO_PAR_FEC1_RMII_FEC; - gpio->par_feci2c |= - GPIO_PAR_FECI2C_MDC1 | GPIO_PAR_FECI2C_MDIO1; + setbits_8(&gpio->par_fec, + GPIO_PAR_FEC1_7W_FEC | GPIO_PAR_FEC1_RMII_FEC); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC1 | GPIO_PAR_FECI2C_MDIO1); } } else { if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { - gpio->par_fec &= - ~(GPIO_PAR_FEC0_7W_FEC | GPIO_PAR_FEC0_RMII_FEC); - gpio->par_feci2c &= GPIO_PAR_FECI2C_RMII0_UNMASK; + clrbits_8(&gpio->par_fec, + GPIO_PAR_FEC0_7W_FEC | GPIO_PAR_FEC0_RMII_FEC); + clrbits_8(&gpio->par_feci2c, ~GPIO_PAR_FECI2C_RMII0_UNMASK); } else { - gpio->par_fec &= - ~(GPIO_PAR_FEC1_7W_FEC | GPIO_PAR_FEC1_RMII_FEC); - gpio->par_feci2c &= GPIO_PAR_FECI2C_RMII1_UNMASK; + clrbits_8(&gpio->par_fec, + GPIO_PAR_FEC1_7W_FEC | GPIO_PAR_FEC1_RMII_FEC); + clrbits_8(&gpio->par_feci2c, ~GPIO_PAR_FECI2C_RMII1_UNMASK); } } return 0; @@ -212,80 +220,81 @@ int fecpin_setclear(struct eth_device *dev, int setclear) #ifdef CONFIG_MCF532x void cpu_init_f(void) { - volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; - volatile scm2_t *scm2 = (scm2_t *) MMAP_SCM2; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - volatile wdog_t *wdog = (wdog_t *) MMAP_WDOG; + scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + scm2_t *scm2 = (scm2_t *) MMAP_SCM2; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + wdog_t *wdog = (wdog_t *) MMAP_WDOG; /* watchdog is enabled by default - disable the watchdog */ #ifndef CONFIG_WATCHDOG - wdog->cr = 0; + out_be16(&wdog->cr, 0); #endif - scm1->mpr0 = 0x77777777; - scm2->pacra = 0; - scm2->pacrb = 0; - scm2->pacrc = 0; - scm2->pacrd = 0; - scm2->pacre = 0; - scm2->pacrf = 0; - scm2->pacrg = 0; - scm1->pacrh = 0; + out_be32(&scm1->mpr0, 0x77777777); + out_be32(&scm2->pacra, 0); + out_be32(&scm2->pacrb, 0); + out_be32(&scm2->pacrc, 0); + out_be32(&scm2->pacrd, 0); + out_be32(&scm2->pacre, 0); + out_be32(&scm2->pacrf, 0); + out_be32(&scm2->pacrg, 0); + out_be32(&scm1->pacrh, 0); /* Port configuration */ - gpio->par_cs = 0; + out_8(&gpio->par_cs, 0); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) \ && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) \ && defined(CONFIG_SYS_CS1_CTRL)) /* Latch chipselect */ - gpio->par_cs |= GPIO_PAR_CS1; - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS1); + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) \ && defined(CONFIG_SYS_CS2_CTRL)) - gpio->par_cs |= GPIO_PAR_CS2; - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS2); + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) \ && defined(CONFIG_SYS_CS3_CTRL)) - gpio->par_cs |= GPIO_PAR_CS3; - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS3); + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) \ && defined(CONFIG_SYS_CS4_CTRL)) - gpio->par_cs |= GPIO_PAR_CS4; - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS4); + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) \ && defined(CONFIG_SYS_CS5_CTRL)) - gpio->par_cs |= GPIO_PAR_CS5; - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS5); + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #ifdef CONFIG_FSL_I2C - gpio->par_feci2c = GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA; + out_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA); #endif icache_enable(); @@ -301,30 +310,35 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= ~(GPIO_PAR_UART_TXD0 | GPIO_PAR_UART_RXD0); - gpio->par_uart |= (GPIO_PAR_UART_TXD0 | GPIO_PAR_UART_RXD0); + clrbits_be16(&gpio->par_uart, + GPIO_PAR_UART_TXD0 | GPIO_PAR_UART_RXD0); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_TXD0 | GPIO_PAR_UART_RXD0); break; case 1: - gpio->par_uart &= - ~(GPIO_PAR_UART_TXD1(3) | GPIO_PAR_UART_RXD1(3)); - gpio->par_uart |= - (GPIO_PAR_UART_TXD1(3) | GPIO_PAR_UART_RXD1(3)); + clrbits_be16(&gpio->par_uart, + GPIO_PAR_UART_TXD1(3) | GPIO_PAR_UART_RXD1(3)); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_TXD1(3) | GPIO_PAR_UART_RXD1(3)); break; case 2: #ifdef CONFIG_SYS_UART2_ALT1_GPIO - gpio->par_timer &= 0x0F; - gpio->par_timer |= (GPIO_PAR_TIN3_URXD2 | GPIO_PAR_TIN2_UTXD2); + clrbits_8(&gpio->par_timer, 0xf0); + setbits_8(&gpio->par_timer, + GPIO_PAR_TIN3_URXD2 | GPIO_PAR_TIN2_UTXD2); #elif defined(CONFIG_SYS_UART2_ALT2_GPIO) - gpio->par_feci2c &= 0xFF00; - gpio->par_feci2c |= (GPIO_PAR_FECI2C_SCL_UTXD2 | GPIO_PAR_FECI2C_SDA_URXD2); + clrbits_8(&gpio->par_feci2c, 0x00ff); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SCL_UTXD2 | GPIO_PAR_FECI2C_SDA_URXD2); #elif defined(CONFIG_SYS_UART2_ALT3_GPIO) - gpio->par_ssi &= 0xF0FF; - gpio->par_ssi |= (GPIO_PAR_SSI_RXD(2) | GPIO_PAR_SSI_TXD(2)); + clrbits_be16(&gpio->par_ssi, 0x0f00); + setbits_be16(&gpio->par_ssi, + GPIO_PAR_SSI_RXD(2) | GPIO_PAR_SSI_TXD(2)); #endif break; } @@ -333,16 +347,18 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; if (setclear) { - gpio->par_fec |= GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC; - gpio->par_feci2c |= - GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO; + setbits_8(&gpio->par_fec, + GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO); } else { - gpio->par_fec &= ~(GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC); - gpio->par_feci2c &= - ~(GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO); + clrbits_8(&gpio->par_fec, + GPIO_PAR_FEC_7W_FEC | GPIO_PAR_FEC_MII_FEC); + clrbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC_EMDC | GPIO_PAR_FECI2C_MDIO_EMDIO); } return 0; } diff --git a/arch/m68k/cpu/mcf532x/interrupts.c b/arch/m68k/cpu/mcf532x/interrupts.c index d6c8205..d1ea2ff 100644 --- a/arch/m68k/cpu/mcf532x/interrupts.c +++ b/arch/m68k/cpu/mcf532x/interrupts.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -25,14 +25,15 @@ /* CPU specific interrupt routine */ #include #include +#include int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ - intp->imrh0 |= 0xFFFFFFFF; - intp->imrl0 |= 0xFFFFFFFF; + setbits_be32(&intp->imrh0, 0xffffffff); + setbits_be32(&intp->imrl0, 0xffffffff); enable_interrupts(); return 0; @@ -41,9 +42,9 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrh0, CONFIG_SYS_TMRINTR_MASK); } #endif diff --git a/arch/m68k/cpu/mcf532x/speed.c b/arch/m68k/cpu/mcf532x/speed.c index 5a29e25..cfdcc8b 100644 --- a/arch/m68k/cpu/mcf532x/speed.c +++ b/arch/m68k/cpu/mcf532x/speed.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -29,6 +29,7 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -65,13 +66,13 @@ DECLARE_GLOBAL_DATA_PTR; /* Get the value of the current system clock */ int get_sys_clock(void) { - volatile ccm_t *ccm = (volatile ccm_t *)(MMAP_CCM); - volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + ccm_t *ccm = (ccm_t *)(MMAP_CCM); + pll_t *pll = (pll_t *)(MMAP_PLL); int divider; /* Test to see if device is in LIMP mode */ - if (ccm->misccr & CCM_MISCCR_LIMP) { - divider = ccm->cdr & CCM_CDR_LPDIV(0xF); + if (in_be16(&ccm->misccr) & CCM_MISCCR_LIMP) { + divider = in_be16(&ccm->cdr) & CCM_CDR_LPDIV(0xF); #ifdef CONFIG_MCF5301x return (FREF / (3 * (1 << divider))); #endif @@ -80,14 +81,14 @@ int get_sys_clock(void) #endif } else { #ifdef CONFIG_MCF5301x - u32 pfdr = (pll->pcr & 0x3F) + 1; - u32 refdiv = (1 << ((pll->pcr & PLL_PCR_REFDIV(7)) >> 8)); - u32 busdiv = ((pll->pdr & 0x00F0) >> 4) + 1; + u32 pfdr = (in_be32(&pll->pcr) & 0x3F) + 1; + u32 refdiv = (1 << ((in_be32(&pll->pcr) & PLL_PCR_REFDIV(7)) >> 8)); + u32 busdiv = ((in_be32(&pll->pdr) & 0x00F0) >> 4) + 1; return (((FREF * pfdr) / refdiv) / busdiv); #endif #ifdef CONFIG_MCF532x - return ((FREF * pll->pfdr) / (BUSDIV * 4)); + return (FREF * in_8(&pll->pfdr)) / (BUSDIV * 4); #endif } } @@ -103,7 +104,7 @@ int get_sys_clock(void) */ int clock_limp(int div) { - volatile ccm_t *ccm = (volatile ccm_t *)(MMAP_CCM); + ccm_t *ccm = (ccm_t *)(MMAP_CCM); u32 temp; /* Check bounds of divider */ @@ -113,12 +114,12 @@ int clock_limp(int div) div = MAX_LPD; /* Save of the current value of the SSIDIV so we don't overwrite the value */ - temp = (ccm->cdr & CCM_CDR_SSIDIV(0xFF)); + temp = (in_be16(&ccm->cdr) & CCM_CDR_SSIDIV(0xFF)); /* Apply the divider to the system clock */ - ccm->cdr = (CCM_CDR_LPDIV(div) | CCM_CDR_SSIDIV(temp)); + out_be16(&ccm->cdr, CCM_CDR_LPDIV(div) | CCM_CDR_SSIDIV(temp)); - ccm->misccr |= CCM_MISCCR_LIMP; + setbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); return (FREF / (3 * (1 << div))); } @@ -126,14 +127,15 @@ int clock_limp(int div) /* Exit low power LIMP mode */ int clock_exit_limp(void) { - volatile ccm_t *ccm = (volatile ccm_t *)(MMAP_CCM); + ccm_t *ccm = (ccm_t *)(MMAP_CCM); int fout; /* Exit LIMP mode */ - ccm->misccr &= (~CCM_MISCCR_LIMP); + clrbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); /* Wait for PLL to lock */ - while (!(ccm->misccr & CCM_MISCCR_PLL_LOCK)) ; + while (!(in_be16(&ccm->misccr) & CCM_MISCCR_PLL_LOCK)) + ; fout = get_sys_clock(); @@ -153,10 +155,10 @@ int clock_exit_limp(void) int clock_pll(int fsys, int flags) { #ifdef CONFIG_MCF532x - volatile u32 *sdram_workaround = (volatile u32 *)(MMAP_SDRAM + 0x80); + u32 *sdram_workaround = (u32 *)(MMAP_SDRAM + 0x80); #endif - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); - volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); + pll_t *pll = (pll_t *)(MMAP_PLL); int fref, temp, fout, mfd; u32 i; @@ -165,13 +167,13 @@ int clock_pll(int fsys, int flags) if (fsys == 0) { /* Return current PLL output */ #ifdef CONFIG_MCF5301x - u32 busdiv = ((pll->pdr >> 4) & 0x0F) + 1; - mfd = (pll->pcr & 0x3F) + 1; + u32 busdiv = ((in_be32(&pll->pdr) >> 4) & 0x0F) + 1; + mfd = (in_be32(&pll->pcr) & 0x3F) + 1; return (fref * mfd) / busdiv; #endif #ifdef CONFIG_MCF532x - mfd = pll->pfdr; + mfd = in_8(&pll->pfdr); return (fref * mfd / (BUSDIV * 4)); #endif @@ -211,8 +213,8 @@ int clock_pll(int fsys, int flags) * If it has then the SDRAM needs to be put into self refresh * mode before reprogramming the PLL. */ - if (sdram->ctrl & SDRAMC_SDCR_REF) - sdram->ctrl &= ~SDRAMC_SDCR_CKE; + if (in_be32(&sdram->ctrl) & SDRAMC_SDCR_REF) + clrbits_be32(&sdram->ctrl, SDRAMC_SDCR_CKE); /* * Initialize the PLL to generate the new system clock frequency. @@ -223,35 +225,36 @@ int clock_pll(int fsys, int flags) clock_limp(DEFAULT_LPD); #ifdef CONFIG_MCF5301x - pll->pdr = - PLL_PDR_OUTDIV1((BUSDIV / 3) - 1) | - PLL_PDR_OUTDIV2(BUSDIV - 1) | - PLL_PDR_OUTDIV3((BUSDIV / 2) - 1) | - PLL_PDR_OUTDIV4(USBDIV - 1); - - pll->pcr &= PLL_PCR_FBDIV_UNMASK; - pll->pcr |= PLL_PCR_FBDIV(mfd - 1); + out_be32(&pll->pdr, + PLL_PDR_OUTDIV1((BUSDIV / 3) - 1) | + PLL_PDR_OUTDIV2(BUSDIV - 1) | + PLL_PDR_OUTDIV3((BUSDIV / 2) - 1) | + PLL_PDR_OUTDIV4(USBDIV - 1)); + + clrbits_be32(&pll->pcr, ~PLL_PCR_FBDIV_UNMASK); + setbits_be32(&pll->pcr, PLL_PCR_FBDIV(mfd - 1)); #endif #ifdef CONFIG_MCF532x /* Reprogram PLL for desired fsys */ - pll->podr = (PLL_PODR_CPUDIV(BUSDIV / 3) | PLL_PODR_BUSDIV(BUSDIV)); + out_8(&pll->podr, + PLL_PODR_CPUDIV(BUSDIV / 3) | PLL_PODR_BUSDIV(BUSDIV)); - pll->pfdr = mfd; + out_8(&pll->pfdr, mfd); #endif /* Exit LIMP mode */ clock_exit_limp(); /* Return the SDRAM to normal operation if it is in use. */ - if (sdram->ctrl & SDRAMC_SDCR_REF) - sdram->ctrl |= SDRAMC_SDCR_CKE; + if (in_be32(&sdram->ctrl) & SDRAMC_SDCR_REF) + setbits_be32(&sdram->ctrl, SDRAMC_SDCR_CKE); #ifdef CONFIG_MCF532x /* * software workaround for SDRAM opeartion after exiting LIMP * mode errata */ - *sdram_workaround = CONFIG_SYS_SDRAM_BASE; + out_be32(sdram_workaround, CONFIG_SYS_SDRAM_BASE); #endif /* wait for DQS logic to relock */ diff --git a/board/freescale/m53017evb/m53017evb.c b/board/freescale/m53017evb/m53017evb.c index f331786..142485f 100644 --- a/board/freescale/m53017evb/m53017evb.c +++ b/board/freescale/m53017evb/m53017evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -39,7 +40,7 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; @@ -50,34 +51,35 @@ phys_size_t initdram(int board_type) } i--; - sdram->cs0 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cs0, CONFIG_SYS_SDRAM_BASE | i); #ifdef CONFIG_SYS_SDRAM_BASE1 - sdram->cs1 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cs1, CONFIG_SYS_SDRAM_BASE | i); #endif - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); asm("nop"); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); asm("nop"); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); asm("nop"); - sdram->mode = CONFIG_SYS_SDRAM_EMOD; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); asm("nop"); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); asm("nop"); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00); asm("nop"); udelay(100); diff --git a/board/freescale/m5329evb/m5329evb.c b/board/freescale/m5329evb/m5329evb.c index b4df22f..1c14b83 100644 --- a/board/freescale/m5329evb/m5329evb.c +++ b/board/freescale/m5329evb/m5329evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -39,7 +40,7 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; @@ -50,29 +51,30 @@ phys_size_t initdram(int board_type) } i--; - sdram->cs0 = (CONFIG_SYS_SDRAM_BASE | i); - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cs0, CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_EMOD; - sdram->mode = (CONFIG_SYS_SDRAM_MODE | 0x04000000); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE | 0x04000000); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00); udelay(100); diff --git a/board/freescale/m5329evb/nand.c b/board/freescale/m5329evb/nand.c index 16025f9..c70c98c 100644 --- a/board/freescale/m5329evb/nand.c +++ b/board/freescale/m5329evb/nand.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -67,18 +67,18 @@ static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, unsigned int ctrl) int board_nand_init(struct nand_chip *nand) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* * set up pin configuration - enabled 2nd output buffer's signals * (nand_ngpio - nCE USB1/2_PWR_EN, LATCH_GPIOs, LCD_VEEEN, etc) * to use nCE signal */ - gpio->par_timer &= ~GPIO_PAR_TIN3_TIN3; - gpio->pddr_timer |= 0x08; - gpio->ppd_timer |= 0x08; - gpio->pclrr_timer = 0; - gpio->podr_timer = 0; + clrbits_8(&gpio->par_timer, GPIO_PAR_TIN3_TIN3); + setbits_8(&gpio->pddr_timer, 0x08); + setbits_8(&gpio->ppd_timer, 0x08); + out_8(&gpio->pclrr_timer, 0); + out_8(&gpio->podr_timer, 0); nand->chip_delay = 60; nand->ecc.mode = NAND_ECC_SOFT; diff --git a/board/freescale/m5373evb/m5373evb.c b/board/freescale/m5373evb/m5373evb.c index 376de4b..8eb3512 100644 --- a/board/freescale/m5373evb/m5373evb.c +++ b/board/freescale/m5373evb/m5373evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -39,7 +40,7 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; @@ -50,29 +51,30 @@ phys_size_t initdram(int board_type) } i--; - sdram->cs0 = (CONFIG_SYS_SDRAM_BASE | i); - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cs0, CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_EMOD; - sdram->mode = (CONFIG_SYS_SDRAM_MODE | 0x04000000); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE | 0x04000000); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00); udelay(100); diff --git a/board/freescale/m5373evb/nand.c b/board/freescale/m5373evb/nand.c index df8c03b..ed79e39 100644 --- a/board/freescale/m5373evb/nand.c +++ b/board/freescale/m5373evb/nand.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -68,21 +68,21 @@ static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, unsigned int ctrl) int board_nand_init(struct nand_chip *nand) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - fbcs->csmr2 &= ~FBCS_CSMR_WP; + clrbits_be32(&fbcs->csmr2, FBCS_CSMR_WP); /* * set up pin configuration - enabled 2nd output buffer's signals * (nand_ngpio - nCE USB1/2_PWR_EN, LATCH_GPIOs, LCD_VEEEN, etc) * to use nCE signal */ - gpio->par_timer &= ~GPIO_PAR_TIN3_TIN3; - gpio->pddr_timer |= 0x08; - gpio->ppd_timer |= 0x08; - gpio->pclrr_timer = 0; - gpio->podr_timer = 0; + clrbits_8(&gpio->par_timer, GPIO_PAR_TIN3_TIN3); + setbits_8(&gpio->pddr_timer, 0x08); + setbits_8(&gpio->ppd_timer, 0x08); + out_8(&gpio->pclrr_timer, 0); + out_8(&gpio->podr_timer, 0); nand->chip_delay = 60; nand->ecc.mode = NAND_ECC_SOFT; -- cgit v1.1 From c6d88630158af79f5700c8bbc37972f511e84500 Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Mon, 26 Mar 2012 21:49:06 +0000 Subject: ColdFire: Clean up checkpatch warnings for MCF523x Signed-off-by: Alison Wang --- arch/m68k/cpu/mcf523x/cpu.c | 33 +++++----- arch/m68k/cpu/mcf523x/cpu_init.c | 122 +++++++++++++++++++----------------- arch/m68k/cpu/mcf523x/interrupts.c | 15 ++--- arch/m68k/cpu/mcf523x/speed.c | 10 +-- board/freescale/m5235evb/m5235evb.c | 43 +++++++------ 5 files changed, 120 insertions(+), 103 deletions(-) diff --git a/arch/m68k/cpu/mcf523x/cpu.c b/arch/m68k/cpu/mcf523x/cpu.c index 2376f97..a3f5684 100644 --- a/arch/m68k/cpu/mcf523x/cpu.c +++ b/arch/m68k/cpu/mcf523x/cpu.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -31,28 +31,29 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; - ccm->rcr = CCM_RCR_SOFTRST; + out_8(&ccm->rcr, CCM_RCR_SOFTRST); /* we don't return! */ return 0; -}; +} int checkcpu(void) { - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; u16 msk; u16 id = 0; u8 ver; puts("CPU: "); - msk = (ccm->cir >> 6); - ver = (ccm->cir & 0x003f); + msk = (in_be16(&ccm->cir) >> 6); + ver = (in_be16(&ccm->cir) & 0x003f); switch (msk) { case 0x31: id = 5235; @@ -76,19 +77,21 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void watchdog_reset(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); - wdp->sr = 0x5555; /* Count register */ + /* Count register */ + out_be16(&wdp->sr, 0x5555); asm("nop"); - wdp->sr = 0xAAAA; /* Count register */ + out_be16(&wdp->sr, 0xaaaa); } int watchdog_disable(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); /* UserManual, once the wdog is disabled, wdog cannot be re-enabled */ - wdp->cr |= WTM_WCR_HALTED; /* halted watchdog timer */ + /* halted watchdog timer */ + setbits_be16(&wdp->cr, WTM_WCR_HALTED); puts("WATCHDOG:disabled\n"); return (0); @@ -96,15 +99,15 @@ int watchdog_disable(void) int watchdog_init(void) { - volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG); + wdog_t *wdp = (wdog_t *) (MMAP_WDOG); u32 wdog_module = 0; /* set timeout and enable watchdog */ wdog_module = ((CONFIG_SYS_CLK / CONFIG_SYS_HZ) * CONFIG_WATCHDOG_TIMEOUT); wdog_module |= (wdog_module / 8192); - wdp->mr = wdog_module; + out_be16(&wdp->mr, wdog_module); - wdp->cr = WTM_WCR_EN; + out_be16(&wdp->cr, WTM_WCR_EN); puts("WATCHDOG:enabled\n"); return (0); diff --git a/arch/m68k/cpu/mcf523x/cpu_init.c b/arch/m68k/cpu/mcf523x/cpu_init.c index 0f299f0..d1c0b40 100644 --- a/arch/m68k/cpu/mcf523x/cpu_init.c +++ b/arch/m68k/cpu/mcf523x/cpu_init.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2007 Freescale Semiconductor, Inc. + * (C) Copyright 2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,6 +28,7 @@ #include #include #include +#include #if defined(CONFIG_CMD_NET) #include @@ -44,74 +45,74 @@ */ void cpu_init_f(void) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - volatile wdog_t *wdog = (wdog_t *) MMAP_WDOG; - volatile scm_t *scm = (scm_t *) MMAP_SCM; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + wdog_t *wdog = (wdog_t *) MMAP_WDOG; + scm_t *scm = (scm_t *) MMAP_SCM; /* watchdog is enabled by default - disable the watchdog */ #ifndef CONFIG_WATCHDOG - wdog->cr = 0; + out_be16(&wdog->cr, 0); #endif - scm->rambar = (CONFIG_SYS_INIT_RAM_ADDR | SCM_RAMBAR_BDE); + out_be32(&scm->rambar, CONFIG_SYS_INIT_RAM_ADDR | SCM_RAMBAR_BDE); /* Port configuration */ - gpio->par_cs = 0; + out_8(&gpio->par_cs, 0); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) && defined(CONFIG_SYS_CS1_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS1; - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS1); + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) && defined(CONFIG_SYS_CS2_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS2; - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS2); + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) && defined(CONFIG_SYS_CS3_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS3; - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS3); + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) && defined(CONFIG_SYS_CS4_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS4; - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS4); + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) && defined(CONFIG_SYS_CS5_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS5; - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS5); + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #if (defined(CONFIG_SYS_CS6_BASE) && defined(CONFIG_SYS_CS6_MASK) && defined(CONFIG_SYS_CS6_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS6; - fbcs->csar6 = CONFIG_SYS_CS6_BASE; - fbcs->cscr6 = CONFIG_SYS_CS6_CTRL; - fbcs->csmr6 = CONFIG_SYS_CS6_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS6); + out_be32(&fbcs->csar6, CONFIG_SYS_CS6_BASE); + out_be32(&fbcs->cscr6, CONFIG_SYS_CS6_CTRL); + out_be32(&fbcs->csmr6, CONFIG_SYS_CS6_MASK); #endif #if (defined(CONFIG_SYS_CS7_BASE) && defined(CONFIG_SYS_CS7_MASK) && defined(CONFIG_SYS_CS7_CTRL)) - gpio->par_cs |= GPIO_PAR_CS_CS7; - fbcs->csar7 = CONFIG_SYS_CS7_BASE; - fbcs->cscr7 = CONFIG_SYS_CS7_CTRL; - fbcs->csmr7 = CONFIG_SYS_CS7_MASK; + setbits_8(&gpio->par_cs, GPIO_PAR_CS_CS7); + out_be32(&fbcs->csar7, CONFIG_SYS_CS7_BASE); + out_be32(&fbcs->cscr7, CONFIG_SYS_CS7_CTRL); + out_be32(&fbcs->csmr7, CONFIG_SYS_CS7_MASK); #endif #ifdef CONFIG_FSL_I2C @@ -132,29 +133,33 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= ~(GPIO_PAR_UART_U0RXD | GPIO_PAR_UART_U0TXD); - gpio->par_uart |= (GPIO_PAR_UART_U0RXD | GPIO_PAR_UART_U0TXD); + clrbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U0RXD | GPIO_PAR_UART_U0TXD); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U0RXD | GPIO_PAR_UART_U0TXD); break; case 1: - gpio->par_uart &= - ~(GPIO_PAR_UART_U1RXD_MASK | GPIO_PAR_UART_U1TXD_MASK); - gpio->par_uart |= - (GPIO_PAR_UART_U1RXD_U1RXD | GPIO_PAR_UART_U1TXD_U1TXD); + clrbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U1RXD_MASK | GPIO_PAR_UART_U1TXD_MASK); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U1RXD_U1RXD | GPIO_PAR_UART_U1TXD_U1TXD); break; case 2: #ifdef CONFIG_SYS_UART2_PRI_GPIO - gpio->par_uart &= ~(GPIO_PAR_UART_U2RXD | GPIO_PAR_UART_U2TXD); - gpio->par_uart |= (GPIO_PAR_UART_U2RXD | GPIO_PAR_UART_U2TXD); + clrbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U2RXD | GPIO_PAR_UART_U2TXD); + setbits_be16(&gpio->par_uart, + GPIO_PAR_UART_U2RXD | GPIO_PAR_UART_U2TXD); #elif defined(CONFIG_SYS_UART2_ALT1_GPIO) - gpio->feci2c &= - ~(GPIO_PAR_FECI2C_EMDC_MASK | GPIO_PAR_FECI2C_EMDIO_MASK); - gpio->feci2c |= - (GPIO_PAR_FECI2C_EMDC_U2TXD | GPIO_PAR_FECI2C_EMDIO_U2RXD); + clrbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_EMDC_MASK | GPIO_PAR_FECI2C_EMDIO_MASK); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_EMDC_U2TXD | GPIO_PAR_FECI2C_EMDIO_U2RXD); #endif break; } @@ -163,15 +168,16 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; if (setclear) { - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_EMDC_FECEMDC | - GPIO_PAR_FECI2C_EMDIO_FECEMDIO); + setbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_EMDC_FECEMDC | + GPIO_PAR_FECI2C_EMDIO_FECEMDIO); } else { - gpio->par_feci2c &= - ~(GPIO_PAR_FECI2C_EMDC_MASK | GPIO_PAR_FECI2C_EMDIO_MASK); + clrbits_8(&gpio->par_feci2c, + GPIO_PAR_FECI2C_EMDC_MASK | + GPIO_PAR_FECI2C_EMDIO_MASK); } return 0; diff --git a/arch/m68k/cpu/mcf523x/interrupts.c b/arch/m68k/cpu/mcf523x/interrupts.c index db5ccdf..76115a4 100644 --- a/arch/m68k/cpu/mcf523x/interrupts.c +++ b/arch/m68k/cpu/mcf523x/interrupts.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -25,13 +25,14 @@ /* CPU specific interrupt routine */ #include #include +#include int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ - intp->imrl0 |= 0x1; + setbits_be32(&intp->imrl0, 0x1); enable_interrupts(); return 0; @@ -40,10 +41,10 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrl0 &= ~INTC_IPRL_INT0; - intp->imrl0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrl0, INTC_IPRL_INT0); + clrbits_be32(&intp->imrl0, CONFIG_SYS_TMRINTR_MASK); } #endif diff --git a/arch/m68k/cpu/mcf523x/speed.c b/arch/m68k/cpu/mcf523x/speed.c index 6096ba4..e2a6ae3 100644 --- a/arch/m68k/cpu/mcf523x/speed.c +++ b/arch/m68k/cpu/mcf523x/speed.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -29,6 +29,7 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; /* @@ -36,11 +37,12 @@ DECLARE_GLOBAL_DATA_PTR; */ int get_clocks(void) { - volatile pll_t *pll = (volatile pll_t *)(MMAP_PLL); + pll_t *pll = (pll_t *)(MMAP_PLL); - pll->syncr = PLL_SYNCR_MFD(1); + out_be32(&pll->syncr, PLL_SYNCR_MFD(1)); - while (!(pll->synsr & PLL_SYNSR_LOCK)); + while (!(in_be32(&pll->synsr) & PLL_SYNSR_LOCK)) + ; gd->bus_clk = CONFIG_SYS_CLK; gd->cpu_clk = (gd->bus_clk * 2); diff --git a/board/freescale/m5235evb/m5235evb.c b/board/freescale/m5235evb/m5235evb.c index b9e6126..e9a568e 100644 --- a/board/freescale/m5235evb/m5235evb.c +++ b/board/freescale/m5235evb/m5235evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -39,8 +40,8 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); - volatile gpio_t *gpio = (volatile gpio_t *)(MMAP_GPIO); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); + gpio_t *gpio = (gpio_t *)(MMAP_GPIO); u32 dramsize, i, dramclk; /* @@ -48,14 +49,15 @@ phys_size_t initdram(int board_type) * the port-size of SDRAM. In this case it is necessary to enable * Data[15:0] on Port Address/Data. */ - gpio->par_ad = - GPIO_PAR_AD_ADDR23 | GPIO_PAR_AD_ADDR22 | GPIO_PAR_AD_ADDR21 | - GPIO_PAR_AD_DATAL; + out_8(&gpio->par_ad, + GPIO_PAR_AD_ADDR23 | GPIO_PAR_AD_ADDR22 | GPIO_PAR_AD_ADDR21 | + GPIO_PAR_AD_DATAL); /* Initialize PAR to enable SDRAM signals */ - gpio->par_sdram = - GPIO_PAR_SDRAM_SDWE | GPIO_PAR_SDRAM_SCAS | GPIO_PAR_SDRAM_SRAS | - GPIO_PAR_SDRAM_SCKE | GPIO_PAR_SDRAM_SDCS(3); + out_8(&gpio->par_sdram, + GPIO_PAR_SDRAM_SDWE | GPIO_PAR_SDRAM_SCAS | + GPIO_PAR_SDRAM_SRAS | GPIO_PAR_SDRAM_SCKE | + GPIO_PAR_SDRAM_SDCS(3)); dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; for (i = 0x13; i < 0x20; i++) { @@ -64,25 +66,28 @@ phys_size_t initdram(int board_type) } i--; - if (!(sdram->dacr0 & SDRAMC_DARCn_RE)) { + if (!(in_be32(&sdram->dacr0) & SDRAMC_DARCn_RE)) { dramclk = gd->bus_clk / (CONFIG_SYS_HZ * CONFIG_SYS_HZ); /* Initialize DRAM Control Register: DCR */ - sdram->dcr = SDRAMC_DCR_RTIM_9CLKS | - SDRAMC_DCR_RTIM_6CLKS | SDRAMC_DCR_RC((15 * dramclk) >> 4); + out_be16(&sdram->dcr, SDRAMC_DCR_RTIM_9CLKS | + SDRAMC_DCR_RTIM_6CLKS | + SDRAMC_DCR_RC((15 * dramclk) >> 4)); /* Initialize DACR0 */ - sdram->dacr0 = - SDRAMC_DARCn_BA(CONFIG_SYS_SDRAM_BASE) | SDRAMC_DARCn_CASL_C1 | - SDRAMC_DARCn_CBM_CMD20 | SDRAMC_DARCn_PS_32; + out_be32(&sdram->dacr0, + SDRAMC_DARCn_BA(CONFIG_SYS_SDRAM_BASE) | + SDRAMC_DARCn_CASL_C1 | SDRAMC_DARCn_CBM_CMD20 | + SDRAMC_DARCn_PS_32); asm("nop"); /* Initialize DMR0 */ - sdram->dmr0 = ((dramsize - 1) & 0xFFFC0000) | SDRAMC_DMRn_V; + out_be32(&sdram->dmr0, + ((dramsize - 1) & 0xFFFC0000) | SDRAMC_DMRn_V); asm("nop"); /* Set IP (bit 3) in DACR */ - sdram->dacr0 |= SDRAMC_DARCn_IP; + setbits_be32(&sdram->dacr0, SDRAMC_DARCn_IP); /* Wait 30ns to allow banks to precharge */ for (i = 0; i < 5; i++) { @@ -93,7 +98,7 @@ phys_size_t initdram(int board_type) *(u32 *) (CONFIG_SYS_SDRAM_BASE) = 0xA5A59696; /* Set RE (bit 15) in DACR */ - sdram->dacr0 |= SDRAMC_DARCn_RE; + setbits_be32(&sdram->dacr0, SDRAMC_DARCn_RE); /* Wait for at least 8 auto refresh cycles to occur */ for (i = 0; i < 0x2000; i++) { @@ -101,7 +106,7 @@ phys_size_t initdram(int board_type) } /* Finish the configuration by issuing the MRS. */ - sdram->dacr0 |= SDRAMC_DARCn_IMRS; + setbits_be32(&sdram->dacr0, SDRAMC_DARCn_IMRS); asm("nop"); /* Write to the SDRAM Mode Register */ -- cgit v1.1 From a4110eecf2944b2f8b47f38273cc3730ddd394a3 Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Mon, 26 Mar 2012 21:49:07 +0000 Subject: ColdFire: Clean up checkpatch warnings for MCF547x and MCF548x Signed-off-by: Alison Wang --- arch/m68k/cpu/mcf547x_8x/cpu.c | 38 ++++++++-------- arch/m68k/cpu/mcf547x_8x/cpu_init.c | 84 ++++++++++++++++++----------------- arch/m68k/cpu/mcf547x_8x/interrupts.c | 15 ++++--- arch/m68k/cpu/mcf547x_8x/pci.c | 59 ++++++++++++------------ arch/m68k/cpu/mcf547x_8x/slicetimer.c | 38 +++++++++------- board/freescale/m547xevb/m547xevb.c | 34 +++++++------- board/freescale/m548xevb/m548xevb.c | 34 +++++++------- 7 files changed, 158 insertions(+), 144 deletions(-) diff --git a/arch/m68k/cpu/mcf547x_8x/cpu.c b/arch/m68k/cpu/mcf547x_8x/cpu.c index 7590f2c..157a8e4 100644 --- a/arch/m68k/cpu/mcf547x_8x/cpu.c +++ b/arch/m68k/cpu/mcf547x_8x/cpu.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -31,19 +31,20 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); - gptmr->pre = 10; - gptmr->cnt = 1; + out_be16(&gptmr->pre, 10); + out_be16(&gptmr->cnt, 1); /* enable watchdog, set timeout to 0 and wait */ - gptmr->mode = GPT_TMS_SGPIO; - gptmr->ctrl = GPT_CTRL_WDEN | GPT_CTRL_CE; + out_8(&gptmr->mode, GPT_TMS_SGPIO); + out_8(&gptmr->ctrl, GPT_CTRL_WDEN | GPT_CTRL_CE); /* we don't return! */ return 1; @@ -51,12 +52,12 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int checkcpu(void) { - volatile siu_t *siu = (siu_t *) MMAP_SIU; + siu_t *siu = (siu_t *) MMAP_SIU; u16 id = 0; puts("CPU: "); - switch ((siu->jtagid & 0x000FF000) >> 12) { + switch ((in_be32(&siu->jtagid) & 0x000FF000) >> 12) { case 0x0C: id = 5485; break; @@ -111,18 +112,18 @@ int checkcpu(void) /* Called by macro WATCHDOG_RESET */ void hw_watchdog_reset(void) { - volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); - gptmr->ocpw = 0xa5; + out_8(&gptmr->ocpw, 0xa5); } int watchdog_disable(void) { - volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); /* UserManual, once the wdog is disabled, wdog cannot be re-enabled */ - gptmr->mode = 0; - gptmr->ctrl = 0; + out_8(&gptmr->mode, 0); + out_8(&gptmr->ctrl, 0); puts("WATCHDOG:disabled\n"); @@ -131,14 +132,13 @@ int watchdog_disable(void) int watchdog_init(void) { + gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); - volatile gptmr_t *gptmr = (gptmr_t *) (MMAP_GPTMR); + out_be16(&gptmr->pre, CONFIG_WATCHDOG_TIMEOUT); + out_be16(&gptmr->cnt, CONFIG_SYS_TIMER_PRESCALER * 1000); - gptmr->pre = CONFIG_WATCHDOG_TIMEOUT; - gptmr->cnt = CONFIG_SYS_TIMER_PRESCALER * 1000; - - gptmr->mode = GPT_TMS_SGPIO; - gptmr->ctrl = GPT_CTRL_CE | GPT_CTRL_WDEN; + out_8(&gptmr->mode, GPT_TMS_SGPIO); + out_8(&gptmr->ctrl, GPT_CTRL_CE | GPT_CTRL_WDEN); puts("WATCHDOG:enabled\n"); return (0); diff --git a/arch/m68k/cpu/mcf547x_8x/cpu_init.c b/arch/m68k/cpu/mcf547x_8x/cpu_init.c index 60c9126..4eb8a7c 100644 --- a/arch/m68k/cpu/mcf547x_8x/cpu_init.c +++ b/arch/m68k/cpu/mcf547x_8x/cpu_init.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2007 Freescale Semiconductor, Inc. + * (C) Copyright 2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,6 +28,7 @@ #include #include #include +#include #if defined(CONFIG_CMD_NET) #include @@ -44,58 +45,59 @@ */ void cpu_init_f(void) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - volatile xlbarb_t *xlbarb = (volatile xlbarb_t *) MMAP_XARB; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + xlbarb_t *xlbarb = (xlbarb_t *) MMAP_XARB; - xlbarb->adrto = 0x2000; - xlbarb->datto = 0x2500; - xlbarb->busto = 0x3000; + out_be32(&xlbarb->adrto, 0x2000); + out_be32(&xlbarb->datto, 0x2500); + out_be32(&xlbarb->busto, 0x3000); - xlbarb->cfg = XARB_CFG_AT | XARB_CFG_DT; + out_be32(&xlbarb->cfg, XARB_CFG_AT | XARB_CFG_DT); /* Master Priority Enable */ - xlbarb->prien = 0xff; - xlbarb->pri = 0; + out_be32(&xlbarb->prien, 0xff); + out_be32(&xlbarb->pri, 0); #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) && defined(CONFIG_SYS_CS1_CTRL)) - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) && defined(CONFIG_SYS_CS2_CTRL)) - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) && defined(CONFIG_SYS_CS3_CTRL)) - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) && defined(CONFIG_SYS_CS4_CTRL)) - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) && defined(CONFIG_SYS_CS5_CTRL)) - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif #ifdef CONFIG_FSL_I2C - gpio->par_feci2cirq = GPIO_PAR_FECI2CIRQ_SCL | GPIO_PAR_FECI2CIRQ_SDA; + out_be16(&gpio->par_feci2cirq, + GPIO_PAR_FECI2CIRQ_SCL | GPIO_PAR_FECI2CIRQ_SDA); #endif icache_enable(); @@ -115,44 +117,44 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile u8 *pscsicr = (u8 *) (CONFIG_SYS_UART_BASE + 0x40); + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + u8 *pscsicr = (u8 *) (CONFIG_SYS_UART_BASE + 0x40); /* Setup Ports: */ switch (port) { case 0: - gpio->par_psc0 = (GPIO_PAR_PSC0_TXD0 | GPIO_PAR_PSC0_RXD0); + out_8(&gpio->par_psc0, GPIO_PAR_PSC0_TXD0 | GPIO_PAR_PSC0_RXD0); break; case 1: - gpio->par_psc1 = (GPIO_PAR_PSC1_TXD1 | GPIO_PAR_PSC1_RXD1); + out_8(&gpio->par_psc1, GPIO_PAR_PSC1_TXD1 | GPIO_PAR_PSC1_RXD1); break; case 2: - gpio->par_psc2 = (GPIO_PAR_PSC2_TXD2 | GPIO_PAR_PSC2_RXD2); + out_8(&gpio->par_psc2, GPIO_PAR_PSC2_TXD2 | GPIO_PAR_PSC2_RXD2); break; case 3: - gpio->par_psc3 = (GPIO_PAR_PSC3_TXD3 | GPIO_PAR_PSC3_RXD3); + out_8(&gpio->par_psc3, GPIO_PAR_PSC3_TXD3 | GPIO_PAR_PSC3_RXD3); break; } - *pscsicr &= 0xF8; + clrbits_8(pscsicr, 0x07); } #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; struct fec_info_dma *info = (struct fec_info_dma *)dev->priv; if (setclear) { if (info->iobase == CONFIG_SYS_FEC0_IOBASE) - gpio->par_feci2cirq |= 0xF000; + setbits_be16(&gpio->par_feci2cirq, 0xf000); else - gpio->par_feci2cirq |= 0x0FC0; + setbits_be16(&gpio->par_feci2cirq, 0x0fc0); } else { if (info->iobase == CONFIG_SYS_FEC0_IOBASE) - gpio->par_feci2cirq &= 0x0FFF; + clrbits_be16(&gpio->par_feci2cirq, 0xf000); else - gpio->par_feci2cirq &= 0xF03F; + clrbits_be16(&gpio->par_feci2cirq, 0x0fc0); } return 0; } diff --git a/arch/m68k/cpu/mcf547x_8x/interrupts.c b/arch/m68k/cpu/mcf547x_8x/interrupts.c index 76be876..d215438 100644 --- a/arch/m68k/cpu/mcf547x_8x/interrupts.c +++ b/arch/m68k/cpu/mcf547x_8x/interrupts.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -25,14 +25,15 @@ /* CPU specific interrupt routine */ #include #include +#include int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ - intp->imrh0 |= 0xFFFFFFFF; - intp->imrl0 |= 0xFFFFFFFF; + setbits_be32(&intp->imrh0, 0xffffffff); + setbits_be32(&intp->imrl0, 0xffffffff); enable_interrupts(); @@ -42,9 +43,9 @@ int interrupt_init(void) #if defined(CONFIG_SLTTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrh0, CONFIG_SYS_TMRINTR_MASK); } #endif diff --git a/arch/m68k/cpu/mcf547x_8x/pci.c b/arch/m68k/cpu/mcf547x_8x/pci.c index f867dc1..1a81e3f 100644 --- a/arch/m68k/cpu/mcf547x_8x/pci.c +++ b/arch/m68k/cpu/mcf547x_8x/pci.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -88,53 +88,56 @@ int pci_read_cfg_dword(struct pci_controller *hose, pci_dev_t dev, void pci_mcf547x_8x_init(struct pci_controller *hose) { - volatile pci_t *pci = (volatile pci_t *) MMAP_PCI; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + pci_t *pci = (pci_t *) MMAP_PCI; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Port configuration */ - gpio->par_pcibg = - GPIO_PAR_PCIBG_PCIBG0(3) | GPIO_PAR_PCIBG_PCIBG1(3) | - GPIO_PAR_PCIBG_PCIBG2(3) | GPIO_PAR_PCIBG_PCIBG3(3) | - GPIO_PAR_PCIBG_PCIBG4(3); - gpio->par_pcibr = - GPIO_PAR_PCIBR_PCIBR0(3) | GPIO_PAR_PCIBR_PCIBR1(3) | - GPIO_PAR_PCIBR_PCIBR2(3) | GPIO_PAR_PCIBR_PCIBR3(3) | - GPIO_PAR_PCIBR_PCIBR4(3); + out_be16(&gpio->par_pcibg, + GPIO_PAR_PCIBG_PCIBG0(3) | GPIO_PAR_PCIBG_PCIBG1(3) | + GPIO_PAR_PCIBG_PCIBG2(3) | GPIO_PAR_PCIBG_PCIBG3(3) | + GPIO_PAR_PCIBG_PCIBG4(3)); + out_be16(&gpio->par_pcibr, + GPIO_PAR_PCIBR_PCIBR0(3) | GPIO_PAR_PCIBR_PCIBR1(3) | + GPIO_PAR_PCIBR_PCIBR2(3) | GPIO_PAR_PCIBR_PCIBR3(3) | + GPIO_PAR_PCIBR_PCIBR4(3)); /* Assert reset bit */ - pci->gscr |= PCI_GSCR_PR; + setbits_be32(&pci->gscr, PCI_GSCR_PR); - pci->tcr1 = PCI_TCR1_P; + out_be32(&pci->tcr1, PCI_TCR1_P); /* Initiator windows */ - pci->iw0btar = CONFIG_SYS_PCI_MEM_PHYS | (CONFIG_SYS_PCI_MEM_PHYS >> 16); - pci->iw1btar = CONFIG_SYS_PCI_IO_PHYS | (CONFIG_SYS_PCI_IO_PHYS >> 16); - pci->iw2btar = CONFIG_SYS_PCI_CFG_PHYS | (CONFIG_SYS_PCI_CFG_PHYS >> 16); + out_be32(&pci->iw0btar, + CONFIG_SYS_PCI_MEM_PHYS | (CONFIG_SYS_PCI_MEM_PHYS >> 16)); + out_be32(&pci->iw1btar, + CONFIG_SYS_PCI_IO_PHYS | (CONFIG_SYS_PCI_IO_PHYS >> 16)); + out_be32(&pci->iw2btar, + CONFIG_SYS_PCI_CFG_PHYS | (CONFIG_SYS_PCI_CFG_PHYS >> 16)); - pci->iwcr = - PCI_IWCR_W0C_EN | PCI_IWCR_W1C_EN | PCI_IWCR_W1C_IO | - PCI_IWCR_W2C_EN | PCI_IWCR_W2C_IO; + out_be32(&pci->iwcr, + PCI_IWCR_W0C_EN | PCI_IWCR_W1C_EN | PCI_IWCR_W1C_IO | + PCI_IWCR_W2C_EN | PCI_IWCR_W2C_IO); - pci->icr = 0; + out_be32(&pci->icr, 0); /* Enable bus master and mem access */ - pci->scr = PCI_SCR_B | PCI_SCR_M; + out_be32(&pci->scr, PCI_SCR_B | PCI_SCR_M); /* Cache line size and master latency */ - pci->cr1 = PCI_CR1_CLS(8) | PCI_CR1_LTMR(0xF8); - pci->cr2 = 0; + out_be32(&pci->cr1, PCI_CR1_CLS(8) | PCI_CR1_LTMR(0xf8)); + out_be32(&pci->cr2, 0); #ifdef CONFIG_SYS_PCI_BAR0 - pci->bar0 = PCI_BAR_BAR0(CONFIG_SYS_PCI_BAR0); - pci->tbatr0a = CONFIG_SYS_PCI_TBATR0 | PCI_TBATR_EN; + out_be32(&pci->bar0, PCI_BAR_BAR0(CONFIG_SYS_PCI_BAR0)); + out_be32(&pci->tbatr0a, CONFIG_SYS_PCI_TBATR0 | PCI_TBATR_EN); #endif #ifdef CONFIG_SYS_PCI_BAR1 - pci->bar1 = PCI_BAR_BAR1(CONFIG_SYS_PCI_BAR1); - pci->tbatr1a = CONFIG_SYS_PCI_TBATR1 | PCI_TBATR_EN; + out_be32(&pci->bar1, PCI_BAR_BAR1(CONFIG_SYS_PCI_BAR1)); + out_be32(&pci->tbatr1a, CONFIG_SYS_PCI_TBATR1 | PCI_TBATR_EN); #endif /* Deassert reset bit */ - pci->gscr &= ~PCI_GSCR_PR; + clrbits_be32(&pci->gscr, PCI_GSCR_PR); udelay(1000); /* Enable PCI bus master support */ diff --git a/arch/m68k/cpu/mcf547x_8x/slicetimer.c b/arch/m68k/cpu/mcf547x_8x/slicetimer.c index ee2e35b..25dd2ae 100644 --- a/arch/m68k/cpu/mcf547x_8x/slicetimer.c +++ b/arch/m68k/cpu/mcf547x_8x/slicetimer.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2007 Freescale Semiconductor, Inc. + * (C) Copyright 2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -25,6 +25,7 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -42,31 +43,32 @@ extern void dtimer_intr_setup(void); void __udelay(unsigned long usec) { - volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE); + slt_t *timerp = (slt_t *) (CONFIG_SYS_UDELAY_BASE); u32 now, freq; /* 1 us period */ freq = CONFIG_SYS_TIMER_PRESCALER; - timerp->cr = 0; /* Disable */ - timerp->tcnt = usec * freq; - timerp->cr = SLT_CR_TEN; + /* Disable */ + out_be32(&timerp->cr, 0); + out_be32(&timerp->tcnt, usec * freq); + out_be32(&timerp->cr, SLT_CR_TEN); - now = timerp->cnt; + now = in_be32(&timerp->cnt); while (now != 0) - now = timerp->cnt; + now = in_be32(&timerp->cnt); - timerp->sr |= SLT_SR_ST; - timerp->cr = 0; + setbits_be32(&timerp->sr, SLT_SR_ST); + out_be32(&timerp->cr, 0); } void dtimer_interrupt(void *not_used) { - volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); + slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); /* check for timer interrupt asserted */ if ((CONFIG_SYS_TMRPND_REG & CONFIG_SYS_TMRINTR_MASK) == CONFIG_SYS_TMRINTR_PEND) { - timerp->sr |= SLT_SR_ST; + setbits_be32(&timerp->sr, SLT_SR_ST); timestamp++; return; } @@ -74,25 +76,27 @@ void dtimer_interrupt(void *not_used) int timer_init(void) { - volatile slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); + slt_t *timerp = (slt_t *) (CONFIG_SYS_TMR_BASE); timestamp = 0; - timerp->cr = 0; /* disable timer */ - timerp->tcnt = 0; - timerp->sr = SLT_SR_BE | SLT_SR_ST; /* clear status */ + /* disable timer */ + out_be32(&timerp->cr, 0); + out_be32(&timerp->tcnt, 0); + /* clear status */ + out_be32(&timerp->sr, SLT_SR_BE | SLT_SR_ST); /* initialize and enable timer interrupt */ irq_install_handler(CONFIG_SYS_TMRINTR_NO, dtimer_interrupt, 0); /* Interrupt every ms */ - timerp->tcnt = 1000 * CONFIG_SYS_TIMER_PRESCALER; + out_be32(&timerp->tcnt, 1000 * CONFIG_SYS_TIMER_PRESCALER); dtimer_intr_setup(); /* set a period of 1us, set timer mode to restart and enable timer and interrupt */ - timerp->cr = SLT_CR_RUN | SLT_CR_IEN | SLT_CR_TEN; + out_be32(&timerp->cr, SLT_CR_RUN | SLT_CR_IEN | SLT_CR_TEN); return 0; } diff --git a/board/freescale/m547xevb/m547xevb.c b/board/freescale/m547xevb/m547xevb.c index 9f1ec38..fd9bddd 100644 --- a/board/freescale/m547xevb/m547xevb.c +++ b/board/freescale/m547xevb/m547xevb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,6 +28,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -40,14 +41,14 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile siu_t *siu = (siu_t *) (MMAP_SIU); - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + siu_t *siu = (siu_t *) (MMAP_SIU); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; #ifdef CONFIG_SYS_DRAMSZ1 u32 temp; #endif - siu->drv = CONFIG_SYS_SDRAM_DRVSTRENGTH; + out_be32(&siu->drv, CONFIG_SYS_SDRAM_DRVSTRENGTH); dramsize = CONFIG_SYS_DRAMSZ * 0x100000; for (i = 0x13; i < 0x20; i++) { @@ -55,7 +56,7 @@ phys_size_t initdram(int board_type) break; } i--; - siu->cs0cfg = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&siu->cs0cfg, CONFIG_SYS_SDRAM_BASE | i); #ifdef CONFIG_SYS_DRAMSZ1 temp = CONFIG_SYS_DRAMSZ1 * 0x100000; @@ -65,31 +66,32 @@ phys_size_t initdram(int board_type) } i--; dramsize += temp; - siu->cs1cfg = ((CONFIG_SYS_SDRAM_BASE + temp) | i); + out_be32(&siu->cs1cfg, (CONFIG_SYS_SDRAM_BASE + temp) | i); #endif - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_EMOD; - sdram->mode = (CONFIG_SYS_SDRAM_MODE | 0x04000000); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE | 0x04000000); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00); udelay(100); diff --git a/board/freescale/m548xevb/m548xevb.c b/board/freescale/m548xevb/m548xevb.c index fbc0888..fb216d8 100644 --- a/board/freescale/m548xevb/m548xevb.c +++ b/board/freescale/m548xevb/m548xevb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,6 +28,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -40,14 +41,14 @@ int checkboard(void) phys_size_t initdram(int board_type) { - volatile siu_t *siu = (siu_t *) (MMAP_SIU); - volatile sdram_t *sdram = (volatile sdram_t *)(MMAP_SDRAM); + siu_t *siu = (siu_t *) (MMAP_SIU); + sdram_t *sdram = (sdram_t *)(MMAP_SDRAM); u32 dramsize, i; #ifdef CONFIG_SYS_DRAMSZ1 u32 temp; #endif - siu->drv = CONFIG_SYS_SDRAM_DRVSTRENGTH; + out_be32(&siu->drv, CONFIG_SYS_SDRAM_DRVSTRENGTH); dramsize = CONFIG_SYS_DRAMSZ * 0x100000; for (i = 0x13; i < 0x20; i++) { @@ -55,7 +56,7 @@ phys_size_t initdram(int board_type) break; } i--; - siu->cs0cfg = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&siu->cs0cfg, CONFIG_SYS_SDRAM_BASE | i); #ifdef CONFIG_SYS_DRAMSZ1 temp = CONFIG_SYS_DRAMSZ1 * 0x100000; @@ -65,31 +66,32 @@ phys_size_t initdram(int board_type) } i--; dramsize += temp; - siu->cs1cfg = ((CONFIG_SYS_SDRAM_BASE + temp) | i); + out_be32(&siu->cs1cfg, (CONFIG_SYS_SDRAM_BASE + temp) | i); #endif - sdram->cfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->cfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->cfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->cfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Issue LEMR */ - sdram->mode = CONFIG_SYS_SDRAM_EMOD; - sdram->mode = (CONFIG_SYS_SDRAM_MODE | 0x04000000); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_EMOD); + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE | 0x04000000); udelay(500); /* Issue PALL */ - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL | 2); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 2); /* Perform two refresh cycles */ - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->ctrl = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->ctrl, CONFIG_SYS_SDRAM_CTRL | 4); - sdram->mode = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->mode, CONFIG_SYS_SDRAM_MODE); - sdram->ctrl = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00; + out_be32(&sdram->ctrl, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000F00); udelay(100); -- cgit v1.1 From 198cafbf2cab9851ee5dd8d24d268d0ccc0fe3bd Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Mon, 26 Mar 2012 21:49:08 +0000 Subject: ColdFire: Clean up checkpatch warnings for MCF54451 and MCF54455 Signed-off-by: Alison Wang --- arch/m68k/cpu/mcf5445x/cpu.c | 13 +- arch/m68k/cpu/mcf5445x/cpu_init.c | 215 +++++++++++++++++----------------- arch/m68k/cpu/mcf5445x/interrupts.c | 15 +-- arch/m68k/cpu/mcf5445x/pci.c | 74 ++++++------ arch/m68k/cpu/mcf5445x/speed.c | 71 +++++------ board/freescale/m54451evb/m54451evb.c | 32 ++--- board/freescale/m54455evb/m54455evb.c | 90 +++++++------- 7 files changed, 267 insertions(+), 243 deletions(-) diff --git a/arch/m68k/cpu/mcf5445x/cpu.c b/arch/m68k/cpu/mcf5445x/cpu.c index 323a54e..adfc708 100644 --- a/arch/m68k/cpu/mcf5445x/cpu.c +++ b/arch/m68k/cpu/mcf5445x/cpu.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -31,14 +31,15 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - volatile rcm_t *rcm = (rcm_t *) (MMAP_RCM); + rcm_t *rcm = (rcm_t *) (MMAP_RCM); udelay(1000); - rcm->rcr |= RCM_RCR_SOFTRST; + setbits_8(&rcm->rcr, RCM_RCR_SOFTRST); /* we don't return! */ return 0; @@ -46,14 +47,14 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int checkcpu(void) { - volatile ccm_t *ccm = (ccm_t *) MMAP_CCM; + ccm_t *ccm = (ccm_t *) MMAP_CCM; u16 msk; u16 id = 0; u8 ver; puts("CPU: "); - msk = (ccm->cir >> 6); - ver = (ccm->cir & 0x003f); + msk = (in_be16(&ccm->cir) >> 6); + ver = (in_be16(&ccm->cir) & 0x003f); switch (msk) { case 0x48: id = 54455; diff --git a/arch/m68k/cpu/mcf5445x/cpu_init.c b/arch/m68k/cpu/mcf5445x/cpu_init.c index fdcd185..3f9209f 100644 --- a/arch/m68k/cpu/mcf5445x/cpu_init.c +++ b/arch/m68k/cpu/mcf5445x/cpu_init.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * (C) Copyright 2004-2007 Freescale Semiconductor, Inc. + * (C) Copyright 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -30,6 +30,7 @@ #include #include #include +#include #if defined(CONFIG_CMD_NET) #include @@ -46,64 +47,64 @@ */ void cpu_init_f(void) { - volatile scm1_t *scm1 = (scm1_t *) MMAP_SCM1; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; - - scm1->mpr = 0x77777777; - scm1->pacra = 0; - scm1->pacrb = 0; - scm1->pacrc = 0; - scm1->pacrd = 0; - scm1->pacre = 0; - scm1->pacrf = 0; - scm1->pacrg = 0; + scm1_t *scm1 = (scm1_t *) MMAP_SCM1; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; + + out_be32(&scm1->mpr, 0x77777777); + out_be32(&scm1->pacra, 0); + out_be32(&scm1->pacrb, 0); + out_be32(&scm1->pacrc, 0); + out_be32(&scm1->pacrd, 0); + out_be32(&scm1->pacre, 0); + out_be32(&scm1->pacrf, 0); + out_be32(&scm1->pacrg, 0); /* FlexBus */ - gpio->par_be = - GPIO_PAR_BE_BE3_BE3 | GPIO_PAR_BE_BE2_BE2 | GPIO_PAR_BE_BE1_BE1 | - GPIO_PAR_BE_BE0_BE0; - gpio->par_fbctl = - GPIO_PAR_FBCTL_OE | GPIO_PAR_FBCTL_TA_TA | GPIO_PAR_FBCTL_RW_RW | - GPIO_PAR_FBCTL_TS_TS; + out_8(&gpio->par_be, + GPIO_PAR_BE_BE3_BE3 | GPIO_PAR_BE_BE2_BE2 | + GPIO_PAR_BE_BE1_BE1 | GPIO_PAR_BE_BE0_BE0); + out_8(&gpio->par_fbctl, + GPIO_PAR_FBCTL_OE | GPIO_PAR_FBCTL_TA_TA | + GPIO_PAR_FBCTL_RW_RW | GPIO_PAR_FBCTL_TS_TS); #if !defined(CONFIG_CF_SBF) #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) && defined(CONFIG_SYS_CS0_CTRL)) - fbcs->csar0 = CONFIG_SYS_CS0_BASE; - fbcs->cscr0 = CONFIG_SYS_CS0_CTRL; - fbcs->csmr0 = CONFIG_SYS_CS0_MASK; + out_be32(&fbcs->csar0, CONFIG_SYS_CS0_BASE); + out_be32(&fbcs->cscr0, CONFIG_SYS_CS0_CTRL); + out_be32(&fbcs->csmr0, CONFIG_SYS_CS0_MASK); #endif #endif #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) && defined(CONFIG_SYS_CS1_CTRL)) /* Latch chipselect */ - fbcs->csar1 = CONFIG_SYS_CS1_BASE; - fbcs->cscr1 = CONFIG_SYS_CS1_CTRL; - fbcs->csmr1 = CONFIG_SYS_CS1_MASK; + out_be32(&fbcs->csar1, CONFIG_SYS_CS1_BASE); + out_be32(&fbcs->cscr1, CONFIG_SYS_CS1_CTRL); + out_be32(&fbcs->csmr1, CONFIG_SYS_CS1_MASK); #endif #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) && defined(CONFIG_SYS_CS2_CTRL)) - fbcs->csar2 = CONFIG_SYS_CS2_BASE; - fbcs->cscr2 = CONFIG_SYS_CS2_CTRL; - fbcs->csmr2 = CONFIG_SYS_CS2_MASK; + out_be32(&fbcs->csar2, CONFIG_SYS_CS2_BASE); + out_be32(&fbcs->cscr2, CONFIG_SYS_CS2_CTRL); + out_be32(&fbcs->csmr2, CONFIG_SYS_CS2_MASK); #endif #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) && defined(CONFIG_SYS_CS3_CTRL)) - fbcs->csar3 = CONFIG_SYS_CS3_BASE; - fbcs->cscr3 = CONFIG_SYS_CS3_CTRL; - fbcs->csmr3 = CONFIG_SYS_CS3_MASK; + out_be32(&fbcs->csar3, CONFIG_SYS_CS3_BASE); + out_be32(&fbcs->cscr3, CONFIG_SYS_CS3_CTRL); + out_be32(&fbcs->csmr3, CONFIG_SYS_CS3_MASK); #endif #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) && defined(CONFIG_SYS_CS4_CTRL)) - fbcs->csar4 = CONFIG_SYS_CS4_BASE; - fbcs->cscr4 = CONFIG_SYS_CS4_CTRL; - fbcs->csmr4 = CONFIG_SYS_CS4_MASK; + out_be32(&fbcs->csar4, CONFIG_SYS_CS4_BASE); + out_be32(&fbcs->cscr4, CONFIG_SYS_CS4_CTRL); + out_be32(&fbcs->csmr4, CONFIG_SYS_CS4_MASK); #endif #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) && defined(CONFIG_SYS_CS5_CTRL)) - fbcs->csar5 = CONFIG_SYS_CS5_BASE; - fbcs->cscr5 = CONFIG_SYS_CS5_CTRL; - fbcs->csmr5 = CONFIG_SYS_CS5_MASK; + out_be32(&fbcs->csar5, CONFIG_SYS_CS5_BASE); + out_be32(&fbcs->cscr5, CONFIG_SYS_CS5_CTRL); + out_be32(&fbcs->csmr5, CONFIG_SYS_CS5_MASK); #endif /* @@ -115,7 +116,8 @@ void cpu_init_f(void) setvbr(CONFIG_SYS_CS0_BASE); #ifdef CONFIG_FSL_I2C - gpio->par_feci2c = GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA; + out_be16(&gpio->par_feci2c, + GPIO_PAR_FECI2C_SCL_SCL | GPIO_PAR_FECI2C_SDA_SDA); #endif icache_enable(); @@ -127,11 +129,11 @@ void cpu_init_f(void) int cpu_init_r(void) { #ifdef CONFIG_MCFRTC - volatile rtc_t *rtc = (volatile rtc_t *)(CONFIG_SYS_MCFRTC_BASE); - volatile rtcex_t *rtcex = (volatile rtcex_t *)&rtc->extended; + rtc_t *rtc = (rtc_t *)(CONFIG_SYS_MCFRTC_BASE); + rtcex_t *rtcex = (rtcex_t *)&rtc->extended; - rtcex->gocu = (CONFIG_SYS_RTC_OSCILLATOR >> 16) & 0xFFFF; - rtcex->gocl = CONFIG_SYS_RTC_OSCILLATOR & 0xFFFF; + out_be32(&rtcex->gocu, (CONFIG_SYS_RTC_OSCILLATOR >> 16) & 0xffff); + out_be32(&rtcex->gocl, CONFIG_SYS_RTC_OSCILLATOR & 0xffff); #endif return (0); @@ -139,40 +141,40 @@ int cpu_init_r(void) void uart_port_conf(int port) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; /* Setup Ports: */ switch (port) { case 0: - gpio->par_uart &= - ~(GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); - gpio->par_uart |= - (GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); + clrbits_8(&gpio->par_uart, + GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); + setbits_8(&gpio->par_uart, + GPIO_PAR_UART_U0TXD_U0TXD | GPIO_PAR_UART_U0RXD_U0RXD); break; case 1: #ifdef CONFIG_SYS_UART1_PRI_GPIO - gpio->par_uart &= - ~(GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); - gpio->par_uart |= - (GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); + clrbits_8(&gpio->par_uart, + GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); + setbits_8(&gpio->par_uart, + GPIO_PAR_UART_U1TXD_U1TXD | GPIO_PAR_UART_U1RXD_U1RXD); #elif defined(CONFIG_SYS_UART1_ALT1_GPIO) - gpio->par_ssi &= - (GPIO_PAR_SSI_SRXD_UNMASK | GPIO_PAR_SSI_STXD_UNMASK); - gpio->par_ssi |= - (GPIO_PAR_SSI_SRXD_U1RXD | GPIO_PAR_SSI_STXD_U1TXD); + clrbits_be16(&gpio->par_ssi, + ~(GPIO_PAR_SSI_SRXD_UNMASK | GPIO_PAR_SSI_STXD_UNMASK)); + setbits_be16(&gpio->par_ssi, + GPIO_PAR_SSI_SRXD_U1RXD | GPIO_PAR_SSI_STXD_U1TXD); #endif break; case 2: #if defined(CONFIG_SYS_UART2_ALT1_GPIO) - gpio->par_timer &= - (GPIO_PAR_TIMER_T3IN_UNMASK | GPIO_PAR_TIMER_T2IN_UNMASK); - gpio->par_timer |= - (GPIO_PAR_TIMER_T3IN_U2RXD | GPIO_PAR_TIMER_T2IN_U2TXD); + clrbits_8(&gpio->par_timer, + ~(GPIO_PAR_TIMER_T3IN_UNMASK | GPIO_PAR_TIMER_T2IN_UNMASK)); + setbits_8(&gpio->par_timer, + GPIO_PAR_TIMER_T3IN_U2RXD | GPIO_PAR_TIMER_T2IN_U2TXD); #elif defined(CONFIG_SYS_UART2_ALT2_GPIO) - gpio->par_timer &= - (GPIO_PAR_FECI2C_SCL_UNMASK | GPIO_PAR_FECI2C_SDA_UNMASK); - gpio->par_timer |= - (GPIO_PAR_FECI2C_SCL_U2TXD | GPIO_PAR_FECI2C_SDA_U2RXD); + clrbits_8(&gpio->par_timer, + ~(GPIO_PAR_FECI2C_SCL_UNMASK | GPIO_PAR_FECI2C_SDA_UNMASK)); + setbits_8(&gpio->par_timer, + GPIO_PAR_FECI2C_SCL_U2TXD | GPIO_PAR_FECI2C_SDA_U2RXD); #endif break; } @@ -181,43 +183,43 @@ void uart_port_conf(int port) #if defined(CONFIG_CMD_NET) int fecpin_setclear(struct eth_device *dev, int setclear) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; struct fec_info_s *info = (struct fec_info_s *)dev->priv; if (setclear) { #ifdef CONFIG_SYS_FEC_NO_SHARED_PHY if (info->iobase == CONFIG_SYS_FEC0_IOBASE) - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_MDC0_MDC0 | - GPIO_PAR_FECI2C_MDIO0_MDIO0); + setbits_be16(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC0_MDC0 | + GPIO_PAR_FECI2C_MDIO0_MDIO0); else - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_MDC1_MDC1 | - GPIO_PAR_FECI2C_MDIO1_MDIO1); + setbits_be16(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC1_MDC1 | + GPIO_PAR_FECI2C_MDIO1_MDIO1); #else - gpio->par_feci2c |= - (GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); + setbits_be16(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); #endif if (info->iobase == CONFIG_SYS_FEC0_IOBASE) - gpio->par_fec |= GPIO_PAR_FEC_FEC0_RMII_GPIO; + setbits_8(&gpio->par_fec, GPIO_PAR_FEC_FEC0_RMII_GPIO); else - gpio->par_fec |= GPIO_PAR_FEC_FEC1_RMII_ATA; + setbits_8(&gpio->par_fec, GPIO_PAR_FEC_FEC1_RMII_ATA); } else { - gpio->par_feci2c &= - ~(GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); + clrbits_be16(&gpio->par_feci2c, + GPIO_PAR_FECI2C_MDC0_MDC0 | GPIO_PAR_FECI2C_MDIO0_MDIO0); if (info->iobase == CONFIG_SYS_FEC0_IOBASE) { #ifdef CONFIG_SYS_FEC_FULL_MII - gpio->par_fec |= GPIO_PAR_FEC_FEC0_MII; + setbits_8(&gpio->par_fec, GPIO_PAR_FEC_FEC0_MII); #else - gpio->par_fec &= GPIO_PAR_FEC_FEC0_UNMASK; + clrbits_8(&gpio->par_fec, ~GPIO_PAR_FEC_FEC0_UNMASK); #endif } else { #ifdef CONFIG_SYS_FEC_FULL_MII - gpio->par_fec |= GPIO_PAR_FEC_FEC1_MII; + setbits_8(&gpio->par_fec, GPIO_PAR_FEC_FEC1_MII); #else - gpio->par_fec &= GPIO_PAR_FEC_FEC1_UNMASK; + clrbits_8(&gpio->par_fec, ~GPIO_PAR_FEC_FEC1_UNMASK); #endif } } @@ -228,43 +230,45 @@ int fecpin_setclear(struct eth_device *dev, int setclear) #ifdef CONFIG_CF_DSPI void cfspi_port_conf(void) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - gpio->par_dspi = GPIO_PAR_DSPI_SIN_SIN | GPIO_PAR_DSPI_SOUT_SOUT | - GPIO_PAR_DSPI_SCK_SCK; + out_8(&gpio->par_dspi, + GPIO_PAR_DSPI_SIN_SIN | + GPIO_PAR_DSPI_SOUT_SOUT | + GPIO_PAR_DSPI_SCK_SCK); } int cfspi_claim_bus(uint bus, uint cs) { - volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + dspi_t *dspi = (dspi_t *) MMAP_DSPI; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - if ((dspi->sr & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) + if ((in_be32(&dspi->sr) & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) return -1; /* Clear FIFO and resume transfer */ - dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); + clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF); switch (cs) { case 0: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0; - gpio->par_dspi |= GPIO_PAR_DSPI_PCS0_PCS0; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0); + setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0); break; case 1: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS1_PCS1; - gpio->par_dspi |= GPIO_PAR_DSPI_PCS1_PCS1; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1); + setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1); break; case 2: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS2_PCS2; - gpio->par_dspi |= GPIO_PAR_DSPI_PCS2_PCS2; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2); + setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2); break; case 3: - gpio->par_dma &= GPIO_PAR_DMA_DACK0_UNMASK; - gpio->par_dma |= GPIO_PAR_DMA_DACK0_PCS3; + clrbits_8(&gpio->par_dma, ~GPIO_PAR_DMA_DACK0_UNMASK); + setbits_8(&gpio->par_dma, GPIO_PAR_DMA_DACK0_PCS3); break; case 5: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS5_PCS5; - gpio->par_dspi |= GPIO_PAR_DSPI_PCS5_PCS5; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5); + setbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5); break; } @@ -273,26 +277,27 @@ int cfspi_claim_bus(uint bus, uint cs) void cfspi_release_bus(uint bus, uint cs) { - volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + dspi_t *dspi = (dspi_t *) MMAP_DSPI; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; - dspi->mcr &= ~(DSPI_MCR_CTXF | DSPI_MCR_CRXF); /* Clear FIFO */ + /* Clear FIFO */ + clrbits_be32(&dspi->mcr, DSPI_MCR_CTXF | DSPI_MCR_CRXF); switch (cs) { case 0: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS0_PCS0; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS0_PCS0); break; case 1: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS1_PCS1; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS1_PCS1); break; case 2: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS2_PCS2; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS2_PCS2); break; case 3: - gpio->par_dma &= GPIO_PAR_DMA_DACK0_UNMASK; + clrbits_8(&gpio->par_dma, ~GPIO_PAR_DMA_DACK0_UNMASK); break; case 5: - gpio->par_dspi &= ~GPIO_PAR_DSPI_PCS5_PCS5; + clrbits_8(&gpio->par_dspi, GPIO_PAR_DSPI_PCS5_PCS5); break; } } diff --git a/arch/m68k/cpu/mcf5445x/interrupts.c b/arch/m68k/cpu/mcf5445x/interrupts.c index 85828a6..a2cf519 100644 --- a/arch/m68k/cpu/mcf5445x/interrupts.c +++ b/arch/m68k/cpu/mcf5445x/interrupts.c @@ -3,7 +3,7 @@ * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -28,14 +28,15 @@ /* CPU specific interrupt routine */ #include #include +#include int interrupt_init(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); /* Make sure all interrupts are disabled */ - intp->imrh0 |= 0xFFFFFFFF; - intp->imrl0 |= 0xFFFFFFFF; + setbits_be32(&intp->imrh0, 0xffffffff); + setbits_be32(&intp->imrl0, 0xffffffff); enable_interrupts(); return 0; @@ -44,9 +45,9 @@ int interrupt_init(void) #if defined(CONFIG_MCFTMR) void dtimer_intr_setup(void) { - volatile int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); + int0_t *intp = (int0_t *) (CONFIG_SYS_INTR_BASE); - intp->icr0[CONFIG_SYS_TMRINTR_NO] = CONFIG_SYS_TMRINTR_PRI; - intp->imrh0 &= ~CONFIG_SYS_TMRINTR_MASK; + out_8(&intp->icr0[CONFIG_SYS_TMRINTR_NO], CONFIG_SYS_TMRINTR_PRI); + clrbits_be32(&intp->imrh0, CONFIG_SYS_TMRINTR_MASK); } #endif diff --git a/arch/m68k/cpu/mcf5445x/pci.c b/arch/m68k/cpu/mcf5445x/pci.c index 7f9784c..c32fcee 100644 --- a/arch/m68k/cpu/mcf5445x/pci.c +++ b/arch/m68k/cpu/mcf5445x/pci.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -60,78 +60,82 @@ PCI_OP(write, dword, u32, out_le32, 0) void pci_mcf5445x_init(struct pci_controller *hose) { - volatile pci_t *pci = (volatile pci_t *)MMAP_PCI; - volatile pciarb_t *pciarb = (volatile pciarb_t *)MMAP_PCIARB; - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; + pci_t *pci = (pci_t *)MMAP_PCI; + pciarb_t *pciarb = (pciarb_t *)MMAP_PCIARB; + gpio_t *gpio = (gpio_t *) MMAP_GPIO; u32 barEn = 0; - pciarb->acr = 0x001F001F; + out_be32(&pciarb->acr, 0x001f001f); /* Set PCIGNT1, PCIREQ1, PCIREQ0/PCIGNTIN, PCIGNT0/PCIREQOUT, PCIREQ2, PCIGNT2 */ - gpio->par_pci = - GPIO_PAR_PCI_GNT3_GNT3 | GPIO_PAR_PCI_GNT2 | GPIO_PAR_PCI_GNT1 | - GPIO_PAR_PCI_GNT0 | GPIO_PAR_PCI_REQ3_REQ3 | GPIO_PAR_PCI_REQ2 | - GPIO_PAR_PCI_REQ1 | GPIO_PAR_PCI_REQ0; + out_be16(&gpio->par_pci, + GPIO_PAR_PCI_GNT3_GNT3 | GPIO_PAR_PCI_GNT2 | + GPIO_PAR_PCI_GNT1 | GPIO_PAR_PCI_GNT0 | + GPIO_PAR_PCI_REQ3_REQ3 | GPIO_PAR_PCI_REQ2 | + GPIO_PAR_PCI_REQ1 | GPIO_PAR_PCI_REQ0); /* Assert reset bit */ - pci->gscr |= PCI_GSCR_PR; + setbits_be32(&pci->gscr, PCI_GSCR_PR); - pci->tcr1 |= PCI_TCR1_P; + setbits_be32(&pci->tcr1, PCI_TCR1_P); /* Initiator windows */ - pci->iw0btar = CONFIG_SYS_PCI_MEM_PHYS | (CONFIG_SYS_PCI_MEM_PHYS >> 16); - pci->iw1btar = CONFIG_SYS_PCI_IO_PHYS | (CONFIG_SYS_PCI_IO_PHYS >> 16); - pci->iw2btar = CONFIG_SYS_PCI_CFG_PHYS | (CONFIG_SYS_PCI_CFG_PHYS >> 16); + out_be32(&pci->iw0btar, + CONFIG_SYS_PCI_MEM_PHYS | (CONFIG_SYS_PCI_MEM_PHYS >> 16)); + out_be32(&pci->iw1btar, + CONFIG_SYS_PCI_IO_PHYS | (CONFIG_SYS_PCI_IO_PHYS >> 16)); + out_be32(&pci->iw2btar, + CONFIG_SYS_PCI_CFG_PHYS | (CONFIG_SYS_PCI_CFG_PHYS >> 16)); - pci->iwcr = - PCI_IWCR_W0C_EN | PCI_IWCR_W1C_EN | PCI_IWCR_W1C_IO | - PCI_IWCR_W2C_EN | PCI_IWCR_W2C_IO; + out_be32(&pci->iwcr, + PCI_IWCR_W0C_EN | PCI_IWCR_W1C_EN | PCI_IWCR_W1C_IO | + PCI_IWCR_W2C_EN | PCI_IWCR_W2C_IO); - pci->icr = 0; + out_be32(&pci->icr, 0); /* Enable bus master and mem access */ - pci->scr = PCI_SCR_B | PCI_SCR_M; + out_be32(&pci->scr, PCI_SCR_B | PCI_SCR_M); /* Cache line size and master latency */ - pci->cr1 = PCI_CR1_CLS(8) | PCI_CR1_LTMR(0xF8); - pci->cr2 = 0; + out_be32(&pci->cr1, PCI_CR1_CLS(8) | PCI_CR1_LTMR(0xF8)); + out_be32(&pci->cr2, 0); #ifdef CONFIG_SYS_PCI_BAR0 - pci->bar0 = PCI_BAR_BAR0(CONFIG_SYS_PCI_BAR0); - pci->tbatr0 = CONFIG_SYS_PCI_TBATR0 | PCI_TBATR_EN; + out_be32(&pci->bar0, PCI_BAR_BAR0(CONFIG_SYS_PCI_BAR0)); + out_be32(&pci->tbatr0, CONFIG_SYS_PCI_TBATR0 | PCI_TBATR_EN); barEn |= PCI_TCR2_B0E; #endif #ifdef CONFIG_SYS_PCI_BAR1 - pci->bar1 = PCI_BAR_BAR1(CONFIG_SYS_PCI_BAR1); - pci->tbatr1 = CONFIG_SYS_PCI_TBATR1 | PCI_TBATR_EN; + out_be32(&pci->bar1, PCI_BAR_BAR1(CONFIG_SYS_PCI_BAR1)); + out_be32(&pci->tbatr1, CONFIG_SYS_PCI_TBATR1 | PCI_TBATR_EN); barEn |= PCI_TCR2_B1E; #endif #ifdef CONFIG_SYS_PCI_BAR2 - pci->bar2 = PCI_BAR_BAR2(CONFIG_SYS_PCI_BAR2); - pci->tbatr2 = CONFIG_SYS_PCI_TBATR2 | PCI_TBATR_EN; + out_be32(&pci->bar2, PCI_BAR_BAR2(CONFIG_SYS_PCI_BAR2)); + out_be32(&pci->tbatr2, CONFIG_SYS_PCI_TBATR2 | PCI_TBATR_EN); barEn |= PCI_TCR2_B2E; #endif #ifdef CONFIG_SYS_PCI_BAR3 - pci->bar3 = PCI_BAR_BAR3(CONFIG_SYS_PCI_BAR3); - pci->tbatr3 = CONFIG_SYS_PCI_TBATR3 | PCI_TBATR_EN; + out_be32(&pci->bar3, PCI_BAR_BAR3(CONFIG_SYS_PCI_BAR3)); + out_be32(&pci->tbatr3, CONFIG_SYS_PCI_TBATR3 | PCI_TBATR_EN); barEn |= PCI_TCR2_B3E; #endif #ifdef CONFIG_SYS_PCI_BAR4 - pci->bar4 = PCI_BAR_BAR4(CONFIG_SYS_PCI_BAR4); - pci->tbatr4 = CONFIG_SYS_PCI_TBATR4 | PCI_TBATR_EN; + out_be32(&pci->bar4, PCI_BAR_BAR4(CONFIG_SYS_PCI_BAR4)); + out_be32(&pci->tbatr4, CONFIG_SYS_PCI_TBATR4 | PCI_TBATR_EN); barEn |= PCI_TCR2_B4E; #endif #ifdef CONFIG_SYS_PCI_BAR5 - pci->bar5 = PCI_BAR_BAR5(CONFIG_SYS_PCI_BAR5); - pci->tbatr5 = CONFIG_SYS_PCI_TBATR5 | PCI_TBATR_EN; + out_be32(&pci->bar5, PCI_BAR_BAR5(CONFIG_SYS_PCI_BAR5)); + out_be32(&pci->tbatr5, CONFIG_SYS_PCI_TBATR5 | PCI_TBATR_EN); barEn |= PCI_TCR2_B5E; #endif - pci->tcr2 = barEn; + out_be32(&pci->tcr2, barEn); /* Deassert reset bit */ - pci->gscr &= ~PCI_GSCR_PR; + clrbits_be32(&pci->gscr, PCI_GSCR_PR); udelay(1000); /* Enable PCI bus master support */ diff --git a/arch/m68k/cpu/mcf5445x/speed.c b/arch/m68k/cpu/mcf5445x/speed.c index 9c0c077..073b7ef 100644 --- a/arch/m68k/cpu/mcf5445x/speed.c +++ b/arch/m68k/cpu/mcf5445x/speed.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -26,6 +26,7 @@ #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -44,7 +45,7 @@ DECLARE_GLOBAL_DATA_PTR; void clock_enter_limp(int lpdiv) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; + ccm_t *ccm = (ccm_t *)MMAP_CCM; int i, j; /* Check bounds of divider */ @@ -57,10 +58,10 @@ void clock_enter_limp(int lpdiv) for (i = 0, j = lpdiv; j != 1; j >>= 1, i++) ; /* Apply the divider to the system clock */ - ccm->cdr = (ccm->cdr & 0xF0FF) | CCM_CDR_LPDIV(i); + clrsetbits_be16(&ccm->cdr, 0x0f00, CCM_CDR_LPDIV(i)); /* Enable Limp Mode */ - ccm->misccr |= CCM_MISCCR_LIMP; + setbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); } /* @@ -69,14 +70,15 @@ void clock_enter_limp(int lpdiv) */ void clock_exit_limp(void) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; - volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + ccm_t *ccm = (ccm_t *)MMAP_CCM; + pll_t *pll = (pll_t *)MMAP_PLL; /* Exit Limp mode */ - ccm->misccr &= ~CCM_MISCCR_LIMP; + clrbits_be16(&ccm->misccr, CCM_MISCCR_LIMP); /* Wait for the PLL to lock */ - while (!(pll->psr & PLL_PSR_LOCK)) ; + while (!(in_be32(&pll->psr) & PLL_PSR_LOCK)) + ; } /* @@ -85,8 +87,8 @@ void clock_exit_limp(void) int get_clocks(void) { - volatile ccm_t *ccm = (volatile ccm_t *)MMAP_CCM; - volatile pll_t *pll = (volatile pll_t *)MMAP_PLL; + ccm_t *ccm = (ccm_t *)MMAP_CCM; + pll_t *pll = (pll_t *)MMAP_PLL; int pllmult_nopci[] = { 20, 10, 24, 18, 12, 6, 16, 8 }; int pllmult_pci[] = { 12, 6, 16, 8 }; int vco = 0, bPci, temp, fbtemp, pcrvalue; @@ -94,13 +96,13 @@ int get_clocks(void) u16 fbpll_mask; #ifdef CONFIG_M54455EVB - volatile u8 *cpld = (volatile u8 *)(CONFIG_SYS_CS2_BASE + 3); + u8 *cpld = (u8 *)(CONFIG_SYS_CS2_BASE + 3); #endif u8 bootmode; /* To determine PCI is present or not */ - if (((ccm->ccr & CCM_CCR_360_FBCONFIG_MASK) == 0x00e0) || - ((ccm->ccr & CCM_CCR_360_FBCONFIG_MASK) == 0x0060)) { + if (((in_be16(&ccm->ccr) & CCM_CCR_360_FBCONFIG_MASK) == 0x00e0) || + ((in_be16(&ccm->ccr) & CCM_CCR_360_FBCONFIG_MASK) == 0x0060)) { pPllmult = &pllmult_pci[0]; fbpll_mask = 3; /* 11b */ bPci = 1; @@ -114,7 +116,7 @@ int get_clocks(void) } #ifdef CONFIG_M54455EVB - bootmode = (*cpld & 0x03); + bootmode = (in_8(cpld) & 0x03); if (bootmode != 3) { /* Temporary read from CCR- fixed fb issue, must be the same clock @@ -122,11 +124,11 @@ int get_clocks(void) fbtemp = pPllmult[ccm->ccr & fbpll_mask]; /* Break down into small pieces, code still in flex bus */ - pcrvalue = pll->pcr & 0xFFFFF0FF; + pcrvalue = in_be32(&pll->pcr) & 0xFFFFF0FF; temp = fbtemp - 1; pcrvalue |= PLL_PCR_OUTDIV3(temp); - pll->pcr = pcrvalue; + out_be32(&pll->pcr, pcrvalue); } #endif #ifdef CONFIG_M54451EVB @@ -137,9 +139,10 @@ int get_clocks(void) bootmode = 2; /* default value is 16 mul, set to 20 mul */ - pcrvalue = (pll->pcr & 0x00FFFFFF) | 0x14000000; - pll->pcr = pcrvalue; - while ((pll->psr & PLL_PSR_LOCK) != PLL_PSR_LOCK); + pcrvalue = (in_be32(&pll->pcr) & 0x00FFFFFF) | 0x14000000; + out_be32(&pll->pcr, pcrvalue); + while ((in_be32(&pll->psr) & PLL_PSR_LOCK) != PLL_PSR_LOCK) + ; #endif #endif @@ -149,10 +152,10 @@ int get_clocks(void) if ((vco < CLOCK_PLL_FVCO_MIN) || (vco > CLOCK_PLL_FVCO_MAX)) { /* invaild range, re-set in PCR */ - int temp = ((pll->pcr & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; + int temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; int i, j, bus; - j = (pll->pcr & 0xFF000000) >> 24; + j = (in_be32(&pll->pcr) & 0xFF000000) >> 24; for (i = j; i < 0xFF; i++) { vco = i * CONFIG_SYS_INPUT_CLKSRC; if (vco >= CLOCK_PLL_FVCO_MIN) { @@ -163,47 +166,47 @@ int get_clocks(void) break; } } - pcrvalue = pll->pcr & 0x00FF00FF; + pcrvalue = in_be32(&pll->pcr) & 0x00FF00FF; fbtemp = ((i - 1) << 8) | ((i - 1) << 12); pcrvalue |= ((i << 24) | fbtemp); - pll->pcr = pcrvalue; + out_be32(&pll->pcr, pcrvalue); } gd->vco_clk = vco; /* Vco clock */ } else if (bootmode == 2) { /* Normal mode */ - vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; if ((vco < CLOCK_PLL_FVCO_MIN) || (vco > CLOCK_PLL_FVCO_MAX)) { /* Default value */ - pcrvalue = (pll->pcr & 0x00FFFFFF); - pcrvalue |= pPllmult[ccm->ccr & fbpll_mask] << 24; - pll->pcr = pcrvalue; - vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + pcrvalue = (in_be32(&pll->pcr) & 0x00FFFFFF); + pcrvalue |= pPllmult[in_be16(&ccm->ccr) & fbpll_mask] << 24; + out_be32(&pll->pcr, pcrvalue); + vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; } gd->vco_clk = vco; /* Vco clock */ } else if (bootmode == 3) { /* serial mode */ - vco = ((pll->pcr & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; + vco = ((in_be32(&pll->pcr) & 0xFF000000) >> 24) * CONFIG_SYS_INPUT_CLKSRC; gd->vco_clk = vco; /* Vco clock */ } - if ((ccm->ccr & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { + if ((in_be16(&ccm->ccr) & CCM_MISCCR_LIMP) == CCM_MISCCR_LIMP) { /* Limp mode */ } else { gd->inp_clk = CONFIG_SYS_INPUT_CLKSRC; /* Input clock */ - temp = (pll->pcr & PLL_PCR_OUTDIV1_MASK) + 1; + temp = (in_be32(&pll->pcr) & PLL_PCR_OUTDIV1_MASK) + 1; gd->cpu_clk = vco / temp; /* cpu clock */ - temp = ((pll->pcr & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; + temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV2_MASK) >> 4) + 1; gd->bus_clk = vco / temp; /* bus clock */ - temp = ((pll->pcr & PLL_PCR_OUTDIV3_MASK) >> 8) + 1; + temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV3_MASK) >> 8) + 1; gd->flb_clk = vco / temp; /* FlexBus clock */ #ifdef CONFIG_PCI if (bPci) { - temp = ((pll->pcr & PLL_PCR_OUTDIV4_MASK) >> 12) + 1; + temp = ((in_be32(&pll->pcr) & PLL_PCR_OUTDIV4_MASK) >> 12) + 1; gd->pci_clk = vco / temp; /* PCI clock */ } #endif diff --git a/board/freescale/m54451evb/m54451evb.c b/board/freescale/m54451evb/m54451evb.c index 088c8c4..32a9374 100644 --- a/board/freescale/m54451evb/m54451evb.c +++ b/board/freescale/m54451evb/m54451evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2008 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2008, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -51,14 +52,14 @@ phys_size_t initdram(int board_type) */ dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; #else - volatile sdramc_t *sdram = (volatile sdramc_t *)(MMAP_SDRAM); - volatile gpio_t *gpio = (volatile gpio_t *)(MMAP_GPIO); + sdramc_t *sdram = (sdramc_t *)(MMAP_SDRAM); + gpio_t *gpio = (gpio_t *)(MMAP_GPIO); u32 i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000; - if ((sdram->sdcfg1 == CONFIG_SYS_SDRAM_CFG1) && - (sdram->sdcfg2 == CONFIG_SYS_SDRAM_CFG2)) + if ((in_be32(&sdram->sdcfg1) == CONFIG_SYS_SDRAM_CFG1) && + (in_be32(&sdram->sdcfg2) == CONFIG_SYS_SDRAM_CFG2)) return dramsize; for (i = 0x13; i < 0x20; i++) { @@ -67,32 +68,33 @@ phys_size_t initdram(int board_type) } i--; - gpio->mscr_sdram = CONFIG_SYS_SDRAM_DRV_STRENGTH; + out_8(&gpio->mscr_sdram, CONFIG_SYS_SDRAM_DRV_STRENGTH); - sdram->sdcs0 = (CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->sdcs0, CONFIG_SYS_SDRAM_BASE | i); - sdram->sdcfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->sdcfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->sdcfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->sdcfg2, CONFIG_SYS_SDRAM_CFG2); udelay(200); /* Issue PALL */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 2); __asm__("nop"); /* Perform two refresh cycles */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); __asm__("nop"); - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); __asm__("nop"); /* Issue LEMR */ - sdram->sdmr = CONFIG_SYS_SDRAM_MODE; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_MODE); __asm__("nop"); - sdram->sdmr = CONFIG_SYS_SDRAM_EMOD; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_MODE); __asm__("nop"); - sdram->sdcr = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000000; + out_be32(&sdram->sdcr, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000000); udelay(100); #endif diff --git a/board/freescale/m54455evb/m54455evb.c b/board/freescale/m54455evb/m54455evb.c index 2a84514..0ca268e 100644 --- a/board/freescale/m54455evb/m54455evb.c +++ b/board/freescale/m54455evb/m54455evb.c @@ -2,7 +2,7 @@ * (C) Copyright 2000-2003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -47,8 +48,8 @@ phys_size_t initdram(int board_type) */ dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000 >> 1; #else - volatile sdramc_t *sdram = (volatile sdramc_t *)(MMAP_SDRAM); - volatile gpio_t *gpio = (volatile gpio_t *)(MMAP_GPIO); + sdramc_t *sdram = (sdramc_t *)(MMAP_SDRAM); + gpio_t *gpio = (gpio_t *)(MMAP_GPIO); u32 i; dramsize = CONFIG_SYS_SDRAM_SIZE * 0x100000 >> 1; @@ -59,33 +60,34 @@ phys_size_t initdram(int board_type) } i--; - gpio->mscr_sdram = CONFIG_SYS_SDRAM_DRV_STRENGTH; + out_8(&gpio->mscr_sdram, CONFIG_SYS_SDRAM_DRV_STRENGTH); - sdram->sdcs0 = (CONFIG_SYS_SDRAM_BASE | i); - sdram->sdcs1 = (CONFIG_SYS_SDRAM_BASE1 | i); + out_be32(&sdram->sdcs0, CONFIG_SYS_SDRAM_BASE | i); + out_be32(&sdram->sdcs1, CONFIG_SYS_SDRAM_BASE1 | i); - sdram->sdcfg1 = CONFIG_SYS_SDRAM_CFG1; - sdram->sdcfg2 = CONFIG_SYS_SDRAM_CFG2; + out_be32(&sdram->sdcfg1, CONFIG_SYS_SDRAM_CFG1); + out_be32(&sdram->sdcfg2, CONFIG_SYS_SDRAM_CFG2); /* Issue PALL */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 2); /* Issue LEMR */ - sdram->sdmr = CONFIG_SYS_SDRAM_EMOD | 0x408; - sdram->sdmr = CONFIG_SYS_SDRAM_MODE | 0x300; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_EMOD | 0x408); + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_MODE | 0x300); udelay(500); /* Issue PALL */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 2; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 2); /* Perform two refresh cycles */ - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; - sdram->sdcr = CONFIG_SYS_SDRAM_CTRL | 4; + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); + out_be32(&sdram->sdcr, CONFIG_SYS_SDRAM_CTRL | 4); - sdram->sdmr = CONFIG_SYS_SDRAM_MODE | 0x200; + out_be32(&sdram->sdmr, CONFIG_SYS_SDRAM_MODE | 0x200); - sdram->sdcr = (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00; + out_be32(&sdram->sdcr, + (CONFIG_SYS_SDRAM_CTRL & ~0x80000000) | 0x10000c00); udelay(100); #endif @@ -105,26 +107,29 @@ int testdram(void) int ide_preinit(void) { - volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO; - - gpio->par_fec |= (gpio->par_fec & GPIO_PAR_FEC_FEC1_UNMASK) | 0x10; - gpio->par_feci2c |= - (gpio->par_feci2c & 0xF0FF) | (GPIO_PAR_FECI2C_MDC1_ATA_DIOR | - GPIO_PAR_FECI2C_MDIO1_ATA_DIOW); - gpio->par_ata |= - (GPIO_PAR_ATA_BUFEN | GPIO_PAR_ATA_CS1 | GPIO_PAR_ATA_CS0 | - GPIO_PAR_ATA_DA2 | GPIO_PAR_ATA_DA1 | GPIO_PAR_ATA_DA0 - | GPIO_PAR_ATA_RESET_RESET | GPIO_PAR_ATA_DMARQ_DMARQ | - GPIO_PAR_ATA_IORDY_IORDY); - gpio->par_pci |= - (GPIO_PAR_PCI_GNT3_ATA_DMACK | GPIO_PAR_PCI_REQ3_ATA_INTRQ); + gpio_t *gpio = (gpio_t *) MMAP_GPIO; + u32 tmp; + + tmp = (in_8(&gpio->par_fec) & GPIO_PAR_FEC_FEC1_UNMASK) | 0x10; + setbits_8(&gpio->par_fec, tmp); + tmp = ((in_be16(&gpio->par_feci2c) & 0xf0ff) | + (GPIO_PAR_FECI2C_MDC1_ATA_DIOR | GPIO_PAR_FECI2C_MDIO1_ATA_DIOW)); + setbits_be16(&gpio->par_feci2c, tmp); + + setbits_be16(&gpio->par_ata, + GPIO_PAR_ATA_BUFEN | GPIO_PAR_ATA_CS1 | GPIO_PAR_ATA_CS0 | + GPIO_PAR_ATA_DA2 | GPIO_PAR_ATA_DA1 | GPIO_PAR_ATA_DA0 | + GPIO_PAR_ATA_RESET_RESET | GPIO_PAR_ATA_DMARQ_DMARQ | + GPIO_PAR_ATA_IORDY_IORDY); + setbits_be16(&gpio->par_pci, + GPIO_PAR_PCI_GNT3_ATA_DMACK | GPIO_PAR_PCI_REQ3_ATA_INTRQ); return (0); } void ide_set_reset(int idereset) { - volatile atac_t *ata = (atac_t *) MMAP_ATA; + atac_t *ata = (atac_t *) MMAP_ATA; long period; /* t1, t2, t3, t4, t5, t6, t9, tRD, tA */ int piotms[5][9] = { @@ -136,24 +141,27 @@ void ide_set_reset(int idereset) }; /* PIO 4 */ if (idereset) { - ata->cr = 0; /* control reset */ + /* control reset */ + out_8(&ata->cr, 0); udelay(10000); } else { #define CALC_TIMING(t) (t + period - 1) / period period = 1000000000 / gd->bus_clk; /* period in ns */ /*ata->ton = CALC_TIMING (180); */ - ata->t1 = CALC_TIMING(piotms[2][0]); - ata->t2w = CALC_TIMING(piotms[2][1]); - ata->t2r = CALC_TIMING(piotms[2][1]); - ata->ta = CALC_TIMING(piotms[2][8]); - ata->trd = CALC_TIMING(piotms[2][7]); - ata->t4 = CALC_TIMING(piotms[2][3]); - ata->t9 = CALC_TIMING(piotms[2][6]); - - ata->cr = 0x40; /* IORDY enable */ + out_8(&ata->t1, CALC_TIMING(piotms[2][0])); + out_8(&ata->t2w, CALC_TIMING(piotms[2][1])); + out_8(&ata->t2r, CALC_TIMING(piotms[2][1])); + out_8(&ata->ta, CALC_TIMING(piotms[2][8])); + out_8(&ata->trd, CALC_TIMING(piotms[2][7])); + out_8(&ata->t4, CALC_TIMING(piotms[2][3])); + out_8(&ata->t9, CALC_TIMING(piotms[2][6])); + + /* IORDY enable */ + out_8(&ata->cr, 0x40); udelay(200000); - ata->cr |= 0x01; /* IORDY enable */ + /* IORDY enable */ + setbits_8(&ata->cr, 0x01); } } #endif -- cgit v1.1 From 59d0612252a0ffcb878a1891249d32a306a24fa6 Mon Sep 17 00:00:00 2001 From: Richard Retanubun Date: Thu, 24 Mar 2011 08:58:11 +0000 Subject: ColdFire: Queued SPI driver This patch adds a driver for Freescale Colfire Queued SPI bus. Coded to work with 8 bits per transfer to use with SPI flash. CPOL, CPHA, and CS_ACTIVE_HIGH can be configured. Tested with MCF5270 which have 4 chip selects. Activate by #define CONFIG_CF_QSPI in board config. Signed-off-by: Richard Retanubun --- arch/m68k/cpu/mcf52x2/cpu_init.c | 15 +- arch/m68k/include/asm/coldfire/qspi.h | 2 +- arch/m68k/include/asm/m5271.h | 26 +++ drivers/spi/Makefile | 1 + drivers/spi/cf_qspi.c | 373 ++++++++++++++++++++++++++++++++++ 5 files changed, 415 insertions(+), 2 deletions(-) create mode 100644 drivers/spi/cf_qspi.c diff --git a/arch/m68k/cpu/mcf52x2/cpu_init.c b/arch/m68k/cpu/mcf52x2/cpu_init.c index a221420..5d0e9f0 100644 --- a/arch/m68k/cpu/mcf52x2/cpu_init.c +++ b/arch/m68k/cpu/mcf52x2/cpu_init.c @@ -333,7 +333,20 @@ int fecpin_setclear(struct eth_device *dev, int setclear) return 0; } #endif /* CONFIG_CMD_NET */ -#endif + +#if defined(CONFIG_CF_QSPI) + +/* Configure PIOs for SIN, SOUT, and SCK */ +void cfspi_port_conf(void) +{ + mbar_writeByte(MCF_GPIO_PAR_QSPI, + MCF_GPIO_PAR_QSPI_SIN_SIN | + MCF_GPIO_PAR_QSPI_SOUT_SOUT | + MCF_GPIO_PAR_QSPI_SCK_SCK); +} +#endif /* CONFIG_CF_QSPI */ + +#endif /* CONFIG_M5271 */ #if defined(CONFIG_M5272) /* diff --git a/arch/m68k/include/asm/coldfire/qspi.h b/arch/m68k/include/asm/coldfire/qspi.h index 8bcd2e4..9fd98f6 100644 --- a/arch/m68k/include/asm/coldfire/qspi.h +++ b/arch/m68k/include/asm/coldfire/qspi.h @@ -98,7 +98,7 @@ typedef struct qspi_ctrl { #define QSPI_QAR_RECV (0x0010) #define QSPI_QAR_CMD (0x0020) -/* DR */ +/* DR with RAM command word definitions */ #define QSPI_QDR_CONT (0x8000) #define QSPI_QDR_BITSE (0x4000) #define QSPI_QDR_DT (0x2000) diff --git a/arch/m68k/include/asm/m5271.h b/arch/m68k/include/asm/m5271.h index d25261b..b2bc051 100644 --- a/arch/m68k/include/asm/m5271.h +++ b/arch/m68k/include/asm/m5271.h @@ -171,6 +171,32 @@ #define MCF_GPIO_PAR_UART_U1RXD_UART1 0x0C00 #define MCF_GPIO_PAR_UART_U1TXD_UART1 0x0300 +/* Bit definitions and macros for PAR_QSPI */ +#define MCF_GPIO_PAR_QSPI_PCS1_UNMASK 0x3F +#define MCF_GPIO_PAR_QSPI_PCS1_PCS1 0xC0 +#define MCF_GPIO_PAR_QSPI_PCS1_SDRAM_SCKE 0x80 +#define MCF_GPIO_PAR_QSPI_PCS1_GPIO 0x00 +#define MCF_GPIO_PAR_QSPI_PCS0_UNMASK 0xDF +#define MCF_GPIO_PAR_QSPI_PCS0_PCS0 0x20 +#define MCF_GPIO_PAR_QSPI_PCS0_GPIO 0x00 +#define MCF_GPIO_PAR_QSPI_SIN_UNMASK 0xE7 +#define MCF_GPIO_PAR_QSPI_SIN_SIN 0x18 +#define MCF_GPIO_PAR_QSPI_SIN_I2C_SDA 0x10 +#define MCF_GPIO_PAR_QSPI_SIN_GPIO 0x00 +#define MCF_GPIO_PAR_QSPI_SOUT_UNMASK 0xFB +#define MCF_GPIO_PAR_QSPI_SOUT_SOUT 0x04 +#define MCF_GPIO_PAR_QSPI_SOUT_GPIO 0x00 +#define MCF_GPIO_PAR_QSPI_SCK_UNMASK 0xFC +#define MCF_GPIO_PAR_QSPI_SCK_SCK 0x03 +#define MCF_GPIO_PAR_QSPI_SCK_I2C_SCL 0x02 +#define MCF_GPIO_PAR_QSPI_SCK_GPIO 0x00 + +/* Bit definitions and macros for PAR_TIMER for QSPI */ +#define MCF_GPIO_PAR_TIMER_T3IN_UNMASK 0x3FFF +#define MCF_GPIO_PAR_TIMER_T3IN_QSPI_PCS2 0x4000 +#define MCF_GPIO_PAR_TIMER_T3OUT_UNMASK 0xFF3F +#define MCF_GPIO_PAR_TIMER_T3OUT_QSPI_PCS3 0x0040 + #define MCF_GPIO_PAR_SDRAM_PAR_CSSDCS(x) (((x)&0x03)<<6) #define MCF_SDRAMC_DCR 0x000040 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 80b981f..f0b82c6 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -32,6 +32,7 @@ COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o COBJS-$(CONFIG_CF_SPI) += cf_spi.o +COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o diff --git a/drivers/spi/cf_qspi.c b/drivers/spi/cf_qspi.c new file mode 100644 index 0000000..72dd1a5 --- /dev/null +++ b/drivers/spi/cf_qspi.c @@ -0,0 +1,373 @@ +/* + * Freescale Coldfire Queued SPI driver + * + * NOTE: + * This driver is written to transfer 8 bit at-a-time and uses the dedicated + * SPI slave select pins as bit-banged GPIO to work with spi_flash subsystem. + * + * + * Copyright (C) 2011 Ruggedcom, Inc. + * Richard Retanubun (richardretanubun@freescale.com) + * + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define clamp(x, low, high) (min(max(low, x), high)) +#define to_cf_qspi_slave(s) container_of(s, struct cf_qspi_slave, s) + +struct cf_qspi_slave { + struct spi_slave slave; /* Specific bus:cs ID for each device */ + qspi_t *regs; /* Pointer to SPI controller registers */ + u16 qmr; /* QMR: Queued Mode Register */ + u16 qwr; /* QWR: Queued Wrap Register */ + u16 qcr; /* QCR: Queued Command Ram */ +}; + +/* Register write wrapper functions */ +static void write_qmr(volatile qspi_t *qspi, u16 val) { qspi->mr = val; } +static void write_qdlyr(volatile qspi_t *qspi, u16 val) { qspi->dlyr = val; } +static void write_qwr(volatile qspi_t *qspi, u16 val) { qspi->wr = val; } +static void write_qir(volatile qspi_t *qspi, u16 val) { qspi->ir = val; } +static void write_qar(volatile qspi_t *qspi, u16 val) { qspi->ar = val; } +static void write_qdr(volatile qspi_t *qspi, u16 val) { qspi->dr = val; } +/* Register read wrapper functions */ +static u16 read_qdlyr(volatile qspi_t *qspi) { return qspi->dlyr; } +static u16 read_qwr(volatile qspi_t *qspi) { return qspi->wr; } +static u16 read_qir(volatile qspi_t *qspi) { return qspi->ir; } +static u16 read_qdr(volatile qspi_t *qspi) { return qspi->dr; } + +/* These call points may be different for each ColdFire CPU */ +extern void cfspi_port_conf(void); +static void cfspi_cs_activate(uint bus, uint cs, uint cs_active_high); +static void cfspi_cs_deactivate(uint bus, uint cs, uint cs_active_high); + +int spi_claim_bus(struct spi_slave *slave) +{ + return 0; +} +void spi_release_bus(struct spi_slave *slave) +{ +} + +__attribute__((weak)) +void spi_init(void) +{ + cfspi_port_conf(); +} + +__attribute__((weak)) +void spi_cs_activate(struct spi_slave *slave) +{ + struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); + + cfspi_cs_activate(slave->bus, slave->cs, !(dev->qwr & QSPI_QWR_CSIV)); +} + +__attribute__((weak)) +void spi_cs_deactivate(struct spi_slave *slave) +{ + struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); + + cfspi_cs_deactivate(slave->bus, slave->cs, !(dev->qwr & QSPI_QWR_CSIV)); +} + +__attribute__((weak)) +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + /* Only 1 bus and 4 chipselect per controller */ + if (bus == 0 && (cs >= 0 && cs < 4)) + return 1; + else + return 0; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); + + free(dev); +} + +/* Translate information given by spi_setup_slave to members of cf_qspi_slave */ +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct cf_qspi_slave *dev = NULL; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + dev = malloc(sizeof(struct cf_qspi_slave)); + if (!dev) + return NULL; + + /* Initialize to known value */ + dev->slave.bus = bus; + dev->slave.cs = cs; + dev->regs = (qspi_t *)MMAP_QSPI; + dev->qmr = 0; + dev->qwr = 0; + dev->qcr = 0; + + + /* Map max_hz to QMR[BAUD] */ + if (max_hz == 0) /* Go as fast as possible */ + dev->qmr = 2u; + else /* Get the closest baud rate */ + dev->qmr = clamp(((gd->bus_clk >> 2) + max_hz - 1)/max_hz, + 2u, 255u); + + /* Map mode to QMR[CPOL] and QMR[CPHA] */ + if (mode & SPI_CPOL) + dev->qmr |= QSPI_QMR_CPOL; + + if (mode & SPI_CPHA) + dev->qmr |= QSPI_QMR_CPHA; + + /* Hardcode bit length to 8 bit per transter */ + dev->qmr |= QSPI_QMR_BITS_8; + + /* Set QMR[MSTR] to enable QSPI as master */ + dev->qmr |= QSPI_QMR_MSTR; + + /* + * Set QCR and QWR to default values for spi flash operation. + * If more custom QCR and QRW are needed, overload mode variable + */ + dev->qcr = (QSPI_QDR_CONT | QSPI_QDR_BITSE); + + if (!(mode & SPI_CS_HIGH)) + dev->qwr |= QSPI_QWR_CSIV; + + return &dev->slave; +} + +/* Transfer 8 bit at a time */ +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); + volatile qspi_t *qspi = dev->regs; + u8 *txbuf = (u8 *)dout; + u8 *rxbuf = (u8 *)din; + u32 count = ((bitlen / 8) + (bitlen % 8 ? 1 : 0)); + u32 n, i = 0; + + /* Sanitize arguments */ + if (slave == NULL) { + printf("%s: NULL slave ptr\n", __func__); + return -1; + } + + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); + + /* There is something to send, lets process it. spi_xfer is also called + * just to toggle chip select, so bitlen of 0 is valid */ + if (count > 0) { + /* + * NOTE: Since chip select is driven as a bit-bang-ed GPIO + * using spi_cs_activate() and spi_cs_deactivate(), + * the chip select settings inside the controller + * (i.e. QCR[CONT] and QWR[CSIV]) are moot. The bits are set to + * keep the controller settings consistent with the actual + * operation of the bus. + */ + + /* Write the slave device's settings for the controller.*/ + write_qmr(qspi, dev->qmr); + write_qwr(qspi, dev->qwr); + + /* Limit transfer to 16 at a time */ + n = min(count, 16u); + do { + /* Setup queue end point */ + write_qwr(qspi, ((read_qwr(qspi) & QSPI_QWR_ENDQP_MASK) + | QSPI_QWR_ENDQP((n-1)))); + + /* Write Command RAM */ + write_qar(qspi, QSPI_QAR_CMD); + for (i = 0; i < n; ++i) + write_qdr(qspi, dev->qcr); + + /* Write TxBuf, if none given, fill with ZEROes */ + write_qar(qspi, QSPI_QAR_TRANS); + if (txbuf) { + for (i = 0; i < n; ++i) + write_qdr(qspi, *txbuf++); + } else { + for (i = 0; i < n; ++i) + write_qdr(qspi, 0); + } + + /* Clear QIR[SPIF] by writing a 1 to it */ + write_qir(qspi, read_qir(qspi) | QSPI_QIR_SPIF); + /* Set QDLYR[SPE] to start sending */ + write_qdlyr(qspi, read_qdlyr(qspi) | QSPI_QDLYR_SPE); + + /* Poll QIR[SPIF] for transfer completion */ + while ((read_qir(qspi) & QSPI_QIR_SPIF) != 1) + udelay(1); + + /* If given read RxBuf, load data to it */ + if (rxbuf) { + write_qar(qspi, QSPI_QAR_RECV); + for (i = 0; i < n; ++i) + *rxbuf++ = read_qdr(qspi); + } + + /* Decrement count */ + count -= n; + } while (count); + } + + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); + + return 0; +} + +/* Each MCF CPU may have different pin assignments for chip selects. */ +#if defined(CONFIG_M5271) +/* Assert chip select, val = [1|0] , dir = out, mode = GPIO */ +void cfspi_cs_activate(uint bus, uint cs, uint cs_active_high) +{ + debug("%s: bus %d cs %d cs_active_high %d\n", + __func__, bus, cs, cs_active_high); + + switch (cs) { + case 0: /* QSPI_CS[0] = PQSPI[3] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x08); + else + mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xF7); + + mbar_writeByte(MCF_GPIO_PDDR_QSPI, + mbar_readByte(MCF_GPIO_PDDR_QSPI) | 0x08); + + mbar_writeByte(MCF_GPIO_PAR_QSPI, + mbar_readByte(MCF_GPIO_PAR_QSPI) & 0xDF); + break; + case 1: /* QSPI_CS[1] = PQSPI[4] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x10); + else + mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xEF); + + mbar_writeByte(MCF_GPIO_PDDR_QSPI, + mbar_readByte(MCF_GPIO_PDDR_QSPI) | 0x10); + + mbar_writeByte(MCF_GPIO_PAR_QSPI, + mbar_readByte(MCF_GPIO_PAR_QSPI) & 0x3F); + break; + case 2: /* QSPI_CS[2] = PTIMER[7] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x80); + else + mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0x7F); + + mbar_writeByte(MCF_GPIO_PDDR_TIMER, + mbar_readByte(MCF_GPIO_PDDR_TIMER) | 0x80); + + mbar_writeShort(MCF_GPIO_PAR_TIMER, + mbar_readShort(MCF_GPIO_PAR_TIMER) & 0x3FFF); + break; + case 3: /* QSPI_CS[3] = PTIMER[3] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x08); + else + mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0xF7); + + mbar_writeByte(MCF_GPIO_PDDR_TIMER, + mbar_readByte(MCF_GPIO_PDDR_TIMER) | 0x08); + + mbar_writeShort(MCF_GPIO_PAR_TIMER, + mbar_readShort(MCF_GPIO_PAR_TIMER) & 0xFF3F); + break; + } +} + +/* Deassert chip select, val = [1|0], dir = in, mode = GPIO + * direction set as IN to undrive the pin, external pullup/pulldown will bring + * bus to deassert state. + */ +void cfspi_cs_deactivate(uint bus, uint cs, uint cs_active_high) +{ + debug("%s: bus %d cs %d cs_active_high %d\n", + __func__, bus, cs, cs_active_high); + + switch (cs) { + case 0: /* QSPI_CS[0] = PQSPI[3] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xF7); + else + mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x08); + + mbar_writeByte(MCF_GPIO_PDDR_QSPI, + mbar_readByte(MCF_GPIO_PDDR_QSPI) & 0xF7); + + mbar_writeByte(MCF_GPIO_PAR_QSPI, + mbar_readByte(MCF_GPIO_PAR_QSPI) & 0xDF); + break; + case 1: /* QSPI_CS[1] = PQSPI[4] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xEF); + else + mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x10); + + mbar_writeByte(MCF_GPIO_PDDR_QSPI, + mbar_readByte(MCF_GPIO_PDDR_QSPI) & 0xEF); + + mbar_writeByte(MCF_GPIO_PAR_QSPI, + mbar_readByte(MCF_GPIO_PAR_QSPI) & 0x3F); + break; + case 2: /* QSPI_CS[2] = PTIMER[7] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0x7F); + else + mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x80); + + mbar_writeByte(MCF_GPIO_PDDR_TIMER, + mbar_readByte(MCF_GPIO_PDDR_TIMER) & 0x7F); + + mbar_writeShort(MCF_GPIO_PAR_TIMER, + mbar_readShort(MCF_GPIO_PAR_TIMER) & 0x3FFF); + break; + case 3: /* QSPI_CS[3] = PTIMER[3] */ + if (cs_active_high) + mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0xF7); + else + mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x08); + + mbar_writeByte(MCF_GPIO_PDDR_TIMER, + mbar_readByte(MCF_GPIO_PDDR_TIMER) & 0xF7); + + mbar_writeShort(MCF_GPIO_PAR_TIMER, + mbar_readShort(MCF_GPIO_PAR_TIMER) & 0xFF3F); + break; + } +} +#endif /* CONFIG_M5271 */ -- cgit v1.1 From 30a3f3881e44187f21eb08bf8601ed4adaf4ca0e Mon Sep 17 00:00:00 2001 From: Jason Jin Date: Thu, 20 Sep 2012 14:17:46 +0800 Subject: Flex bus definition update for Coldfire 5253. originally work by Jate Sujjavanich ---- The defines in arch/m68k/include/coldfire/flexbus.h are not compatible with the 5235 processor. The registers in struct fbcs are different sizes from those in the 5235. Also, the defines are a little different. This is what I have so far. Comments? ---- Reformat the patch manually by Jason Jin Signed-off-by: Jate Sujjavanich Signed-off-by: Jason Jin --- arch/m68k/include/asm/coldfire/flexbus.h | 68 ++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/arch/m68k/include/asm/coldfire/flexbus.h b/arch/m68k/include/asm/coldfire/flexbus.h index 51cbbd8..9a3078a 100644 --- a/arch/m68k/include/asm/coldfire/flexbus.h +++ b/arch/m68k/include/asm/coldfire/flexbus.h @@ -29,7 +29,57 @@ /********************************************************************* * FlexBus Chip Selects (FBCS) *********************************************************************/ +#ifdef CONFIG_M5235 +typedef struct fbcs { + u16 csar0; /* Chip-select Address */ + u16 res1; + u32 csmr0; /* Chip-select Mask */ + u16 res2; + u16 cscr0; /* Chip-select Control */ + + u16 csar1; + u16 res3; + u32 csmr1; + u16 res4; + u16 cscr1; + + u16 csar2; + u16 res5; + u32 csmr2; + u16 res6; + u16 cscr2; + + u16 csar3; + u16 res7; + u32 csmr3; + u16 res8; + u16 cscr3; + + u16 csar4; + u16 res9; + u32 csmr4; + u16 res10; + u16 cscr4; + + u16 csar5; + u16 res11; + u32 csmr5; + u16 res12; + u16 cscr5; + u16 csar6; + u16 res13; + u32 csmr6; + u16 res14; + u16 cscr6; + + u16 csar7; + u16 res15; + u32 csmr7; + u16 res16; + u16 cscr7; +} fbcs_t; +#else typedef struct fbcs { u32 csar0; /* Chip-select Address */ u32 csmr0; /* Chip-select Mask */ @@ -56,6 +106,7 @@ typedef struct fbcs { u32 csmr7; u32 cscr7; } fbcs_t; +#endif #define FBCS_CSAR_BA(x) ((x) & 0xFFFF0000) @@ -94,6 +145,22 @@ typedef struct fbcs { #endif #define FBCS_CSMR_V (0x00000001) /* Valid bit */ +#ifdef CONFIG_M5235 +#define FBCS_CSCR_SRWS(x) (((x) & 0x3) << 14) +#define FBCS_CSCR_IWS(x) (((x) & 0xF) << 10) +#define FBCS_CSCR_AA_ON (1 << 8) +#define FBCS_CSCR_AA_OFF (0 << 8) +#define FBCS_CSCR_PS_32 (0 << 6) +#define FBCS_CSCR_PS_16 (2 << 6) +#define FBCS_CSCR_PS_8 (1 << 6) +#define FBCS_CSCR_BEM_ON (1 << 5) +#define FBCS_CSCR_BEM_OFF (0 << 5) +#define FBCS_CSCR_BSTR_ON (1 << 4) +#define FBCS_CSCR_BSTR_OFF (0 << 4) +#define FBCS_CSCR_BSTW_ON (1 << 3) +#define FBCS_CSCR_BSTW_OFF (0 << 3) +#define FBCS_CSCR_SWWS(x) (((x) & 0x7) << 0) +#else #define FBCS_CSCR_SWS(x) (((x) & 0x3F) << 26) #define FBCS_CSCR_SWS_MASK (0x03FFFFFF) #define FBCS_CSCR_SWSEN (0x00800000) @@ -116,5 +183,6 @@ typedef struct fbcs { #define FBCS_CSCR_PS_16 (0x00000080) #define FBCS_CSCR_PS_8 (0x00000040) #define FBCS_CSCR_PS_32 (0x00000000) +#endif #endif /* __FLEXBUS_H */ -- cgit v1.1 From 55b523b7d4ab885142f77d388007eb5490ba6bf4 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 18 Sep 2012 08:05:28 +0000 Subject: ext4: cache-align buffers so the invalidation works DMA buffer cache invalidation requires that buffers have cache-aligned buffer locations and sizes. Use memalign() and ALLOC_CACHE_ALIGN_BUFFER() to ensure this. On Tegra at least, without this fix, the following fail commands fail in u-boot-master/ext4, but succeeded at the branch's branch point in u-boot/master. With this fix, the commands work again: ext2ls mmc 0:1 / ext2load mmc 0:1 /boot/zImage Cc: Uma Shankar Cc: Manjunatha C Achar Cc: Iqbal Shareef Cc: Hakgoo Lee Cc: Wolfgang Denk Cc: Tom Rini Signed-off-by: Stephen Warren --- fs/ext4/dev.c | 4 ++-- fs/ext4/ext4_common.c | 2 +- fs/ext4/ext4_common.h | 7 ++++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c index fb62f24..9e85228 100644 --- a/fs/ext4/dev.c +++ b/fs/ext4/dev.c @@ -62,7 +62,7 @@ int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part) int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf) { - char sec_buf[SECTOR_SIZE]; + ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, SECTOR_SIZE); unsigned block_len; /* Check partition boundaries */ @@ -107,7 +107,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf) block_len = byte_len & ~(SECTOR_SIZE - 1); if (block_len == 0) { - u8 p[SECTOR_SIZE]; + ALLOC_CACHE_ALIGN_BUFFER(u8, p, SECTOR_SIZE); block_len = SECTOR_SIZE; ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev, diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c index 083e45e..3deffd5 100644 --- a/fs/ext4/ext4_common.c +++ b/fs/ext4/ext4_common.c @@ -71,7 +71,7 @@ void put_ext4(uint64_t off, void *buf, uint32_t size) uint64_t startblock; uint64_t remainder; unsigned char *temp_ptr = NULL; - unsigned char sec_buf[SECTOR_SIZE]; + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, sec_buf, SECTOR_SIZE); struct ext_filesystem *fs = get_fs(); startblock = off / (uint64_t)SECTOR_SIZE; diff --git a/fs/ext4/ext4_common.h b/fs/ext4/ext4_common.h index 801b8b8..0af625d 100644 --- a/fs/ext4/ext4_common.h +++ b/fs/ext4/ext4_common.h @@ -55,7 +55,12 @@ #define SUPERBLOCK_SIZE 1024 #define F_FILE 1 -#define zalloc(size) calloc(1, size) +static inline void *zalloc(size_t size) +{ + void *p = memalign(ARCH_DMA_MINALIGN, size); + memset(p, 0, size); + return p; +} extern unsigned long part_offset; int ext4fs_read_inode(struct ext2_data *data, int ino, -- cgit v1.1 From 43e6627259da3900a73f40fb2fe3a6f106c0e2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Majewski?= Date: Thu, 23 Aug 2012 23:33:55 +0000 Subject: dfu:usb: Support for ext4 Support for ext4 file system handling at DFU. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Reviewed-by: Marek Vasut --- drivers/dfu/dfu_mmc.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c index 060145b..2270a61 100644 --- a/drivers/dfu/dfu_mmc.c +++ b/drivers/dfu/dfu_mmc.c @@ -63,10 +63,23 @@ static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu, char *str_env; int ret; - sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s %lx", - op == DFU_OP_READ ? "load" : "write", - dfu->data.mmc.dev, dfu->data.mmc.part, - (unsigned int) buf, dfu->name, *len); + switch (dfu->layout) { + case DFU_FS_FAT: + sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s %lx", + op == DFU_OP_READ ? "load" : "write", + dfu->data.mmc.dev, dfu->data.mmc.part, + (unsigned int) buf, dfu->name, *len); + break; + case DFU_FS_EXT4: + sprintf(cmd_buf, "ext4%s mmc %d:%d /%s 0x%x %ld", + op == DFU_OP_READ ? "load" : "write", + dfu->data.mmc.dev, dfu->data.mmc.part, + dfu->name, (unsigned int) buf, *len); + break; + default: + printf("%s: Layout (%s) not (yet) supported!\n", __func__, + dfu_get_layout(dfu->layout)); + } debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf); @@ -107,6 +120,7 @@ int dfu_write_medium_mmc(struct dfu_entity *dfu, void *buf, long *len) ret = mmc_block_write(dfu, buf, len); break; case DFU_FS_FAT: + case DFU_FS_EXT4: ret = mmc_file_write(dfu, buf, len); break; default: @@ -126,6 +140,7 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, void *buf, long *len) ret = mmc_block_read(dfu, buf, len); break; case DFU_FS_FAT: + case DFU_FS_EXT4: ret = mmc_file_read(dfu, buf, len); break; default: @@ -149,12 +164,17 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s) dfu->data.mmc.lba_blk_size = get_mmc_blk_size(dfu->dev_num); } else if (!strcmp(st, "fat")) { dfu->layout = DFU_FS_FAT; - dfu->data.mmc.dev = simple_strtoul(s, &s, 10); - dfu->data.mmc.part = simple_strtoul(++s, &s, 10); + } else if (!strcmp(st, "ext4")) { + dfu->layout = DFU_FS_EXT4; } else { printf("%s: Memory layout (%s) not supported!\n", __func__, st); } + if (dfu->layout == DFU_FS_EXT4 || dfu->layout == DFU_FS_FAT) { + dfu->data.mmc.dev = simple_strtoul(s, &s, 10); + dfu->data.mmc.part = simple_strtoul(++s, &s, 10); + } + dfu->read_medium = dfu_read_medium_mmc; dfu->write_medium = dfu_write_medium_mmc; -- cgit v1.1 From 81c1d7b605e1a48d3c02248c5e51fabcf42f5014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Majewski?= Date: Thu, 23 Aug 2012 23:33:56 +0000 Subject: dfu:usb:fix: Read the "filesize" environment variable only when file read The "filesize" environment variable shall be read only when relevant file is read. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park Reviewed-by: Marek Vasut --- drivers/dfu/dfu_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c index 2270a61..5d504df 100644 --- a/drivers/dfu/dfu_mmc.c +++ b/drivers/dfu/dfu_mmc.c @@ -89,7 +89,7 @@ static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu, return ret; } - if (dfu->layout != DFU_RAW_ADDR) { + if (dfu->layout != DFU_RAW_ADDR && op == DFU_OP_READ) { str_env = getenv("filesize"); if (str_env == NULL) { puts("dfu: Wrong file size!\n"); -- cgit v1.1 From 93ad908c43ed5d8e3e546dd22fa08b668c5090d9 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 6 Sep 2012 08:00:13 +0200 Subject: usb: do explicit unaligned accesses usb_hub_descriptor has to be packed as it's used for communication with the device. Member wHubCharacteristics violates the natural alignment rules. Use explicit unaligned access functions for this member. Fixes ARMv7 traping while using USB. v2: fix typo found by Thomas Langer v3: rebased on top of u-boot-usb/master Signed-off-by: Lucas Stach --- common/usb_hub.c | 14 +++++++++----- drivers/usb/host/ehci-hcd.c | 7 +++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/common/usb_hub.c b/common/usb_hub.c index f35ad95..32750e8 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -269,6 +270,7 @@ static int usb_hub_configure(struct usb_device *dev) int i; ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, USB_BUFSIZ); unsigned char *bitmap; + short hubCharacteristics; struct usb_hub_descriptor *descriptor; struct usb_hub_device *hub; #ifdef USB_HUB_DEBUG @@ -304,8 +306,9 @@ static int usb_hub_configure(struct usb_device *dev) } memcpy((unsigned char *)&hub->desc, buffer, descriptor->bLength); /* adjust 16bit values */ - hub->desc.wHubCharacteristics = - le16_to_cpu(descriptor->wHubCharacteristics); + put_unaligned(le16_to_cpu(get_unaligned( + &descriptor->wHubCharacteristics)), + &hub->desc.wHubCharacteristics); /* set the bitmap */ bitmap = (unsigned char *)&hub->desc.DeviceRemovable[0]; /* devices not removable by default */ @@ -322,7 +325,8 @@ static int usb_hub_configure(struct usb_device *dev) dev->maxchild = descriptor->bNbrPorts; USB_HUB_PRINTF("%d ports detected\n", dev->maxchild); - switch (hub->desc.wHubCharacteristics & HUB_CHAR_LPSM) { + hubCharacteristics = get_unaligned(&hub->desc.wHubCharacteristics); + switch (hubCharacteristics & HUB_CHAR_LPSM) { case 0x00: USB_HUB_PRINTF("ganged power switching\n"); break; @@ -335,12 +339,12 @@ static int usb_hub_configure(struct usb_device *dev) break; } - if (hub->desc.wHubCharacteristics & HUB_CHAR_COMPOUND) + if (hubCharacteristics & HUB_CHAR_COMPOUND) USB_HUB_PRINTF("part of a compound device\n"); else USB_HUB_PRINTF("standalone hub\n"); - switch (hub->desc.wHubCharacteristics & HUB_CHAR_OCPM) { + switch (hubCharacteristics & HUB_CHAR_OCPM) { case 0x00: USB_HUB_PRINTF("global over-current protection\n"); break; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 18b4bc6..392e286 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -22,6 +22,7 @@ */ #include #include +#include #include #include #include @@ -866,10 +867,12 @@ int usb_lowlevel_init(void) printf("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts); /* Port Indicators */ if (HCS_INDICATOR(reg)) - descriptor.hub.wHubCharacteristics |= 0x80; + put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics) + | 0x80, &descriptor.hub.wHubCharacteristics); /* Port Power Control */ if (HCS_PPC(reg)) - descriptor.hub.wHubCharacteristics |= 0x01; + put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics) + | 0x01, &descriptor.hub.wHubCharacteristics); /* Start the host controller. */ cmd = ehci_readl(&hcor->or_usbcmd); -- cgit v1.1 From 3ab270d5df7ae7bf8d7b5d225ab1abb37297d77e Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 21 Sep 2012 08:14:05 -0700 Subject: Revert "memsize: Fix for bug in memory sizing code" After further investigation this change is not correct and results in get_ram_size returning incorrectly large values. Reported first by Gerlando Falauto. This reverts commit b8496cced856ff411f1eb2e4eff20f5abe7080b0. Signed-off-by: Tom Rini --- common/memsize.c | 1 - 1 file changed, 1 deletion(-) diff --git a/common/memsize.c b/common/memsize.c index 74cf075..963e4f3 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -73,7 +73,6 @@ long get_ram_size(long *base, long maxsize) } return (0); } - *addr = save[i]; for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) { addr = base + cnt; /* pointer arith! */ -- cgit v1.1 From 1bbd28d21518e3118e0a2d1da87084b6846e5b32 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 13 Jun 2012 06:19:37 +0000 Subject: Add gpio_request() to asm-generic header This function should also be part of the GPIO API, so add it. Signed-off-by: Simon Glass --- include/asm-generic/gpio.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index c19e16c..23c9649 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -94,4 +94,13 @@ int gpio_get_value(unsigned gpio); */ int gpio_set_value(unsigned gpio, int value); +/** + * Request a gpio. This should be called before any of the other functions + * are used on this gpio. + * + * @param gp GPIO number + * @param label User label for this GPIO + * @return 0 if ok, -1 on error + */ +int gpio_request(unsigned gpio, const char *label); #endif /* _ASM_GENERIC_GPIO_H_ */ -- cgit v1.1 From 1cb2323b8a457f00f50a76a3491d7f21a3c0929f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 12 Jul 2012 05:25:01 +0000 Subject: fdt: Tidy debugging, add to fdtdec_get_int/addr() The new debugging shows the value of integers and addresses read from the device tree and tidy up GPIO output. Signed-off-by: Simon Glass --- lib/fdtdec.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/fdtdec.c b/lib/fdtdec.c index af17ac1..dd0879f 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -79,11 +79,16 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node, const fdt_addr_t *cell; int len; - debug("get_addr: %s\n", prop_name); + debug("%s: %s: ", __func__, prop_name); cell = fdt_getprop(blob, node, prop_name, &len); if (cell && (len == sizeof(fdt_addr_t) || - len == sizeof(fdt_addr_t) * 2)) - return fdt_addr_to_cpu(*cell); + len == sizeof(fdt_addr_t) * 2)) { + fdt_addr_t addr = fdt_addr_to_cpu(*cell); + + debug("%p\n", (void *)addr); + return addr; + } + debug("(not found)\n"); return FDT_ADDR_T_NONE; } @@ -93,10 +98,15 @@ s32 fdtdec_get_int(const void *blob, int node, const char *prop_name, const s32 *cell; int len; - debug("get_size: %s\n", prop_name); + debug("%s: %s: ", __func__, prop_name); cell = fdt_getprop(blob, node, prop_name, &len); - if (cell && len >= sizeof(s32)) - return fdt32_to_cpu(cell[0]); + if (cell && len >= sizeof(s32)) { + s32 val = fdt32_to_cpu(cell[0]); + + debug("%#x (%d)\n", val, val); + return val; + } + debug("(not found)\n"); return default_val; } @@ -328,6 +338,7 @@ int fdtdec_lookup_phandle(const void *blob, int node, const char *prop_name) const u32 *phandle; int lookup; + debug("%s: %s\n", __func__, prop_name); phandle = fdt_getprop(blob, node, prop_name, NULL); if (!phandle) return -FDT_ERR_NOTFOUND; @@ -427,7 +438,7 @@ static int fdtdec_decode_gpios(const void *blob, int node, assert(max_count > 0); prop = fdt_get_property(blob, node, prop_name, &len); if (!prop) { - debug("FDT: %s: property '%s' missing\n", __func__, prop_name); + debug("%s: property '%s' missing\n", __func__, prop_name); return -FDT_ERR_NOTFOUND; } @@ -436,7 +447,7 @@ static int fdtdec_decode_gpios(const void *blob, int node, cell = (u32 *)prop->data; len /= sizeof(u32) * 3; /* 3 cells per GPIO record */ if (len > max_count) { - debug("FDT: %s: too many GPIOs / cells for " + debug(" %s: too many GPIOs / cells for " "property '%s'\n", __func__, prop_name); return -FDT_ERR_BADLAYOUT; } -- cgit v1.1 From 5bfa78db4ffcc2c53aaf7e0a303008c80441b0b5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 12 Jul 2012 05:25:02 +0000 Subject: fdt: Add header guard to fdtdec.h This makes it easier to include this header from other headers. Signed-off-by: Simon Glass Acked-by: Mike Frysinger --- include/fdtdec.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/fdtdec.h b/include/fdtdec.h index a8f783f..d829606 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -19,6 +19,8 @@ * MA 02111-1307 USA */ +#ifndef __fdtdec_h +#define __fdtdec_h /* * This file contains convenience functions for decoding useful and @@ -382,3 +384,4 @@ int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name, */ const u8 *fdtdec_locate_byte_array(const void *blob, int node, const char *prop_name, int count); +#endif -- cgit v1.1 From 1b09b53e7dda7f8d4e7ec2927137f3b71327955a Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Sun, 19 Aug 2012 19:32:30 +0000 Subject: common/lcd: add protection from null bmp pointer If the bmp pointer is null then U-Boot will get stuck when trying to load the image. What's worse, it will get stuck before the U-Boot shell becomes available to the user, thus making it difficult to correct the situation. To protect from the above scenario, check if the pointer is valid. Signed-off-by: Nikita Kiryanov --- common/lcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lcd.c b/common/lcd.c index 88dfa51..fcc09ac 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -674,7 +674,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) unsigned long pwidth = panel_info.vl_col; unsigned colors, bpix, bmp_bpix; - if (!((bmp->header.signature[0] == 'B') && + if (!bmp || !((bmp->header.signature[0] == 'B') && (bmp->header.signature[1] == 'M'))) { printf("Error: no valid bmp image at %lx\n", bmp_image); -- cgit v1.1 From 15b83386aa50168bce659fdc33cd6784effa2e3d Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Mon, 17 Sep 2012 11:12:42 +0000 Subject: video/powerpc: don't touch DIU registers that we don't need Several DIU registers were being initialized either unnecessarily or to wrong values. 1) All interrupts were enabled even though there's no interrupt handler. Interrupts were left enabled when booting Linux. 2) Don't configure a dummy area descriptor, since we don't support ADs in U-Boot. 3) Don't configure any write-back buffer registers, since we don't use that mode. 4) The default values for the THRESHOLDS, SYN_POL, and PLUT registers should be used, so don't touch those registers either. Signed-off-by: Timur Tabi --- drivers/video/fsl_diu_fb.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/video/fsl_diu_fb.c b/drivers/video/fsl_diu_fb.c index 648ffa3..a98cb67 100644 --- a/drivers/video/fsl_diu_fb.c +++ b/drivers/video/fsl_diu_fb.c @@ -271,7 +271,6 @@ int fsl_diu_init(u16 xres, u16 yres, u32 pixel_format, int gamma_fix) struct diu *hw = (struct diu *)CONFIG_SYS_DIU_ADDR; u8 *gamma_table_base; unsigned int i, j; - struct diu_ad *dummy_ad; struct diu_addr gamma; struct diu_addr cursor; @@ -302,14 +301,6 @@ int fsl_diu_init(u16 xres, u16 yres, u32 pixel_format, int gamma_fix) return -1; } - /* The AD struct for the dummy framebuffer and the FB itself */ - dummy_ad = allocate_fb(2, 4, 4, NULL); - if (!dummy_ad) { - printf("DIU: Out of memory\n"); - return -1; - } - dummy_ad->pix_fmt = 0x88883316; - /* read mode info */ info.var.xres = fsl_diu_mode_db->xres; info.var.yres = fsl_diu_mode_db->yres; @@ -376,10 +367,7 @@ int fsl_diu_init(u16 xres, u16 yres, u32 pixel_format, int gamma_fix) out_be32(&hw->gamma, gamma.paddr); out_be32(&hw->cursor, cursor.paddr); out_be32(&hw->bgnd, 0x007F7F7F); - out_be32(&hw->bgnd_wb, 0); out_be32(&hw->disp_size, info.var.yres << 16 | info.var.xres); - out_be32(&hw->wb_size, 0); - out_be32(&hw->wb_mem_addr, 0); out_be32(&hw->hsyn_para, info.var.left_margin << 22 | info.var.hsync_len << 11 | info.var.right_margin); @@ -388,18 +376,13 @@ int fsl_diu_init(u16 xres, u16 yres, u32 pixel_format, int gamma_fix) info.var.vsync_len << 11 | info.var.lower_margin); - out_be32(&hw->syn_pol, 0); - out_be32(&hw->thresholds, 0x00037800); - out_be32(&hw->int_status, 0); - out_be32(&hw->int_mask, 0); - out_be32(&hw->plut, 0x01F5F666); /* Pixel Clock configuration */ diu_set_pixel_clock(info.var.pixclock); /* Set the frame buffers */ out_be32(&hw->desc[0], virt_to_phys(ad)); - out_be32(&hw->desc[1], virt_to_phys(dummy_ad)); - out_be32(&hw->desc[2], virt_to_phys(dummy_ad)); + out_be32(&hw->desc[1], 0); + out_be32(&hw->desc[2], 0); /* Enable the DIU, set display to all three planes */ out_be32(&hw->diu_mode, 1); -- cgit v1.1 From cf5787f2a4f1af71e72f4faaee32685c8f82a3dd Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 19 Sep 2012 04:47:36 +0000 Subject: pci: fix some warnings related to assumptions about The following commit introduced some warnings associated with using pci_addr_t instead of a proper 32-bit data type. commit af778c6d9e2b945ee03cbc53bb976238a3374f33 Author: Andrew Sharp Date: Wed Aug 1 12:27:16 2012 +0000 pci: fix errant data types and corresponding access functions On some platforms pci_addr_t is defined as a 64-bit data type so its not proper to use with pci_{read,write}_config_dword. Signed-off-by: Kumar Gala --- drivers/pci/pci.c | 6 +++--- drivers/pci/pci_auto.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2a6d0a7..d864f13 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -118,11 +118,11 @@ PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff) void *pci_map_bar(pci_dev_t pdev, int bar, int flags) { pci_addr_t pci_bus_addr; - pci_addr_t bar_response; + u32 bar_response; /* read BAR address */ pci_read_config_dword(pdev, bar, &bar_response); - pci_bus_addr = bar_response & ~0xf; + pci_bus_addr = (pci_addr_t)(bar_response & ~0xf); /* * Pass "0" as the length argument to pci_bus_to_virt. The arg @@ -389,7 +389,7 @@ int pci_hose_config_device(struct pci_controller *hose, pci_addr_t mem, unsigned long command) { - pci_addr_t bar_response; + u32 bar_response; unsigned int old_command; pci_addr_t bar_value; pci_size_t bar_size; diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index ae61e24..cd78030 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -89,7 +89,7 @@ void pciauto_setup_device(struct pci_controller *hose, struct pci_region *prefetch, struct pci_region *io) { - pci_addr_t bar_response; + u32 bar_response; pci_size_t bar_size; u16 cmdstat = 0; int bar, bar_nr = 0; -- cgit v1.1 From ee1f4caaa2a3f79d692155eec8a4c7289d60e106 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 21 Sep 2012 17:18:28 -0700 Subject: Prepare v2012.10-rc1 Signed-off-by: Tom Rini --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 27c6962..e3a27c6 100644 --- a/Makefile +++ b/Makefile @@ -22,9 +22,9 @@ # VERSION = 2012 -PATCHLEVEL = 07 +PATCHLEVEL = 10 SUBLEVEL = -EXTRAVERSION = +EXTRAVERSION = -rc1 ifneq "$(SUBLEVEL)" "" U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) else -- cgit v1.1 From 7f51898c1b170e0036e6931a17ada46e2b4fd52e Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 31 Jul 2012 06:06:41 +0000 Subject: net: Make netconsole src and dest ports configurable It is desirable to use different port numbers for sending and receiving packets with netconsole in the case where you have more than one device on the local subnet with netconsole enabled for broadcast. When they use the same port for both, any output from one will look like input to the other. This is typlically not desirable. This patch allows the input and output ports to be specified separately in the environment. Signed-off-by: Joe Hershberger Cc: Mike Frysinger Acked-by: Mike Frysinger --- doc/README.NetConsole | 3 +++ drivers/net/netconsole.c | 29 ++++++++++++++++++++--------- tools/netconsole | 18 +++++++++++------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/doc/README.NetConsole b/doc/README.NetConsole index c8bcb90..070e86a 100644 --- a/doc/README.NetConsole +++ b/doc/README.NetConsole @@ -11,6 +11,9 @@ port of the destination. The format is :. If is omitted, the value of 6666 is used. If the env var doesn't exist, the broadcast address and port 6666 are used. If it is set to an IP address of 0 (or 0.0.0.0) then no messages are sent to the network. +The source / listening port can be configured separately by setting +the 'ncinport' environment variable and the destination port can be +configured by setting the 'ncoutport' environment variable. For example, if your server IP is 192.168.1.1, you could use: diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 14243b8..86f5301 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -36,7 +36,8 @@ static int output_recursion; static int net_timeout; static uchar nc_ether[6]; /* server enet address */ static IPaddr_t nc_ip; /* server ip */ -static short nc_port; /* source/target port */ +static short nc_out_port; /* target output port */ +static short nc_in_port; /* source input port */ static const char *output_packet; /* used by first send udp */ static int output_packet_len; @@ -71,7 +72,7 @@ void NcStart(void) net_set_arp_handler(nc_wait_arp_handler); pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; memcpy(pkt, output_packet, output_packet_len); - NetSendUDPPacket(nc_ether, nc_ip, nc_port, nc_port, + NetSendUDPPacket(nc_ether, nc_ip, nc_out_port, nc_in_port, output_packet_len); } } @@ -80,7 +81,7 @@ int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len) { int end, chunk; - if (dest != nc_port || !len) + if (dest != nc_in_port || !len) return 0; /* not for us */ debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt); @@ -139,7 +140,7 @@ static void nc_send_packet(const char *buf, int len) memcpy(pkt, buf, len); ether = nc_ether; ip = nc_ip; - NetSendUDPPacket(ether, ip, nc_port, nc_port, len); + NetSendUDPPacket(ether, ip, nc_out_port, nc_in_port, len); if (inited) eth_halt(); @@ -148,20 +149,30 @@ static void nc_send_packet(const char *buf, int len) static int nc_start(void) { int netmask, our_ip; + char *p; - nc_port = 6666; /* default port */ + nc_out_port = 6666; /* default port */ + nc_in_port = nc_out_port; if (getenv("ncip")) { - char *p; nc_ip = getenv_IPaddr("ncip"); if (!nc_ip) return -1; /* ncip is 0.0.0.0 */ p = strchr(getenv("ncip"), ':'); - if (p != NULL) - nc_port = simple_strtoul(p + 1, NULL, 10); + if (p != NULL) { + nc_out_port = simple_strtoul(p + 1, NULL, 10); + nc_in_port = nc_out_port; + } } else - nc_ip = ~0; /* ncip is not set */ + nc_ip = ~0; /* ncip is not set, so broadcast */ + + p = getenv("ncoutport"); + if (p != NULL) + nc_out_port = simple_strtoul(p, NULL, 10); + p = getenv("ncinport"); + if (p != NULL) + nc_in_port = simple_strtoul(p, NULL, 10); our_ip = getenv_IPaddr("ipaddr"); netmask = getenv_IPaddr("netmask"); diff --git a/tools/netconsole b/tools/netconsole index c8109bb..1a0ef22 100755 --- a/tools/netconsole +++ b/tools/netconsole @@ -2,7 +2,7 @@ usage() { ( - echo "Usage: $0 [board port]" + echo "Usage: $0 [board-port [board-in-port]]" echo "" echo "If port is not specified, '6666' will be used" [ -z "$*" ] && exit 0 @@ -24,9 +24,13 @@ while [ -n "$1" ] ; do done ip=$1 -port=${2:-6666} +board_out_port=${2:-6666} +board_in_port=${3:-${board_out_port}} -if [ -z "${ip}" ] || [ -n "$3" ] ; then +echo Board out port: ${board_out_port} +echo Board in port: ${board_in_port} + +if [ -z "${ip}" ] || [ -n "$4" ] ; then usage "Invalid number of arguments" fi @@ -41,19 +45,19 @@ stty -icanon -echo intr ^T ( if type ncb 2>/dev/null ; then # see if ncb is in $PATH - exec ncb ${port} + exec ncb ${board_out_port} elif [ -x ${0%/*}/ncb ] ; then # maybe it's in the same dir as the netconsole script - exec ${0%/*}/ncb ${port} + exec ${0%/*}/ncb ${board_out_port} else # blah, just use regular netcat - while ${nc} -u -l -p ${port} < /dev/null ; do + while ${nc} -u -l -p ${board_out_port} < /dev/null ; do : done fi ) & pid=$! -${nc} -u ${ip} ${port} +${nc} -u ${ip} ${board_in_port} kill ${pid} 2>/dev/null -- cgit v1.1 From 46c07bcf12a7d6478b5e2f3e4b4c961d84428c6c Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Fri, 22 Jun 2012 11:24:28 +0000 Subject: api: net: fix length check in eth_receive() If the requested length is too small to hold the received packet, eth_receive() will return -1 and will leave the packet in the receive buffers. Instead of returning an error in this case, we return the first portion of the received packet and remove it from the receive buffers. This fixes FreeBSD's ubldr. Without this patch it will just stop receiving packets if the NIC receives more than PKTBUFSRX too large packets. Signed-off-by: Michael Walle Cc: Joe Hershberger Cc: Rafal Jaworowski Cc: Piotr Kruszynski --- net/eth.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/net/eth.c b/net/eth.c index 1a11ce1..bb4d95b 100644 --- a/net/eth.c +++ b/net/eth.c @@ -500,10 +500,7 @@ int eth_receive(void *packet, int length) return -1; } - if (length < eth_rcv_bufs[eth_rcv_current].length) - return -1; - - length = eth_rcv_bufs[eth_rcv_current].length; + length = min(eth_rcv_bufs[eth_rcv_current].length, length); for (i = 0; i < length; i++) p[i] = eth_rcv_bufs[eth_rcv_current].data[i]; -- cgit v1.1 From 1389f98fced3651ece415a6011ccbdfac3a52286 Mon Sep 17 00:00:00 2001 From: Tetsuyuki Kobayashi Date: Mon, 25 Jun 2012 02:37:27 +0000 Subject: net: bugfix: NetSetTimeout assumes CONFIG_SYS_HZ=1000 NetSetTimeout sets incorrect value to timeDelta when CONFIG_SYS_HZ != 1000. Signed-off-by: Tetsuyuki Kobayashi --- net/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/net.c b/net/net.c index e8ff066..f440434 100644 --- a/net/net.c +++ b/net/net.c @@ -652,7 +652,7 @@ NetSetTimeout(ulong iv, thand_f *f) "--- NetLoop timeout handler set (%p)\n", f); timeHandler = f; timeStart = get_timer(0); - timeDelta = iv; + timeDelta = iv * CONFIG_SYS_HZ / 1000; } } -- cgit v1.1 From 61e129885a8fd6d36c25301e537d46e66b6c6e6a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 21 Jul 2012 05:02:26 +0000 Subject: dm: net: Move IXP NPE to drivers/net/ Signed-off-by: Marek Vasut Cc: Bryan Hundven Cc: Michael Schwingen Cc: Wolfgang Denk Cc: Albert Aribaud Cc: U-Boot DM Cc: Joe Hershberger --- Makefile | 2 +- arch/arm/cpu/ixp/npe/IxEthAcc.c | 261 -- arch/arm/cpu/ixp/npe/IxEthAccCommon.c | 1049 -------- arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c | 533 ---- arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c | 2483 ------------------ arch/arm/cpu/ixp/npe/IxEthAccMac.c | 2641 -------------------- arch/arm/cpu/ixp/npe/IxEthAccMii.c | 410 --- arch/arm/cpu/ixp/npe/IxEthDBAPI.c | 448 ---- arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c | 675 ----- arch/arm/cpu/ixp/npe/IxEthDBCore.c | 463 ---- arch/arm/cpu/ixp/npe/IxEthDBEvents.c | 520 ---- arch/arm/cpu/ixp/npe/IxEthDBFeatures.c | 662 ----- arch/arm/cpu/ixp/npe/IxEthDBFirewall.c | 266 -- arch/arm/cpu/ixp/npe/IxEthDBHashtable.c | 642 ----- arch/arm/cpu/ixp/npe/IxEthDBLearning.c | 149 -- arch/arm/cpu/ixp/npe/IxEthDBMem.c | 649 ----- arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c | 719 ------ arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c | 740 ------ arch/arm/cpu/ixp/npe/IxEthDBReports.c | 652 ----- arch/arm/cpu/ixp/npe/IxEthDBSearch.c | 327 --- arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c | 107 - arch/arm/cpu/ixp/npe/IxEthDBUtil.c | 120 - arch/arm/cpu/ixp/npe/IxEthDBVlan.c | 1179 --------- arch/arm/cpu/ixp/npe/IxEthDBWiFi.c | 480 ---- arch/arm/cpu/ixp/npe/IxEthMii.c | 497 ---- arch/arm/cpu/ixp/npe/IxFeatureCtrl.c | 422 ---- arch/arm/cpu/ixp/npe/IxNpeDl.c | 940 ------- arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c | 687 ----- arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c | 931 ------- arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c | 806 ------ arch/arm/cpu/ixp/npe/IxNpeMh.c | 582 ----- arch/arm/cpu/ixp/npe/IxNpeMhConfig.c | 608 ----- arch/arm/cpu/ixp/npe/IxNpeMhReceive.c | 320 --- arch/arm/cpu/ixp/npe/IxNpeMhSend.c | 307 --- arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c | 358 --- arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c | 246 -- arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c | 800 ------ arch/arm/cpu/ixp/npe/IxOsalIoMem.c | 332 --- arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c | 67 - arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c | 79 - arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c | 233 -- arch/arm/cpu/ixp/npe/IxOsalOsServices.c | 251 -- arch/arm/cpu/ixp/npe/IxOsalOsThread.c | 98 - arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c | 963 ------- arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c | 1344 ---------- arch/arm/cpu/ixp/npe/IxQMgrInit.c | 233 -- arch/arm/cpu/ixp/npe/IxQMgrQAccess.c | 796 ------ arch/arm/cpu/ixp/npe/IxQMgrQCfg.c | 543 ---- arch/arm/cpu/ixp/npe/Makefile | 99 - arch/arm/cpu/ixp/npe/include/IxAssert.h | 71 - arch/arm/cpu/ixp/npe/include/IxAtmSch.h | 504 ---- arch/arm/cpu/ixp/npe/include/IxAtmTypes.h | 409 --- arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h | 1194 --------- arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h | 1958 --------------- arch/arm/cpu/ixp/npe/include/IxAtmm.h | 795 ------ arch/arm/cpu/ixp/npe/include/IxDmaAcc.h | 260 -- arch/arm/cpu/ixp/npe/include/IxEthAcc.h | 2512 ------------------- arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h | 245 -- arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h | 248 -- arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h | 97 - .../cpu/ixp/npe/include/IxEthAccQueueAssign_p.h | 137 - arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h | 325 --- arch/arm/cpu/ixp/npe/include/IxEthDB.h | 2373 ------------------ arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h | 122 - arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h | 227 -- arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h | 258 -- arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h | 163 -- arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h | 154 -- arch/arm/cpu/ixp/npe/include/IxEthDB_p.h | 710 ------ arch/arm/cpu/ixp/npe/include/IxEthMii.h | 270 -- arch/arm/cpu/ixp/npe/include/IxEthMii_p.h | 185 -- arch/arm/cpu/ixp/npe/include/IxEthNpe.h | 695 ------ arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h | 742 ------ arch/arm/cpu/ixp/npe/include/IxHssAcc.h | 1316 ---------- arch/arm/cpu/ixp/npe/include/IxI2cDrv.h | 867 ------- arch/arm/cpu/ixp/npe/include/IxNpeA.h | 782 ------ arch/arm/cpu/ixp/npe/include/IxNpeDl.h | 980 -------- arch/arm/cpu/ixp/npe/include/IxNpeDlImageMgr_p.h | 363 --- arch/arm/cpu/ixp/npe/include/IxNpeDlMacros_p.h | 414 --- .../ixp/npe/include/IxNpeDlNpeMgrEcRegisters_p.h | 893 ------- .../arm/cpu/ixp/npe/include/IxNpeDlNpeMgrUtils_p.h | 405 --- arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgr_p.h | 260 -- arch/arm/cpu/ixp/npe/include/IxNpeMh.h | 497 ---- arch/arm/cpu/ixp/npe/include/IxNpeMhConfig_p.h | 555 ---- arch/arm/cpu/ixp/npe/include/IxNpeMhMacros_p.h | 296 --- arch/arm/cpu/ixp/npe/include/IxNpeMhReceive_p.h | 139 -- arch/arm/cpu/ixp/npe/include/IxNpeMhSend_p.h | 163 -- .../cpu/ixp/npe/include/IxNpeMhSolicitedCbMgr_p.h | 171 -- .../ixp/npe/include/IxNpeMhUnsolicitedCbMgr_p.h | 169 -- arch/arm/cpu/ixp/npe/include/IxNpeMicrocode.h | 296 --- arch/arm/cpu/ixp/npe/include/IxOsBufLib.h | 55 - arch/arm/cpu/ixp/npe/include/IxOsBuffMgt.h | 52 - arch/arm/cpu/ixp/npe/include/IxOsBuffPoolMgt.h | 74 - arch/arm/cpu/ixp/npe/include/IxOsCacheMMU.h | 60 - arch/arm/cpu/ixp/npe/include/IxOsPrintf.h | 102 - arch/arm/cpu/ixp/npe/include/IxOsServices.h | 55 - .../cpu/ixp/npe/include/IxOsServicesComponents.h | 134 - .../cpu/ixp/npe/include/IxOsServicesEndianess.h | 52 - .../cpu/ixp/npe/include/IxOsServicesMemAccess.h | 52 - arch/arm/cpu/ixp/npe/include/IxOsServicesMemMap.h | 54 - arch/arm/cpu/ixp/npe/include/IxOsal.h | 1517 ----------- arch/arm/cpu/ixp/npe/include/IxOsalAssert.h | 81 - arch/arm/cpu/ixp/npe/include/IxOsalBackward.h | 65 - .../arm/cpu/ixp/npe/include/IxOsalBackwardAssert.h | 54 - .../cpu/ixp/npe/include/IxOsalBackwardBufferMgt.h | 159 -- .../cpu/ixp/npe/include/IxOsalBackwardCacheMMU.h | 69 - .../arm/cpu/ixp/npe/include/IxOsalBackwardMemMap.h | 141 -- .../cpu/ixp/npe/include/IxOsalBackwardOsServices.h | 125 - arch/arm/cpu/ixp/npe/include/IxOsalBackwardOssl.h | 272 -- arch/arm/cpu/ixp/npe/include/IxOsalBufferMgt.h | 621 ----- .../cpu/ixp/npe/include/IxOsalBufferMgtDefault.h | 88 - arch/arm/cpu/ixp/npe/include/IxOsalConfig.h | 76 - arch/arm/cpu/ixp/npe/include/IxOsalEndianess.h | 134 - arch/arm/cpu/ixp/npe/include/IxOsalIoMem.h | 322 --- arch/arm/cpu/ixp/npe/include/IxOsalMemAccess.h | 494 ---- arch/arm/cpu/ixp/npe/include/IxOsalOem.h | 97 - arch/arm/cpu/ixp/npe/include/IxOsalOs.h | 30 - arch/arm/cpu/ixp/npe/include/IxOsalOsAssert.h | 10 - arch/arm/cpu/ixp/npe/include/IxOsalOsBufferMgt.h | 96 - arch/arm/cpu/ixp/npe/include/IxOsalOsIxp400.h | 316 --- .../npe/include/IxOsalOsIxp400CustomizedMapping.h | 404 --- arch/arm/cpu/ixp/npe/include/IxOsalOsTypes.h | 60 - .../cpu/ixp/npe/include/IxOsalOsUtilitySymbols.h | 4 - arch/arm/cpu/ixp/npe/include/IxOsalTypes.h | 401 --- .../arm/cpu/ixp/npe/include/IxOsalUtilitySymbols.h | 51 - arch/arm/cpu/ixp/npe/include/IxParityENAcc.h | 785 ------ arch/arm/cpu/ixp/npe/include/IxPerfProfAcc.h | 1358 ---------- arch/arm/cpu/ixp/npe/include/IxQMgr.h | 2210 ---------------- arch/arm/cpu/ixp/npe/include/IxQMgrAqmIf_p.h | 927 ------- arch/arm/cpu/ixp/npe/include/IxQMgrDefines_p.h | 55 - arch/arm/cpu/ixp/npe/include/IxQMgrDispatcher_p.h | 106 - arch/arm/cpu/ixp/npe/include/IxQMgrLog_p.h | 124 - arch/arm/cpu/ixp/npe/include/IxQMgrQAccess_p.h | 96 - arch/arm/cpu/ixp/npe/include/IxQMgrQCfg_p.h | 122 - arch/arm/cpu/ixp/npe/include/IxQueueAssignments.h | 516 ---- arch/arm/cpu/ixp/npe/include/IxSspAcc.h | 1271 ---------- arch/arm/cpu/ixp/npe/include/IxTimeSyncAcc.h | 783 ------ arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h | 263 -- arch/arm/cpu/ixp/npe/include/IxTypes.h | 86 - arch/arm/cpu/ixp/npe/include/IxUART.h | 458 ---- arch/arm/cpu/ixp/npe/include/IxVersionId.h | 155 -- arch/arm/cpu/ixp/npe/include/ix_error.h | 66 - arch/arm/cpu/ixp/npe/include/ix_macros.h | 266 -- arch/arm/cpu/ixp/npe/include/ix_os_type.h | 65 - arch/arm/cpu/ixp/npe/include/ix_ossl.h | 160 -- arch/arm/cpu/ixp/npe/include/ix_symbols.h | 106 - arch/arm/cpu/ixp/npe/include/ix_types.h | 208 -- arch/arm/cpu/ixp/npe/include/npe.h | 90 - arch/arm/cpu/ixp/npe/include/os_datatypes.h | 82 - arch/arm/cpu/ixp/npe/miiphy.c | 120 - arch/arm/cpu/ixp/npe/npe.c | 696 ------ drivers/net/npe/IxEthAcc.c | 261 ++ drivers/net/npe/IxEthAccCommon.c | 1049 ++++++++ drivers/net/npe/IxEthAccControlInterface.c | 533 ++++ drivers/net/npe/IxEthAccDataPlane.c | 2483 ++++++++++++++++++ drivers/net/npe/IxEthAccMac.c | 2641 ++++++++++++++++++++ drivers/net/npe/IxEthAccMii.c | 410 +++ drivers/net/npe/IxEthDBAPI.c | 448 ++++ drivers/net/npe/IxEthDBAPISupport.c | 675 +++++ drivers/net/npe/IxEthDBCore.c | 463 ++++ drivers/net/npe/IxEthDBEvents.c | 520 ++++ drivers/net/npe/IxEthDBFeatures.c | 662 +++++ drivers/net/npe/IxEthDBFirewall.c | 266 ++ drivers/net/npe/IxEthDBHashtable.c | 642 +++++ drivers/net/npe/IxEthDBLearning.c | 149 ++ drivers/net/npe/IxEthDBMem.c | 649 +++++ drivers/net/npe/IxEthDBNPEAdaptor.c | 719 ++++++ drivers/net/npe/IxEthDBPortUpdate.c | 740 ++++++ drivers/net/npe/IxEthDBReports.c | 652 +++++ drivers/net/npe/IxEthDBSearch.c | 327 +++ drivers/net/npe/IxEthDBSpanningTree.c | 107 + drivers/net/npe/IxEthDBUtil.c | 120 + drivers/net/npe/IxEthDBVlan.c | 1179 +++++++++ drivers/net/npe/IxEthDBWiFi.c | 480 ++++ drivers/net/npe/IxEthMii.c | 497 ++++ drivers/net/npe/IxFeatureCtrl.c | 422 ++++ drivers/net/npe/IxNpeDl.c | 940 +++++++ drivers/net/npe/IxNpeDlImageMgr.c | 687 +++++ drivers/net/npe/IxNpeDlNpeMgr.c | 931 +++++++ drivers/net/npe/IxNpeDlNpeMgrUtils.c | 806 ++++++ drivers/net/npe/IxNpeMh.c | 582 +++++ drivers/net/npe/IxNpeMhConfig.c | 608 +++++ drivers/net/npe/IxNpeMhReceive.c | 320 +++ drivers/net/npe/IxNpeMhSend.c | 307 +++ drivers/net/npe/IxNpeMhSolicitedCbMgr.c | 358 +++ drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c | 246 ++ drivers/net/npe/IxOsalBufferMgt.c | 800 ++++++ drivers/net/npe/IxOsalIoMem.c | 332 +++ drivers/net/npe/IxOsalOsCacheMMU.c | 67 + drivers/net/npe/IxOsalOsMsgQ.c | 79 + drivers/net/npe/IxOsalOsSemaphore.c | 233 ++ drivers/net/npe/IxOsalOsServices.c | 251 ++ drivers/net/npe/IxOsalOsThread.c | 98 + drivers/net/npe/IxQMgrAqmIf.c | 963 +++++++ drivers/net/npe/IxQMgrDispatcher.c | 1344 ++++++++++ drivers/net/npe/IxQMgrInit.c | 233 ++ drivers/net/npe/IxQMgrQAccess.c | 796 ++++++ drivers/net/npe/IxQMgrQCfg.c | 543 ++++ drivers/net/npe/Makefile | 99 + drivers/net/npe/include/IxAssert.h | 71 + drivers/net/npe/include/IxAtmSch.h | 504 ++++ drivers/net/npe/include/IxAtmTypes.h | 409 +++ drivers/net/npe/include/IxAtmdAcc.h | 1194 +++++++++ drivers/net/npe/include/IxAtmdAccCtrl.h | 1958 +++++++++++++++ drivers/net/npe/include/IxAtmm.h | 795 ++++++ drivers/net/npe/include/IxDmaAcc.h | 260 ++ drivers/net/npe/include/IxEthAcc.h | 2512 +++++++++++++++++++ drivers/net/npe/include/IxEthAccDataPlane_p.h | 245 ++ drivers/net/npe/include/IxEthAccMac_p.h | 248 ++ drivers/net/npe/include/IxEthAccMii_p.h | 97 + drivers/net/npe/include/IxEthAccQueueAssign_p.h | 137 + drivers/net/npe/include/IxEthAcc_p.h | 325 +++ drivers/net/npe/include/IxEthDB.h | 2373 ++++++++++++++++++ drivers/net/npe/include/IxEthDBLocks_p.h | 122 + drivers/net/npe/include/IxEthDBLog_p.h | 227 ++ drivers/net/npe/include/IxEthDBMessages_p.h | 258 ++ drivers/net/npe/include/IxEthDBPortDefs.h | 163 ++ drivers/net/npe/include/IxEthDBQoS.h | 154 ++ drivers/net/npe/include/IxEthDB_p.h | 710 ++++++ drivers/net/npe/include/IxEthMii.h | 270 ++ drivers/net/npe/include/IxEthMii_p.h | 185 ++ drivers/net/npe/include/IxEthNpe.h | 695 ++++++ drivers/net/npe/include/IxFeatureCtrl.h | 742 ++++++ drivers/net/npe/include/IxHssAcc.h | 1316 ++++++++++ drivers/net/npe/include/IxI2cDrv.h | 867 +++++++ drivers/net/npe/include/IxNpeA.h | 782 ++++++ drivers/net/npe/include/IxNpeDl.h | 980 ++++++++ drivers/net/npe/include/IxNpeDlImageMgr_p.h | 363 +++ drivers/net/npe/include/IxNpeDlMacros_p.h | 414 +++ .../net/npe/include/IxNpeDlNpeMgrEcRegisters_p.h | 893 +++++++ drivers/net/npe/include/IxNpeDlNpeMgrUtils_p.h | 405 +++ drivers/net/npe/include/IxNpeDlNpeMgr_p.h | 260 ++ drivers/net/npe/include/IxNpeMh.h | 497 ++++ drivers/net/npe/include/IxNpeMhConfig_p.h | 555 ++++ drivers/net/npe/include/IxNpeMhMacros_p.h | 296 +++ drivers/net/npe/include/IxNpeMhReceive_p.h | 139 ++ drivers/net/npe/include/IxNpeMhSend_p.h | 163 ++ drivers/net/npe/include/IxNpeMhSolicitedCbMgr_p.h | 171 ++ .../net/npe/include/IxNpeMhUnsolicitedCbMgr_p.h | 169 ++ drivers/net/npe/include/IxNpeMicrocode.h | 296 +++ drivers/net/npe/include/IxOsBufLib.h | 55 + drivers/net/npe/include/IxOsBuffMgt.h | 52 + drivers/net/npe/include/IxOsBuffPoolMgt.h | 74 + drivers/net/npe/include/IxOsCacheMMU.h | 60 + drivers/net/npe/include/IxOsPrintf.h | 102 + drivers/net/npe/include/IxOsServices.h | 55 + drivers/net/npe/include/IxOsServicesComponents.h | 134 + drivers/net/npe/include/IxOsServicesEndianess.h | 52 + drivers/net/npe/include/IxOsServicesMemAccess.h | 52 + drivers/net/npe/include/IxOsServicesMemMap.h | 54 + drivers/net/npe/include/IxOsal.h | 1517 +++++++++++ drivers/net/npe/include/IxOsalAssert.h | 81 + drivers/net/npe/include/IxOsalBackward.h | 65 + drivers/net/npe/include/IxOsalBackwardAssert.h | 54 + drivers/net/npe/include/IxOsalBackwardBufferMgt.h | 159 ++ drivers/net/npe/include/IxOsalBackwardCacheMMU.h | 69 + drivers/net/npe/include/IxOsalBackwardMemMap.h | 141 ++ drivers/net/npe/include/IxOsalBackwardOsServices.h | 125 + drivers/net/npe/include/IxOsalBackwardOssl.h | 272 ++ drivers/net/npe/include/IxOsalBufferMgt.h | 621 +++++ drivers/net/npe/include/IxOsalBufferMgtDefault.h | 88 + drivers/net/npe/include/IxOsalConfig.h | 76 + drivers/net/npe/include/IxOsalEndianess.h | 134 + drivers/net/npe/include/IxOsalIoMem.h | 322 +++ drivers/net/npe/include/IxOsalMemAccess.h | 494 ++++ drivers/net/npe/include/IxOsalOem.h | 97 + drivers/net/npe/include/IxOsalOs.h | 30 + drivers/net/npe/include/IxOsalOsAssert.h | 10 + drivers/net/npe/include/IxOsalOsBufferMgt.h | 96 + drivers/net/npe/include/IxOsalOsIxp400.h | 316 +++ .../npe/include/IxOsalOsIxp400CustomizedMapping.h | 404 +++ drivers/net/npe/include/IxOsalOsTypes.h | 60 + drivers/net/npe/include/IxOsalOsUtilitySymbols.h | 4 + drivers/net/npe/include/IxOsalTypes.h | 401 +++ drivers/net/npe/include/IxOsalUtilitySymbols.h | 51 + drivers/net/npe/include/IxParityENAcc.h | 785 ++++++ drivers/net/npe/include/IxPerfProfAcc.h | 1358 ++++++++++ drivers/net/npe/include/IxQMgr.h | 2210 ++++++++++++++++ drivers/net/npe/include/IxQMgrAqmIf_p.h | 927 +++++++ drivers/net/npe/include/IxQMgrDefines_p.h | 55 + drivers/net/npe/include/IxQMgrDispatcher_p.h | 106 + drivers/net/npe/include/IxQMgrLog_p.h | 124 + drivers/net/npe/include/IxQMgrQAccess_p.h | 96 + drivers/net/npe/include/IxQMgrQCfg_p.h | 122 + drivers/net/npe/include/IxQueueAssignments.h | 516 ++++ drivers/net/npe/include/IxSspAcc.h | 1271 ++++++++++ drivers/net/npe/include/IxTimeSyncAcc.h | 783 ++++++ drivers/net/npe/include/IxTimerCtrl.h | 263 ++ drivers/net/npe/include/IxTypes.h | 86 + drivers/net/npe/include/IxUART.h | 458 ++++ drivers/net/npe/include/IxVersionId.h | 155 ++ drivers/net/npe/include/ix_error.h | 66 + drivers/net/npe/include/ix_macros.h | 266 ++ drivers/net/npe/include/ix_os_type.h | 65 + drivers/net/npe/include/ix_ossl.h | 160 ++ drivers/net/npe/include/ix_symbols.h | 106 + drivers/net/npe/include/ix_types.h | 208 ++ drivers/net/npe/include/npe.h | 90 + drivers/net/npe/include/os_datatypes.h | 82 + drivers/net/npe/miiphy.c | 120 + drivers/net/npe/npe.c | 696 ++++++ 301 files changed, 69489 insertions(+), 69489 deletions(-) delete mode 100644 arch/arm/cpu/ixp/npe/IxEthAcc.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthAccCommon.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthAccMac.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthAccMii.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBAPI.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBCore.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBEvents.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBFeatures.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBFirewall.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBHashtable.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBLearning.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBMem.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBReports.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBSearch.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBUtil.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBVlan.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthDBWiFi.c delete mode 100644 arch/arm/cpu/ixp/npe/IxEthMii.c delete mode 100644 arch/arm/cpu/ixp/npe/IxFeatureCtrl.c delete mode 100644 arch/arm/cpu/ixp/npe/IxNpeDl.c delete mode 100644 arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c delete mode 100644 arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c delete mode 100644 arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c delete mode 100644 arch/arm/cpu/ixp/npe/IxNpeMh.c delete mode 100644 arch/arm/cpu/ixp/npe/IxNpeMhConfig.c delete mode 100644 arch/arm/cpu/ixp/npe/IxNpeMhReceive.c delete mode 100644 arch/arm/cpu/ixp/npe/IxNpeMhSend.c delete mode 100644 arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c delete mode 100644 arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c delete mode 100644 arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c delete mode 100644 arch/arm/cpu/ixp/npe/IxOsalIoMem.c delete mode 100644 arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c delete mode 100644 arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c delete mode 100644 arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c delete mode 100644 arch/arm/cpu/ixp/npe/IxOsalOsServices.c delete mode 100644 arch/arm/cpu/ixp/npe/IxOsalOsThread.c delete mode 100644 arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c delete mode 100644 arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c delete mode 100644 arch/arm/cpu/ixp/npe/IxQMgrInit.c delete mode 100644 arch/arm/cpu/ixp/npe/IxQMgrQAccess.c delete mode 100644 arch/arm/cpu/ixp/npe/IxQMgrQCfg.c delete mode 100644 arch/arm/cpu/ixp/npe/Makefile delete mode 100644 arch/arm/cpu/ixp/npe/include/IxAssert.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxAtmSch.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxAtmTypes.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxAtmm.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxDmaAcc.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthAcc.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthDB.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthDB_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthMii.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthMii_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxEthNpe.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxHssAcc.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxI2cDrv.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeA.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeDl.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeDlImageMgr_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeDlMacros_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgrEcRegisters_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgrUtils_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeDlNpeMgr_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeMh.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeMhConfig_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeMhMacros_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeMhReceive_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeMhSend_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeMhSolicitedCbMgr_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeMhUnsolicitedCbMgr_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxNpeMicrocode.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsBufLib.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsBuffMgt.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsBuffPoolMgt.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsCacheMMU.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsPrintf.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsServices.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsServicesComponents.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsServicesEndianess.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsServicesMemAccess.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsServicesMemMap.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsal.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalAssert.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalBackward.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalBackwardAssert.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalBackwardBufferMgt.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalBackwardCacheMMU.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalBackwardMemMap.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalBackwardOsServices.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalBackwardOssl.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalBufferMgt.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalBufferMgtDefault.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalConfig.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalEndianess.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalIoMem.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalMemAccess.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalOem.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalOs.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalOsAssert.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalOsBufferMgt.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalOsIxp400.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalOsIxp400CustomizedMapping.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalOsTypes.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalOsUtilitySymbols.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalTypes.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxOsalUtilitySymbols.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxParityENAcc.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxPerfProfAcc.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxQMgr.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxQMgrAqmIf_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxQMgrDefines_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxQMgrDispatcher_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxQMgrLog_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxQMgrQAccess_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxQMgrQCfg_p.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxQueueAssignments.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxSspAcc.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxTimeSyncAcc.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxTypes.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxUART.h delete mode 100644 arch/arm/cpu/ixp/npe/include/IxVersionId.h delete mode 100644 arch/arm/cpu/ixp/npe/include/ix_error.h delete mode 100644 arch/arm/cpu/ixp/npe/include/ix_macros.h delete mode 100644 arch/arm/cpu/ixp/npe/include/ix_os_type.h delete mode 100644 arch/arm/cpu/ixp/npe/include/ix_ossl.h delete mode 100644 arch/arm/cpu/ixp/npe/include/ix_symbols.h delete mode 100644 arch/arm/cpu/ixp/npe/include/ix_types.h delete mode 100644 arch/arm/cpu/ixp/npe/include/npe.h delete mode 100644 arch/arm/cpu/ixp/npe/include/os_datatypes.h delete mode 100644 arch/arm/cpu/ixp/npe/miiphy.c delete mode 100644 arch/arm/cpu/ixp/npe/npe.c create mode 100644 drivers/net/npe/IxEthAcc.c create mode 100644 drivers/net/npe/IxEthAccCommon.c create mode 100644 drivers/net/npe/IxEthAccControlInterface.c create mode 100644 drivers/net/npe/IxEthAccDataPlane.c create mode 100644 drivers/net/npe/IxEthAccMac.c create mode 100644 drivers/net/npe/IxEthAccMii.c create mode 100644 drivers/net/npe/IxEthDBAPI.c create mode 100644 drivers/net/npe/IxEthDBAPISupport.c create mode 100644 drivers/net/npe/IxEthDBCore.c create mode 100644 drivers/net/npe/IxEthDBEvents.c create mode 100644 drivers/net/npe/IxEthDBFeatures.c create mode 100644 drivers/net/npe/IxEthDBFirewall.c create mode 100644 drivers/net/npe/IxEthDBHashtable.c create mode 100644 drivers/net/npe/IxEthDBLearning.c create mode 100644 drivers/net/npe/IxEthDBMem.c create mode 100644 drivers/net/npe/IxEthDBNPEAdaptor.c create mode 100644 drivers/net/npe/IxEthDBPortUpdate.c create mode 100644 drivers/net/npe/IxEthDBReports.c create mode 100644 drivers/net/npe/IxEthDBSearch.c create mode 100644 drivers/net/npe/IxEthDBSpanningTree.c create mode 100644 drivers/net/npe/IxEthDBUtil.c create mode 100644 drivers/net/npe/IxEthDBVlan.c create mode 100644 drivers/net/npe/IxEthDBWiFi.c create mode 100644 drivers/net/npe/IxEthMii.c create mode 100644 drivers/net/npe/IxFeatureCtrl.c create mode 100644 drivers/net/npe/IxNpeDl.c create mode 100644 drivers/net/npe/IxNpeDlImageMgr.c create mode 100644 drivers/net/npe/IxNpeDlNpeMgr.c create mode 100644 drivers/net/npe/IxNpeDlNpeMgrUtils.c create mode 100644 drivers/net/npe/IxNpeMh.c create mode 100644 drivers/net/npe/IxNpeMhConfig.c create mode 100644 drivers/net/npe/IxNpeMhReceive.c create mode 100644 drivers/net/npe/IxNpeMhSend.c create mode 100644 drivers/net/npe/IxNpeMhSolicitedCbMgr.c create mode 100644 drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c create mode 100644 drivers/net/npe/IxOsalBufferMgt.c create mode 100644 drivers/net/npe/IxOsalIoMem.c create mode 100644 drivers/net/npe/IxOsalOsCacheMMU.c create mode 100644 drivers/net/npe/IxOsalOsMsgQ.c create mode 100644 drivers/net/npe/IxOsalOsSemaphore.c create mode 100644 drivers/net/npe/IxOsalOsServices.c create mode 100644 drivers/net/npe/IxOsalOsThread.c create mode 100644 drivers/net/npe/IxQMgrAqmIf.c create mode 100644 drivers/net/npe/IxQMgrDispatcher.c create mode 100644 drivers/net/npe/IxQMgrInit.c create mode 100644 drivers/net/npe/IxQMgrQAccess.c create mode 100644 drivers/net/npe/IxQMgrQCfg.c create mode 100644 drivers/net/npe/Makefile create mode 100644 drivers/net/npe/include/IxAssert.h create mode 100644 drivers/net/npe/include/IxAtmSch.h create mode 100644 drivers/net/npe/include/IxAtmTypes.h create mode 100644 drivers/net/npe/include/IxAtmdAcc.h create mode 100644 drivers/net/npe/include/IxAtmdAccCtrl.h create mode 100644 drivers/net/npe/include/IxAtmm.h create mode 100644 drivers/net/npe/include/IxDmaAcc.h create mode 100644 drivers/net/npe/include/IxEthAcc.h create mode 100644 drivers/net/npe/include/IxEthAccDataPlane_p.h create mode 100644 drivers/net/npe/include/IxEthAccMac_p.h create mode 100644 drivers/net/npe/include/IxEthAccMii_p.h create mode 100644 drivers/net/npe/include/IxEthAccQueueAssign_p.h create mode 100644 drivers/net/npe/include/IxEthAcc_p.h create mode 100644 drivers/net/npe/include/IxEthDB.h create mode 100644 drivers/net/npe/include/IxEthDBLocks_p.h create mode 100644 drivers/net/npe/include/IxEthDBLog_p.h create mode 100644 drivers/net/npe/include/IxEthDBMessages_p.h create mode 100644 drivers/net/npe/include/IxEthDBPortDefs.h create mode 100644 drivers/net/npe/include/IxEthDBQoS.h create mode 100644 drivers/net/npe/include/IxEthDB_p.h create mode 100644 drivers/net/npe/include/IxEthMii.h create mode 100644 drivers/net/npe/include/IxEthMii_p.h create mode 100644 drivers/net/npe/include/IxEthNpe.h create mode 100644 drivers/net/npe/include/IxFeatureCtrl.h create mode 100644 drivers/net/npe/include/IxHssAcc.h create mode 100644 drivers/net/npe/include/IxI2cDrv.h create mode 100644 drivers/net/npe/include/IxNpeA.h create mode 100644 drivers/net/npe/include/IxNpeDl.h create mode 100644 drivers/net/npe/include/IxNpeDlImageMgr_p.h create mode 100644 drivers/net/npe/include/IxNpeDlMacros_p.h create mode 100644 drivers/net/npe/include/IxNpeDlNpeMgrEcRegisters_p.h create mode 100644 drivers/net/npe/include/IxNpeDlNpeMgrUtils_p.h create mode 100644 drivers/net/npe/include/IxNpeDlNpeMgr_p.h create mode 100644 drivers/net/npe/include/IxNpeMh.h create mode 100644 drivers/net/npe/include/IxNpeMhConfig_p.h create mode 100644 drivers/net/npe/include/IxNpeMhMacros_p.h create mode 100644 drivers/net/npe/include/IxNpeMhReceive_p.h create mode 100644 drivers/net/npe/include/IxNpeMhSend_p.h create mode 100644 drivers/net/npe/include/IxNpeMhSolicitedCbMgr_p.h create mode 100644 drivers/net/npe/include/IxNpeMhUnsolicitedCbMgr_p.h create mode 100644 drivers/net/npe/include/IxNpeMicrocode.h create mode 100644 drivers/net/npe/include/IxOsBufLib.h create mode 100644 drivers/net/npe/include/IxOsBuffMgt.h create mode 100644 drivers/net/npe/include/IxOsBuffPoolMgt.h create mode 100644 drivers/net/npe/include/IxOsCacheMMU.h create mode 100644 drivers/net/npe/include/IxOsPrintf.h create mode 100644 drivers/net/npe/include/IxOsServices.h create mode 100644 drivers/net/npe/include/IxOsServicesComponents.h create mode 100644 drivers/net/npe/include/IxOsServicesEndianess.h create mode 100644 drivers/net/npe/include/IxOsServicesMemAccess.h create mode 100644 drivers/net/npe/include/IxOsServicesMemMap.h create mode 100644 drivers/net/npe/include/IxOsal.h create mode 100644 drivers/net/npe/include/IxOsalAssert.h create mode 100644 drivers/net/npe/include/IxOsalBackward.h create mode 100644 drivers/net/npe/include/IxOsalBackwardAssert.h create mode 100644 drivers/net/npe/include/IxOsalBackwardBufferMgt.h create mode 100644 drivers/net/npe/include/IxOsalBackwardCacheMMU.h create mode 100644 drivers/net/npe/include/IxOsalBackwardMemMap.h create mode 100644 drivers/net/npe/include/IxOsalBackwardOsServices.h create mode 100644 drivers/net/npe/include/IxOsalBackwardOssl.h create mode 100644 drivers/net/npe/include/IxOsalBufferMgt.h create mode 100644 drivers/net/npe/include/IxOsalBufferMgtDefault.h create mode 100644 drivers/net/npe/include/IxOsalConfig.h create mode 100644 drivers/net/npe/include/IxOsalEndianess.h create mode 100644 drivers/net/npe/include/IxOsalIoMem.h create mode 100644 drivers/net/npe/include/IxOsalMemAccess.h create mode 100644 drivers/net/npe/include/IxOsalOem.h create mode 100644 drivers/net/npe/include/IxOsalOs.h create mode 100644 drivers/net/npe/include/IxOsalOsAssert.h create mode 100644 drivers/net/npe/include/IxOsalOsBufferMgt.h create mode 100644 drivers/net/npe/include/IxOsalOsIxp400.h create mode 100644 drivers/net/npe/include/IxOsalOsIxp400CustomizedMapping.h create mode 100644 drivers/net/npe/include/IxOsalOsTypes.h create mode 100644 drivers/net/npe/include/IxOsalOsUtilitySymbols.h create mode 100644 drivers/net/npe/include/IxOsalTypes.h create mode 100644 drivers/net/npe/include/IxOsalUtilitySymbols.h create mode 100644 drivers/net/npe/include/IxParityENAcc.h create mode 100644 drivers/net/npe/include/IxPerfProfAcc.h create mode 100644 drivers/net/npe/include/IxQMgr.h create mode 100644 drivers/net/npe/include/IxQMgrAqmIf_p.h create mode 100644 drivers/net/npe/include/IxQMgrDefines_p.h create mode 100644 drivers/net/npe/include/IxQMgrDispatcher_p.h create mode 100644 drivers/net/npe/include/IxQMgrLog_p.h create mode 100644 drivers/net/npe/include/IxQMgrQAccess_p.h create mode 100644 drivers/net/npe/include/IxQMgrQCfg_p.h create mode 100644 drivers/net/npe/include/IxQueueAssignments.h create mode 100644 drivers/net/npe/include/IxSspAcc.h create mode 100644 drivers/net/npe/include/IxTimeSyncAcc.h create mode 100644 drivers/net/npe/include/IxTimerCtrl.h create mode 100644 drivers/net/npe/include/IxTypes.h create mode 100644 drivers/net/npe/include/IxUART.h create mode 100644 drivers/net/npe/include/IxVersionId.h create mode 100644 drivers/net/npe/include/ix_error.h create mode 100644 drivers/net/npe/include/ix_macros.h create mode 100644 drivers/net/npe/include/ix_os_type.h create mode 100644 drivers/net/npe/include/ix_ossl.h create mode 100644 drivers/net/npe/include/ix_symbols.h create mode 100644 drivers/net/npe/include/ix_types.h create mode 100644 drivers/net/npe/include/npe.h create mode 100644 drivers/net/npe/include/os_datatypes.h create mode 100644 drivers/net/npe/miiphy.c create mode 100644 drivers/net/npe/npe.c diff --git a/Makefile b/Makefile index e3a27c6..6718f8d 100644 --- a/Makefile +++ b/Makefile @@ -238,7 +238,7 @@ ifdef SOC LIBS-y += $(CPUDIR)/$(SOC)/lib$(SOC).o endif ifeq ($(CPU),ixp) -LIBS-y += arch/arm/cpu/ixp/npe/libnpe.o +LIBS-y += drivers/net/npe/libnpe.o endif LIBS-$(CONFIG_OF_EMBED) += dts/libdts.o LIBS-y += arch/$(ARCH)/lib/lib$(ARCH).o diff --git a/arch/arm/cpu/ixp/npe/IxEthAcc.c b/arch/arm/cpu/ixp/npe/IxEthAcc.c deleted file mode 100644 index 20d3d9e..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthAcc.c +++ /dev/null @@ -1,261 +0,0 @@ -/** - * @file IxEthAcc.c - * - * @author Intel Corporation - * @date 20-Feb-2001 - * - * @brief This file contains the implementation of the IXP425 Ethernet Access Component - * - * Design Notes: - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - - - -#include "IxEthAcc.h" -#ifdef CONFIG_IXP425_COMPONENT_ETHDB -#include "IxEthDB.h" -#endif -#include "IxFeatureCtrl.h" - -#include "IxEthAcc_p.h" -#include "IxEthAccMac_p.h" -#include "IxEthAccMii_p.h" - -/** - * @addtogroup IxEthAcc - *@{ - */ - - -/** - * @brief System-wide information data strucure. - * - * @ingroup IxEthAccPri - * - */ - -IxEthAccInfo ixEthAccDataInfo; -extern PUBLIC IxEthAccMacState ixEthAccMacState[]; -extern PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex; - -/** - * @brief System-wide information - * - * @ingroup IxEthAccPri - * - */ -BOOL ixEthAccServiceInit = FALSE; - -/* global filtering bit mask */ -PUBLIC UINT32 ixEthAccNewSrcMask; - -/** - * @brief Per port information data strucure. - * - * @ingroup IxEthAccPri - * - */ - -IxEthAccPortDataInfo ixEthAccPortData[IX_ETH_ACC_NUMBER_OF_PORTS]; - -PUBLIC IxEthAccStatus ixEthAccInit() -{ -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - /* - * Initialize Control plane - */ - if (ixEthDBInit() != IX_ETH_DB_SUCCESS) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccInit: EthDB init failed\n", 0, 0, 0, 0, 0, 0); - - return IX_ETH_ACC_FAIL; - } -#endif - - if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING)) - { - ixEthAccNewSrcMask = (~0); /* want all the bits */ - } - else - { - ixEthAccNewSrcMask = (~IX_ETHACC_NE_NEWSRCMASK); /* want all but the NewSrc bit */ - } - - /* - * Initialize Data plane - */ - if ( ixEthAccInitDataPlane() != IX_ETH_ACC_SUCCESS ) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccInit: data plane init failed\n", 0, 0, 0, 0, 0, 0); - - return IX_ETH_ACC_FAIL; - } - - - if ( ixEthAccQMgrQueuesConfig() != IX_ETH_ACC_SUCCESS ) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccInit: queue config failed\n", 0, 0, 0, 0, 0, 0); - - return IX_ETH_ACC_FAIL; - } - - /* - * Initialize MII - */ - if ( ixEthAccMiiInit() != IX_ETH_ACC_SUCCESS ) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mii init failed\n", 0, 0, 0, 0, 0, 0); - - return IX_ETH_ACC_FAIL; - } - - /* - * Initialize MAC I/O memory - */ - if (ixEthAccMacMemInit() != IX_ETH_ACC_SUCCESS) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mac init failed\n", 0, 0, 0, 0, 0, 0); - - return IX_ETH_ACC_FAIL; - } - - /* - * Initialize control plane interface lock - */ - if (ixOsalMutexInit(&ixEthAccControlInterfaceMutex) != IX_SUCCESS) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Control plane interface lock initialization failed\n", 0, 0, 0, 0, 0, 0); - - return IX_ETH_ACC_FAIL; - } - - /* initialiasation is complete */ - ixEthAccServiceInit = TRUE; - - return IX_ETH_ACC_SUCCESS; - -} - -PUBLIC void ixEthAccUnload(void) -{ - IxEthAccPortId portId; - - if ( IX_ETH_ACC_IS_SERVICE_INITIALIZED() ) - { - /* check none of the port is still active */ - for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - if ( IX_ETH_IS_PORT_INITIALIZED(portId) ) - { - if (ixEthAccMacState[portId].portDisableState == ACTIVE) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccUnload: port %u still active, bail out\n", portId, 0, 0, 0, 0, 0); - return; - } - } - } - - /* unmap the memory areas */ - ixEthAccMiiUnload(); - ixEthAccMacUnload(); - - /* set all ports as uninitialized */ - for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - ixEthAccPortData[portId].portInitialized = FALSE; - } - - /* uninitialize the service */ - ixEthAccServiceInit = FALSE; - } -} - -PUBLIC IxEthAccStatus ixEthAccPortInit( IxEthAccPortId portId) -{ - - IxEthAccStatus ret=IX_ETH_ACC_SUCCESS; - - if ( ! IX_ETH_ACC_IS_SERVICE_INITIALIZED() ) - { - return(IX_ETH_ACC_FAIL); - } - - /* - * Check for valid port - */ - - if ( ! IX_ETH_ACC_IS_PORT_VALID(portId) ) - { - return (IX_ETH_ACC_INVALID_PORT); - } - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Eth port.\n",(INT32) portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if ( IX_ETH_IS_PORT_INITIALIZED(portId) ) - { - /* Already initialized */ - return(IX_ETH_ACC_FAIL); - } - - if(ixEthAccMacInit(portId)!=IX_ETH_ACC_SUCCESS) - { - return IX_ETH_ACC_FAIL; - } - - /* - * Set the port init flag. - */ - - ixEthAccPortData[portId].portInitialized = TRUE; - -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - /* init learning/filtering database structures for this port */ - ixEthDBPortInit(portId); -#endif - - return(ret); -} - - diff --git a/arch/arm/cpu/ixp/npe/IxEthAccCommon.c b/arch/arm/cpu/ixp/npe/IxEthAccCommon.c deleted file mode 100644 index 211203d..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthAccCommon.c +++ /dev/null @@ -1,1049 +0,0 @@ -/** - * @file IxEthAccCommon.c - * - * @author Intel Corporation - * @date 12-Feb-2002 - * - * @brief This file contains the implementation common support routines for the component - * - * Design Notes: - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/* - * Component header files - */ - -#include "IxOsal.h" -#include "IxEthAcc.h" -#include "IxEthDB.h" -#include "IxNpeMh.h" -#include "IxEthDBPortDefs.h" -#include "IxFeatureCtrl.h" -#include "IxEthAcc_p.h" -#include "IxEthAccQueueAssign_p.h" - -#include "IxEthAccDataPlane_p.h" -#include "IxEthAccMii_p.h" - -/** - * @addtogroup IxEthAccPri - *@{ - */ - -extern IxEthAccInfo ixEthAccDataInfo; - -/** - * - * @brief Maximum number of RX queues set to be the maximum number - * of traffic calsses. - * - */ -#define IX_ETHACC_MAX_RX_QUEUES \ - (IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY \ - - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY \ - + 1) - -/** - * - * @brief Maximum number of 128 entry RX queues - * - */ -#define IX_ETHACC_MAX_LARGE_RX_QUEUES 4 - -/** - * - * @brief Data structure template for Default RX Queues - * - */ -IX_ETH_ACC_PRIVATE -IxEthAccQregInfo ixEthAccQmgrRxDefaultTemplate = - { - IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */ - "Eth Rx Q", - ixEthRxFrameQMCallback, /**< Functional callback */ - (IxQMgrCallbackId) 0, /**< Callback tag */ - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - TRUE, /**< Enable Q notification at startup */ - IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */ - }; - -/** - * - * @brief Data structure template for Small RX Queues - * - */ -IX_ETH_ACC_PRIVATE -IxEthAccQregInfo ixEthAccQmgrRxSmallTemplate = - { - IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */ - "Eth Rx Q", - ixEthRxFrameQMCallback, /**< Functional callback */ - (IxQMgrCallbackId) 0, /**< Callback tag */ - IX_QMGR_Q_SIZE64, /**< Allocate Smaller Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - TRUE, /**< Enable Q notification at startup */ - IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */ - }; - - -/** - * - * @brief Data structure used to register & initialize the Queues - * - */ -IX_ETH_ACC_PRIVATE -IxEthAccQregInfo ixEthAccQmgrStaticInfo[]= -{ - { - IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q, - "Eth Rx Fr Q 1", - ixEthRxFreeQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_1, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - FALSE, /**< Disable Q notification at startup */ - IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /***< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ - }, - - { - IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q, - "Eth Rx Fr Q 2", - ixEthRxFreeQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_2, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - FALSE, /**< Disable Q notification at startup */ - IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ - }, -#ifdef __ixp46X - { - IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q, - "Eth Rx Fr Q 3", - ixEthRxFreeQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_3, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - FALSE, /**< Disable Q notification at startup */ - IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ - }, -#endif - { - IX_ETH_ACC_TX_FRAME_ENET0_Q, - "Eth Tx Q 1", - ixEthTxFrameQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_1, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - FALSE, /**< Disable Q notification at startup */ - IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ - }, - - { - IX_ETH_ACC_TX_FRAME_ENET1_Q, - "Eth Tx Q 2", - ixEthTxFrameQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_2, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - FALSE, /**< Disable Q notification at startup */ - IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ - }, -#ifdef __ixp46X - { - IX_ETH_ACC_TX_FRAME_ENET2_Q, - "Eth Tx Q 3", - ixEthTxFrameQMCallback, - (IxQMgrCallbackId) IX_ETH_PORT_3, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /** Queue Entry Sizes - all Q entries are single ord entries */ - FALSE, /** Disable Q notification at startup */ - IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE, /** Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /* No queues use almost empty */ - IX_QMGR_Q_WM_LEVEL64, /** Q High water mark - needed used */ - }, -#endif - { - IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, - "Eth Tx Done Q", - ixEthTxFrameDoneQMCallback, - (IxQMgrCallbackId) 0, - IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ - IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ - TRUE, /**< Enable Q notification at startup */ - IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE, /**< Q Condition to drive callback */ - IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ - IX_QMGR_Q_WM_LEVEL2, /**< Q High water mark - needed by NPE */ - }, - - { /* Null Termination entry - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - } - -}; - -/** - * - * @brief Data structure used to register & initialize the Queues - * - * The structure will be filled at run time depending on the NPE - * image already loaded and the QoS configured in ethDB. - * - */ -IX_ETH_ACC_PRIVATE -IxEthAccQregInfo ixEthAccQmgrRxQueuesInfo[IX_ETHACC_MAX_RX_QUEUES+1]= -{ - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* PlaceHolder for rx queues - * depending on the QoS configured - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - }, - - { /* Null Termination entry - */ - (IxQMgrQId)0, - (char *) NULL, - (IxQMgrCallback) NULL, - (IxQMgrCallbackId) 0, - 0, - 0, - 0, - 0, - 0, - 0 - } - -}; - -/* forward declarations */ -IX_ETH_ACC_PRIVATE IxEthAccStatus -ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes); - -/** - * @fn ixEthAccQMgrQueueSetup(void) - * - * @brief Setup one queue and its event, and register the callback required - * by this component to the QMgr - * - * @internal - */ -IX_ETH_ACC_PRIVATE IxEthAccStatus -ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes) -{ - /* - * Configure each Q. - */ - if ( ixQMgrQConfig( qInfoDes->qName, - qInfoDes->qId, - qInfoDes->qSize, - qInfoDes->qWords) != IX_SUCCESS) - { - return IX_ETH_ACC_FAIL; - } - - if ( ixQMgrWatermarkSet( qInfoDes->qId, - qInfoDes->AlmostEmptyThreshold, - qInfoDes->AlmostFullThreshold - ) != IX_SUCCESS) - { - return IX_ETH_ACC_FAIL; - } - - /* - * Set dispatcher priority. - */ - if ( ixQMgrDispatcherPrioritySet( qInfoDes->qId, - IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY) - != IX_SUCCESS) - { - return IX_ETH_ACC_FAIL; - } - - /* - * Register callbacks for each Q. - */ - if ( ixQMgrNotificationCallbackSet(qInfoDes->qId, - qInfoDes->qCallback, - qInfoDes->callbackTag) - != IX_SUCCESS ) - { - return IX_ETH_ACC_FAIL; - } - - /* - * Set notification condition for Q - */ - if ( qInfoDes->qNotificationEnableAtStartup == TRUE ) - { - if ( ixQMgrNotificationEnable(qInfoDes->qId, - qInfoDes->qConditionSource) - != IX_SUCCESS ) - { - return IX_ETH_ACC_FAIL; - } - } - - return(IX_ETH_ACC_SUCCESS); -} - -/** - * @fn ixEthAccQMgrQueuesConfig(void) - * - * @brief Setup all the queues and register all callbacks required - * by this component to the QMgr - * - * The RxFree queues, tx queues, rx queues are configured statically - * - * Rx queues configuration is driven by QoS setup. - * Many Rx queues may be required when QoS is enabled (this depends - * on IxEthDB setup and the images being downloaded). The configuration - * of the rxQueues is done in many steps as follows: - * - * @li select all Rx queues as configured by ethDB for all ports - * @li sort the queues by traffic class - * @li build the priority dependency for all queues - * @li fill the configuration for all rx queues - * @li configure all statically configured queues - * @li configure all dynamically configured queues - * - * @param none - * - * @return IxEthAccStatus - * - * @internal - */ -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccQMgrQueuesConfig(void) -{ - struct - { - int npeCount; - UINT32 npeId; - IxQMgrQId qId; - IxEthDBProperty trafficClass; - } rxQueues[IX_ETHACC_MAX_RX_QUEUES]; - - UINT32 rxQueue = 0; - UINT32 rxQueueCount = 0; - IxQMgrQId ixQId =IX_QMGR_MAX_NUM_QUEUES; - IxEthDBStatus ixEthDBStatus = IX_ETH_DB_SUCCESS; - IxEthDBPortId ixEthDbPortId = 0; - IxEthAccPortId ixEthAccPortId = 0; - UINT32 ixNpeId = 0; - UINT32 ixHighestNpeId = 0; - UINT32 sortIterations = 0; - IxEthAccStatus ret = IX_ETH_ACC_SUCCESS; - IxEthAccQregInfo *qInfoDes = NULL; - IxEthDBProperty ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; - IxEthDBPropertyType ixEthDBPropertyType = IX_ETH_DB_INTEGER_PROPERTY; - UINT32 ixEthDBParameter = 0; - BOOL completelySorted = FALSE; - - /* Fill the corspondance between ports and queues - * This defines the mapping from port to queue Ids. - */ - - ixEthAccPortData[IX_ETH_PORT_1].ixEthAccRxData.rxFreeQueue - = IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q; - ixEthAccPortData[IX_ETH_PORT_2].ixEthAccRxData.rxFreeQueue - = IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q; -#ifdef __ixp46X - ixEthAccPortData[IX_ETH_PORT_3].ixEthAccRxData.rxFreeQueue - = IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q; -#endif - ixEthAccPortData[IX_ETH_PORT_1].ixEthAccTxData.txQueue - = IX_ETH_ACC_TX_FRAME_ENET0_Q; - ixEthAccPortData[IX_ETH_PORT_2].ixEthAccTxData.txQueue - = IX_ETH_ACC_TX_FRAME_ENET1_Q; -#ifdef __ixp46X - ixEthAccPortData[IX_ETH_PORT_3].ixEthAccTxData.txQueue - = IX_ETH_ACC_TX_FRAME_ENET2_Q; -#endif - /* Fill the corspondance between ports and NPEs - * This defines the mapping from port to npeIds. - */ - - ixEthAccPortData[IX_ETH_PORT_1].npeId = IX_NPEMH_NPEID_NPEB; - ixEthAccPortData[IX_ETH_PORT_2].npeId = IX_NPEMH_NPEID_NPEC; -#ifdef __ixp46X - ixEthAccPortData[IX_ETH_PORT_3].npeId = IX_NPEMH_NPEID_NPEA; -#endif - /* set the default rx scheduling discipline */ - ixEthAccDataInfo.schDiscipline = FIFO_NO_PRIORITY; - - /* - * Queue Selection step: - * - * The following code selects all the queues and build - * a temporary array which contains for each queue - * - the queue Id, - * - the highest traffic class (in case of many - * priorities configured for the same queue on different - * ports) - * - the number of different Npes which are - * configured to write to this queue. - * - * The output of this loop is a temporary array of RX queues - * in any order. - * - */ -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - for (ixEthAccPortId = 0; - (ixEthAccPortId < IX_ETH_ACC_NUMBER_OF_PORTS) - && (ret == IX_ETH_ACC_SUCCESS); - ixEthAccPortId++) - { - /* map between ethDb and ethAcc port Ids */ - ixEthDbPortId = (IxEthDBPortId)ixEthAccPortId; - - /* map between npeId and ethAcc port Ids */ - ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId); - - /* Iterate thru the different priorities */ - for (ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; - ixEthDBTrafficClass <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY; - ixEthDBTrafficClass++) - { - ixEthDBStatus = ixEthDBFeaturePropertyGet( - ixEthDbPortId, - IX_ETH_DB_VLAN_QOS, - ixEthDBTrafficClass, - &ixEthDBPropertyType, - (void *)&ixEthDBParameter); - - if (ixEthDBStatus == IX_ETH_DB_SUCCESS) - { - /* This port and QoS class are mapped to - * a RX queue. - */ - if (ixEthDBPropertyType == IX_ETH_DB_INTEGER_PROPERTY) - { - /* remember the highest npe Id supporting ethernet */ - if (ixNpeId > ixHighestNpeId) - { - ixHighestNpeId = ixNpeId; - } - - /* search the queue in the list of queues - * already used by an other port or QoS - */ - for (rxQueue = 0; - rxQueue < rxQueueCount; - rxQueue++) - { - if (rxQueues[rxQueue].qId == (IxQMgrQId)ixEthDBParameter) - { - /* found an existing setup, update the number of ports - * for this queue if the port maps to - * a different NPE. - */ - if (rxQueues[rxQueue].npeId != ixNpeId) - { - rxQueues[rxQueue].npeCount++; - rxQueues[rxQueue].npeId = ixNpeId; - } - /* get the highest traffic class for this queue */ - if (rxQueues[rxQueue].trafficClass > ixEthDBTrafficClass) - { - rxQueues[rxQueue].trafficClass = ixEthDBTrafficClass; - } - break; - } - } - if (rxQueue == rxQueueCount) - { - /* new queue not found in the current list, - * add a new entry. - */ - IX_OSAL_ASSERT(rxQueueCount < IX_ETHACC_MAX_RX_QUEUES); - rxQueues[rxQueueCount].qId = ixEthDBParameter; - rxQueues[rxQueueCount].npeCount = 1; - rxQueues[rxQueueCount].npeId = ixNpeId; - rxQueues[rxQueueCount].trafficClass = ixEthDBTrafficClass; - rxQueueCount++; - } - } - else - { - /* unexpected property type (not Integer) */ - ret = IX_ETH_ACC_FAIL; - - IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: unexpected property type returned by EthDB\n", 0, 0, 0, 0, 0, 0); - - /* no point to continue to iterate */ - break; - } - } - else - { - /* No Rx queue configured for this port - * and this traffic class. Do nothing. - */ - } - } - - /* notify EthDB that queue initialization is complete and traffic class allocation is frozen */ - ixEthDBFeaturePropertySet(ixEthDbPortId, - IX_ETH_DB_VLAN_QOS, - IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE, - NULL /* ignored */); - } - -#else - - ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId); - rxQueues[0].qId = 4; - rxQueues[0].npeCount = 1; - rxQueues[0].npeId = ixNpeId; - rxQueues[0].trafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; - rxQueueCount++; - -#endif - - /* check there is at least 1 rx queue : there is no point - * to continue if there is no rx queue configured - */ - if ((rxQueueCount == 0) || (ret == IX_ETH_ACC_FAIL)) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: no queues configured, bailing out\n", 0, 0, 0, 0, 0, 0); - return (IX_ETH_ACC_FAIL); - } - - /* Queue sort step: - * - * Re-order the array of queues by decreasing traffic class - * using a bubble sort. (trafficClass 0 is the lowest - * priority traffic, trafficClass 7 is the highest priority traffic) - * - * Primary sort order is traffic class - * Secondary sort order is npeId - * - * Note that a bubble sort algorithm is not very efficient when - * the number of queues grows . However, this is not a very bad choice - * considering the very small number of entries to sort. Also, bubble - * sort is extremely fast when the list is already sorted. - * - * The output of this loop is a sorted array of queues. - * - */ - sortIterations = 0; - do - { - sortIterations++; - completelySorted = TRUE; - for (rxQueue = 0; - rxQueue < rxQueueCount - sortIterations; - rxQueue++) - { - /* compare adjacent elements */ - if ((rxQueues[rxQueue].trafficClass < - rxQueues[rxQueue+1].trafficClass) - || ((rxQueues[rxQueue].trafficClass == - rxQueues[rxQueue+1].trafficClass) - &&(rxQueues[rxQueue].npeId < - rxQueues[rxQueue+1].npeId))) - { - /* swap adjacent elements */ - int npeCount = rxQueues[rxQueue].npeCount; - UINT32 npeId = rxQueues[rxQueue].npeId; - IxQMgrQId qId = rxQueues[rxQueue].qId; - IxEthDBProperty trafficClass = rxQueues[rxQueue].trafficClass; - rxQueues[rxQueue].npeCount = rxQueues[rxQueue+1].npeCount; - rxQueues[rxQueue].npeId = rxQueues[rxQueue+1].npeId; - rxQueues[rxQueue].qId = rxQueues[rxQueue+1].qId; - rxQueues[rxQueue].trafficClass = rxQueues[rxQueue+1].trafficClass; - rxQueues[rxQueue+1].npeCount = npeCount; - rxQueues[rxQueue+1].npeId = npeId; - rxQueues[rxQueue+1].qId = qId; - rxQueues[rxQueue+1].trafficClass = trafficClass; - completelySorted = FALSE; - } - } - } - while (!completelySorted); - - /* Queue traffic class list: - * - * Fill an array of rx queues linked by ascending traffic classes. - * - * If the queues are configured as follows - * qId 6 -> traffic class 0 (lowest) - * qId 7 -> traffic class 0 - * qId 8 -> traffic class 6 - * qId 12 -> traffic class 7 (highest) - * - * Then the output of this loop will be - * - * higherPriorityQueue[6] = 8 - * higherPriorityQueue[7] = 8 - * higherPriorityQueue[8] = 12 - * higherPriorityQueue[12] = Invalid queueId - * higherPriorityQueue[...] = Invalid queueId - * - * Note that this queue ordering does not handle all possibilities - * that could result from different rules associated with different - * ports, and inconsistencies in the rules. In all cases, the - * output of this algorithm is a simple linked list of queues, - * without closed circuit. - - * This list is implemented as an array with invalid values initialized - * with an "invalid" queue id which is the maximum number of queues. - * - */ - - /* - * Initialise the rx queue list. - */ - for (rxQueue = 0; rxQueue < IX_QMGR_MAX_NUM_QUEUES; rxQueue++) - { - ixEthAccDataInfo.higherPriorityQueue[rxQueue] = IX_QMGR_MAX_NUM_QUEUES; - } - - /* build the linked list for this NPE. - */ - for (ixNpeId = 0; - ixNpeId <= ixHighestNpeId; - ixNpeId++) - { - /* iterate thru the sorted list of queues - */ - ixQId = IX_QMGR_MAX_NUM_QUEUES; - for (rxQueue = 0; - rxQueue < rxQueueCount; - rxQueue++) - { - if (rxQueues[rxQueue].npeId == ixNpeId) - { - ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId; - /* iterate thru queues with the same traffic class - * than the current queue. (queues are ordered by descending - * traffic classes and npeIds). - */ - while ((rxQueue < rxQueueCount - 1) - && (rxQueues[rxQueue].trafficClass - == rxQueues[rxQueue+1].trafficClass) - && (ixNpeId == rxQueues[rxQueue].npeId)) - { - rxQueue++; - ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId; - } - ixQId = rxQueues[rxQueue].qId; - } - } - } - - /* point on the first dynamic queue description */ - qInfoDes = ixEthAccQmgrRxQueuesInfo; - - /* update the list of queues with the rx queues */ - for (rxQueue = 0; - (rxQueue < rxQueueCount) && (ret == IX_ETH_ACC_SUCCESS); - rxQueue++) - { - /* Don't utilize more than IX_ETHACC_MAX_LARGE_RX_QUEUES queues - * with the full 128 entries. For the lower priority queues, use - * a smaller number of entries. This ensures queue resources - * remain available for other components. - */ - if( (rxQueueCount > IX_ETHACC_MAX_LARGE_RX_QUEUES) && - (rxQueue < rxQueueCount - IX_ETHACC_MAX_LARGE_RX_QUEUES) ) - { - /* add the small RX Queue setup template to the list of queues */ - memcpy(qInfoDes, &ixEthAccQmgrRxSmallTemplate, sizeof(*qInfoDes)); - } else { - /* add the default RX Queue setup template to the list of queues */ - memcpy(qInfoDes, &ixEthAccQmgrRxDefaultTemplate, sizeof(*qInfoDes)); - } - - /* setup the RxQueue ID */ - qInfoDes->qId = rxQueues[rxQueue].qId; - - /* setup the RxQueue watermark level - * - * Each queue can be filled by many NPEs. To avoid the - * NPEs to write to a full queue, need to set the - * high watermark level for nearly full condition. - * (the high watermark level are a power of 2 - * starting from the top of the queue) - * - * Number of watermark - * ports level - * 1 0 - * 2 1 - * 3 2 - * 4 4 - * 5 4 - * 6 8 - * n approx. 2**ceil(log2(n)) - */ - if (rxQueues[rxQueue].npeCount == 1) - { - qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL0; - } - else if (rxQueues[rxQueue].npeCount == 2) - { - qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL1; - } - else if (rxQueues[rxQueue].npeCount == 3) - { - qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL2; - } - else - { - /* reach the maximum number for CSR 2.0 */ - IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: maximum number of NPEs per queue reached, bailing out\n", 0, 0, 0, 0, 0, 0); - ret = IX_ETH_ACC_FAIL; - break; - } - - /* move to next queue entry */ - ++qInfoDes; - } - - /* configure the static list (RxFree, Tx and TxDone queues) */ - for (qInfoDes = ixEthAccQmgrStaticInfo; - (qInfoDes->qCallback != (IxQMgrCallback) NULL ) - && (ret == IX_ETH_ACC_SUCCESS); - ++qInfoDes) - { - ret = ixEthAccQMgrQueueSetup(qInfoDes); - } - - /* configure the dynamic list (Rx queues) */ - for (qInfoDes = ixEthAccQmgrRxQueuesInfo; - (qInfoDes->qCallback != (IxQMgrCallback) NULL ) - && (ret == IX_ETH_ACC_SUCCESS); - ++qInfoDes) - { - ret = ixEthAccQMgrQueueSetup(qInfoDes); - } - - return(ret); -} - -/** - * @fn ixEthAccQMgrRxQEntryGet(UINT32 *rxQueueEntries) - * - * @brief Add and return the total number of entries in all Rx queues - * - * @param UINT32 rxQueueEntries[in] number of entries in all queues - * - * @return void - * - * @note Rx queues configuration is driven by Qos Setup. There is a - * variable number of rx queues which are set at initialisation. - * - * @internal - */ -IX_ETH_ACC_PUBLIC -void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries) -{ - UINT32 rxQueueLevel; - IxEthAccQregInfo *qInfoDes;; - - *numRxQueueEntries = 0; - - /* iterate thru rx queues */ - for (qInfoDes = ixEthAccQmgrRxQueuesInfo; - qInfoDes->qCallback != (IxQMgrCallback)NULL; - ++qInfoDes) - { - /* retrieve the rx queue level */ - rxQueueLevel = 0; - ixQMgrQNumEntriesGet(qInfoDes->qId, &rxQueueLevel); - (*numRxQueueEntries) += rxQueueLevel; - } -} - -/** - * @fn ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback) - * - * @brief Change the callback registered to all rx queues. - * - * @param IxQMgrCallback ixQMgrCallback[in] QMgr callback to register - * - * @return IxEthAccStatus - * - * @note The user may decide to use different Rx mechanisms - * (e.g. receive many frames at the same time , or receive - * one frame at a time, depending on the overall application - * performances). A different QMgr callback is registered. This - * way, there is no excessive pointer checks in the datapath. - * - * @internal - */ -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback) -{ - IxEthAccQregInfo *qInfoDes; - IxEthAccStatus ret = IX_ETH_ACC_SUCCESS; - - /* parameter check */ - if (NULL == ixQMgrCallback) - { - ret = IX_ETH_ACC_FAIL; - } - - /* iterate thru rx queues */ - for (qInfoDes = ixEthAccQmgrRxQueuesInfo; - (qInfoDes->qCallback != (IxQMgrCallback) NULL ) - && (ret == IX_ETH_ACC_SUCCESS); - ++qInfoDes) - { - /* register the rx callback for all queues */ - if (ixQMgrNotificationCallbackSet(qInfoDes->qId, - ixQMgrCallback, - qInfoDes->callbackTag - ) != IX_SUCCESS) - { - ret = IX_ETH_ACC_FAIL; - } - } - return(ret); -} - -/** - * @fn ixEthAccSingleEthNpeCheck(IxEthAccPortId portId) - * - * @brief Check the npe exists for this port - * - * @param IxEthAccPortId portId[in] port - * - * @return IxEthAccStatus - * - * @internal - */ -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId portId) -{ - - /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */ - if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != - (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) - || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) - { - if ((IX_ETH_PORT_1 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == - IX_FEATURE_CTRL_COMPONENT_ENABLED)) - { - return IX_ETH_ACC_SUCCESS; - } - - if ((IX_ETH_PORT_2 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == - IX_FEATURE_CTRL_COMPONENT_ENABLED)) - { - return IX_ETH_ACC_SUCCESS; - } - - if ((IX_ETH_PORT_3 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) == - IX_FEATURE_CTRL_COMPONENT_ENABLED)) - { - return IX_ETH_ACC_SUCCESS; - } - - return IX_ETH_ACC_FAIL; - } - - return IX_ETH_ACC_SUCCESS; -} - -/** - * @fn ixEthAccStatsShow(void) - * - * @brief Displays all EthAcc stats - * - * @return void - * - */ -void ixEthAccStatsShow(IxEthAccPortId portId) -{ - ixEthAccMdioShow(); - - printf("\nPort %u\nUnicast MAC : ", portId); - ixEthAccPortUnicastAddressShow(portId); - ixEthAccPortMulticastAddressShow(portId); - printf("\n"); - - ixEthAccDataPlaneShow(); -} - - - diff --git a/arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c b/arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c deleted file mode 100644 index 4432847..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthAccControlInterface.c +++ /dev/null @@ -1,533 +0,0 @@ -/** - * @file IxEthAccControlInterface.c - * - * @author Intel Corporation - * @date - * - * @brief IX_ETH_ACC_PUBLIC wrappers for control plane functions - * - * Design Notes: - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxOsal.h" -#include "IxEthAcc.h" -#include "IxEthAcc_p.h" - -PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex; - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortEnable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - printf("EthAcc: (Mac) cannot enable port %d, service not initialized\n", portId); - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortEnablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortDisable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - /* check the context is iinitialized */ - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortDisablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortEnabledQueryPriv(portId, enabled); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortPromiscuousModeClearPriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortPromiscuousModeSetPriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortUnicastMacAddressSetPriv(portId, macAddr); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortUnicastMacAddressGetPriv(portId, macAddr); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId, IxEthAccMacAddr *macAddr) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortMulticastAddressJoinPriv(portId, macAddr); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortMulticastAddressJoinAllPriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId, IxEthAccMacAddr *macAddr) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortMulticastAddressLeavePriv(portId, macAddr); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortMulticastAddressLeaveAllPriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortUnicastAddressShow(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortUnicastAddressShowPriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC void -ixEthAccPortMulticastAddressShow(IxEthAccPortId portId) -{ - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return; - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - ixEthAccPortMulticastAddressShowPriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortDuplexModeSet(IxEthAccPortId portId, IxEthAccDuplexMode mode) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortDuplexModeSetPriv(portId, mode); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortDuplexModeGet(IxEthAccPortId portId, IxEthAccDuplexMode *mode) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortDuplexModeGetPriv(portId, mode); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortTxFrameAppendPaddingEnablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortTxFrameAppendPaddingDisablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortTxFrameAppendFCSEnablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortTxFrameAppendFCSDisablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortRxFrameAppendFCSEnablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortRxFrameAppendFCSDisablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccTxSchedulingDisciplineSetPriv(portId, sched); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccRxSchedulingDisciplineSetPriv(sched); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccNpeLoopbackEnablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortTxEnable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortTxEnablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortRxEnable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortRxEnablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccNpeLoopbackDisablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortTxDisable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortTxDisablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortRxDisable(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortRxDisablePriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} - -IX_ETH_ACC_PUBLIC IxEthAccStatus -ixEthAccPortMacReset(IxEthAccPortId portId) -{ - IxEthAccStatus result; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); - result = ixEthAccPortMacResetPriv(portId); - ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); - return result; -} diff --git a/arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c b/arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c deleted file mode 100644 index b62f0d0..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthAccDataPlane.c +++ /dev/null @@ -1,2483 +0,0 @@ -/** - * @file IxEthDataPlane.c - * - * @author Intel Corporation - * @date 12-Feb-2002 - * - * @brief This file contains the implementation of the IXPxxx - * Ethernet Access Data plane component - * - * Design Notes: - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxNpeMh.h" -#include "IxEthAcc.h" -#include "IxEthDB.h" -#include "IxOsal.h" -#include "IxEthDBPortDefs.h" -#include "IxFeatureCtrl.h" -#include "IxEthAcc_p.h" -#include "IxEthAccQueueAssign_p.h" - -extern PUBLIC IxEthAccMacState ixEthAccMacState[]; -extern PUBLIC UINT32 ixEthAccNewSrcMask; - -/** - * private functions prototype - */ -PRIVATE IX_OSAL_MBUF * -ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask); - -PRIVATE UINT32 -ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf); - -PRIVATE UINT32 -ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf); - -PRIVATE IxEthAccStatus -ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId, - IxEthAccTxPriority *priorityPtr); - -PRIVATE IxEthAccStatus -ixEthAccTxFromSwQ(IxEthAccPortId portId, - IxEthAccTxPriority priority); - -PRIVATE IxEthAccStatus -ixEthAccRxFreeFromSwQ(IxEthAccPortId portId); - -PRIVATE void -ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf); - -PRIVATE void -ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf); - -PRIVATE IX_STATUS -ixEthAccQmgrLockTxWrite(IxEthAccPortId portId, - UINT32 qBuffer); - -PRIVATE IX_STATUS -ixEthAccQmgrLockRxWrite(IxEthAccPortId portId, - UINT32 qBuffer); - -PRIVATE IX_STATUS -ixEthAccQmgrTxWrite(IxEthAccPortId portId, - UINT32 qBuffer, - UINT32 priority); - -/** - * @addtogroup IxEthAccPri - *@{ - */ - -/* increment a counter only when stats are enabled */ -#define TX_STATS_INC(port,field) \ - IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccTxData.stats.field) -#define RX_STATS_INC(port,field) \ - IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccRxData.stats.field) - -/* always increment the counter (mainly used for unexpected errors) */ -#define TX_INC(port,field) \ - ixEthAccPortData[port].ixEthAccTxData.stats.field++ -#define RX_INC(port,field) \ - ixEthAccPortData[port].ixEthAccRxData.stats.field++ - -PRIVATE IxEthAccDataPlaneStats ixEthAccDataStats; - -extern IxEthAccPortDataInfo ixEthAccPortData[]; -extern IxEthAccInfo ixEthAccDataInfo; - -PRIVATE IxOsalFastMutex txWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS]; -PRIVATE IxOsalFastMutex rxWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS]; - -/** - * - * @brief Mbuf header conversion macros : they implement the - * different conversions using a temporary value. They also double-check - * that the parameters can be converted to/from NPE format. - * - */ -#if defined(__wince) && !defined(IN_KERNEL) -#define PTR_VIRT2NPE(ptrSrc,dst) \ - do { UINT32 temp; \ - IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \ - temp = (UINT32)IX_OSAL_MBUF_MBUF_VIRTUAL_TO_PHYSICAL_TRANSLATION((IX_OSAL_MBUF*)ptrSrc); \ - (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ - while(0) - -#define PTR_NPE2VIRT(type,src,ptrDst) \ - do { void *temp; \ - IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \ - temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \ - (ptrDst) = (type)IX_OSAL_MBUF_MBUF_PHYSICAL_TO_VIRTUAL_TRANSLATION(temp); } \ - while(0) -#else -#define PTR_VIRT2NPE(ptrSrc,dst) \ - do { UINT32 temp; \ - IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \ - temp = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(ptrSrc); \ - (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ - while(0) - -#define PTR_NPE2VIRT(type,src,ptrDst) \ - do { void *temp; \ - IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \ - IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \ - temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \ - (ptrDst) = (type)IX_OSAL_MMU_PHYS_TO_VIRT(temp); } \ - while(0) -#endif - -/** - * - * @brief Mbuf payload pointer conversion macros : Wince has its own - * method to convert the buffer pointers - */ -#if defined(__wince) && !defined(IN_KERNEL) -#define DATAPTR_VIRT2NPE(ptrSrc,dst) \ - do { UINT32 temp; \ - temp = (UINT32)IX_OSAL_MBUF_DATA_VIRTUAL_TO_PHYSICAL_TRANSLATION(ptrSrc); \ - (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ - while(0) - -#else -#define DATAPTR_VIRT2NPE(ptrSrc,dst) PTR_VIRT2NPE(IX_OSAL_MBUF_MDATA(ptrSrc),dst) -#endif - - -/* Flush the shared part of the mbuf header */ -#define IX_ETHACC_NE_CACHE_FLUSH(mbufPtr) \ - do { \ - IX_OSAL_CACHE_FLUSH(IX_ETHACC_NE_SHARED(mbufPtr), \ - sizeof(IxEthAccNe)); \ - } \ - while(0) - -/* Invalidate the shared part of the mbuf header */ -#define IX_ETHACC_NE_CACHE_INVALIDATE(mbufPtr) \ - do { \ - IX_OSAL_CACHE_INVALIDATE(IX_ETHACC_NE_SHARED(mbufPtr), \ - sizeof(IxEthAccNe)); \ - } \ - while(0) - -/* Preload one cache line (shared mbuf headers are aligned - * and their size is 1 cache line) - * - * IX_OSAL_CACHED is defined when the mbuf headers are - * allocated from cached memory. - * - * Other processor on emulation environment may not implement - * preload function - */ -#ifdef IX_OSAL_CACHED - #if (CPU!=SIMSPARCSOLARIS) && !defined (__wince) - #define IX_ACC_DATA_CACHE_PRELOAD(ptr) \ - do { /* preload a cache line (Xscale Processor) */ \ - __asm__ (" pld [%0]\n": : "r" (ptr)); \ - } \ - while(0) - #else - /* preload not implemented on different processor */ - #define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \ - do { /* nothing */ } while (0) - #endif -#else - /* preload not needed if cache is not enabled */ - #define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \ - do { /* nothing */ } while (0) -#endif - -/** - * - * @brief function to retrieve the correct pointer from - * a queue entry posted by the NPE - * - * @param qEntry : entry from qmgr queue - * mask : applicable mask for this queue - * (4 most significant bits are used for additional informations) - * - * @return IX_OSAL_MBUF * pointer to mbuf header - * - * @internal - */ -PRIVATE IX_OSAL_MBUF * -ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask) -{ - IX_OSAL_MBUF *mbufPtr; - - if (qEntry != 0) - { - /* mask NPE bits (e.g. priority, port ...) */ - qEntry &= mask; - -#if IX_ACC_DRAM_PHYS_OFFSET != 0 - /* restore the original address pointer (if PHYS_OFFSET is not 0) */ - qEntry |= (IX_ACC_DRAM_PHYS_OFFSET & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); -#endif - /* get the mbuf pointer address from the npe-shared address */ - qEntry -= offsetof(IX_OSAL_MBUF,ix_ne); - - /* phys2virt mbuf */ - mbufPtr = (IX_OSAL_MBUF *)IX_OSAL_MMU_PHYS_TO_VIRT(qEntry); - - /* preload the cacheline shared with NPE */ - IX_ACC_DATA_CACHE_PRELOAD(IX_ETHACC_NE_SHARED(mbufPtr)); - - /* preload the cacheline used by xscale */ - IX_ACC_DATA_CACHE_PRELOAD(mbufPtr); - } - else - { - mbufPtr = NULL; - } - - return mbufPtr; -} - -/* Convert the mbuf header for NPE transmission */ -PRIVATE UINT32 -ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf) -{ - UINT32 qbuf; - UINT32 len; - - /* endianess swap for tci and flags - note: this is done only once, even for chained buffers */ - IX_ETHACC_NE_FLAGS(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf)); - IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf)); - - /* test for unchained mbufs */ - if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL) - { - /* "best case" scenario : unchained mbufs */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxMBufs); - - /* payload pointer conversion */ - DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf)); - - /* unchained mbufs : the frame length is the mbuf length - * and the 2 identical lengths are stored in the same - * word. - */ - len = IX_OSAL_MBUF_MLEN(mbuf); - - /* set the length in both length and pktLen 16-bits fields */ - len |= (len << IX_ETHNPE_ACC_LENGTH_OFFSET); - IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len); - - /* unchained mbufs : next contains 0 */ - IX_ETHACC_NE_NEXT(mbuf) = 0; - - /* flush shared header after all address conversions */ - IX_ETHACC_NE_CACHE_FLUSH(mbuf); - } - else - { - /* chained mbufs */ - IX_OSAL_MBUF *ptr = mbuf; - IX_OSAL_MBUF *nextPtr; - UINT32 frmLen; - - /* get the frame length from the header of the first buffer */ - frmLen = IX_OSAL_MBUF_PKT_LEN(mbuf); - - do - { - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxMBufs); - - /* payload pointer */ - DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr)); - /* Buffer length and frame length are stored in the same word */ - len = IX_OSAL_MBUF_MLEN(ptr); - len = frmLen | (len << IX_ETHNPE_ACC_LENGTH_OFFSET); - IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len); - - /* get the virtual next chain pointer */ - nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); - if (nextPtr != NULL) - { - /* shared pointer of the next buffer is chained */ - PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr), - IX_ETHACC_NE_NEXT(ptr)); - } - else - { - IX_ETHACC_NE_NEXT(ptr) = 0; - } - - /* flush shared header after all address conversions */ - IX_ETHACC_NE_CACHE_FLUSH(ptr); - - /* move to next buffer */ - ptr = nextPtr; - - /* the frame length field is set only in the first buffer - * and is zeroed in the next buffers - */ - frmLen = 0; - } - while(ptr != NULL); - - } - - /* virt2phys mbuf itself */ - qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS( - IX_ETHACC_NE_SHARED(mbuf)); - - /* Ensure the bits which are reserved to exchange information with - * the NPE are cleared - * - * If the mbuf address is not correctly aligned, or from an - * incompatible memory range, there is no point to continue - */ - IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_TXENET_ADDR_MASK) == 0), - "Invalid address range"); - - return qbuf; -} - -/* Convert the mbuf header for NPE reception */ -PRIVATE UINT32 -ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf) -{ - UINT32 len; - UINT32 qbuf; - - if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL) - { - /* "best case" scenario : unchained mbufs */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxFreeMBufs); - - /* unchained mbufs : payload pointer */ - DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf)); - - /* unchained mbufs : set the buffer length - * and the frame length field is zeroed - */ - len = (IX_OSAL_MBUF_MLEN(mbuf) << IX_ETHNPE_ACC_LENGTH_OFFSET); - IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len); - - /* unchained mbufs : next pointer is null */ - IX_ETHACC_NE_NEXT(mbuf) = 0; - - /* flush shared header after all address conversions */ - IX_ETHACC_NE_CACHE_FLUSH(mbuf); - - /* remove shared header cache line */ - IX_ETHACC_NE_CACHE_INVALIDATE(mbuf); - } - else - { - /* chained mbufs */ - IX_OSAL_MBUF *ptr = mbuf; - IX_OSAL_MBUF *nextPtr; - - do - { - /* chained mbufs */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxFreeMBufs); - - /* we must save virtual next chain pointer */ - nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); - - if (nextPtr != NULL) - { - /* chaining pointer for NPE */ - PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr), - IX_ETHACC_NE_NEXT(ptr)); - } - else - { - IX_ETHACC_NE_NEXT(ptr) = 0; - } - - /* payload pointer */ - DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr)); - - /* buffer length */ - len = (IX_OSAL_MBUF_MLEN(ptr) << IX_ETHNPE_ACC_LENGTH_OFFSET); - IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len); - - /* flush shared header after all address conversions */ - IX_ETHACC_NE_CACHE_FLUSH(ptr); - - /* remove shared header cache line */ - IX_ETHACC_NE_CACHE_INVALIDATE(ptr); - - /* next mbuf in the chain */ - ptr = nextPtr; - } - while(ptr != NULL); - } - - /* virt2phys mbuf itself */ - qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS( - IX_ETHACC_NE_SHARED(mbuf)); - - /* Ensure the bits which are reserved to exchange information with - * the NPE are cleared - * - * If the mbuf address is not correctly aligned, or from an - * incompatible memory range, there is no point to continue - */ - IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK) == 0), - "Invalid address range"); - - return qbuf; -} - -/* Convert the mbuf header after NPE transmission - * Since there is nothing changed by the NPE, there is no need - * to process anything but the update of internal stats - * when they are enabled -*/ -PRIVATE void -ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf) -{ -#ifndef NDEBUG - /* test for unchained mbufs */ - if (IX_ETHACC_NE_NEXT(mbuf) == 0) - { - /* unchained mbufs : update the stats */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxDoneMBufs); - } - else - { - /* chained mbufs : walk the chain and update the stats */ - IX_OSAL_MBUF *ptr = mbuf; - - do - { - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxDoneMBufs); - ptr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); - } - while (ptr != NULL); - } -#endif -} - -/* Convert the mbuf header after NPE reception */ -PRIVATE void -ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf) -{ - UINT32 len; - - /* endianess swap for tci and flags - note: this is done only once, even for chained buffers */ - IX_ETHACC_NE_FLAGS(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf)); - IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf)); - - /* test for unchained mbufs */ - if (IX_ETHACC_NE_NEXT(mbuf) == 0) - { - /* unchained mbufs */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxMBufs); - - /* get the frame length. it is the same than the buffer length */ - len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf)); - len &= IX_ETHNPE_ACC_PKTLENGTH_MASK; - IX_OSAL_MBUF_PKT_LEN(mbuf) = IX_OSAL_MBUF_MLEN(mbuf) = len; - - /* clears the next packet field */ - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) = NULL; - } - else - { - IX_OSAL_MBUF *ptr = mbuf; - IX_OSAL_MBUF *nextPtr; - UINT32 frmLen; - - /* convert the frame length */ - frmLen = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf)); - IX_OSAL_MBUF_PKT_LEN(mbuf) = (frmLen & IX_ETHNPE_ACC_PKTLENGTH_MASK); - - /* chained mbufs */ - do - { - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxMBufs); - - /* convert the length */ - len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(ptr)); - IX_OSAL_MBUF_MLEN(ptr) = (len >> IX_ETHNPE_ACC_LENGTH_OFFSET); - - /* get the next pointer */ - PTR_NPE2VIRT(IX_OSAL_MBUF *,IX_ETHACC_NE_NEXT(ptr), nextPtr); - if (nextPtr != NULL) - { - nextPtr = (IX_OSAL_MBUF *)((UINT8 *)nextPtr - offsetof(IX_OSAL_MBUF,ix_ne)); - } - /* set the next pointer */ - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr) = nextPtr; - - /* move to the next buffer */ - ptr = nextPtr; - } - while (ptr != NULL); - } -} - -/* write to qmgr if possible and report an overflow if not possible - * Use a fast lock to protect the queue write. - * This way, the tx feature is reentrant. - */ -PRIVATE IX_STATUS -ixEthAccQmgrLockTxWrite(IxEthAccPortId portId, UINT32 qBuffer) -{ - IX_STATUS qStatus; - if (ixOsalFastMutexTryLock(&txWriteMutex[portId]) == IX_SUCCESS) - { - qStatus = ixQMgrQWrite( - IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), - &qBuffer); -#ifndef NDEBUG - if (qStatus != IX_SUCCESS) - { - TX_STATS_INC(portId, txOverflow); - } -#endif - ixOsalFastMutexUnlock(&txWriteMutex[portId]); - } - else - { - TX_STATS_INC(portId, txLock); - qStatus = IX_QMGR_Q_OVERFLOW; - } - return qStatus; -} - -/* write to qmgr if possible and report an overflow if not possible - * Use a fast lock to protect the queue write. - * This way, the Rx feature is reentrant. - */ -PRIVATE IX_STATUS -ixEthAccQmgrLockRxWrite(IxEthAccPortId portId, UINT32 qBuffer) -{ - IX_STATUS qStatus; - if (ixOsalFastMutexTryLock(&rxWriteMutex[portId]) == IX_SUCCESS) - { - qStatus = ixQMgrQWrite( - IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId), - &qBuffer); -#ifndef NDEBUG - if (qStatus != IX_SUCCESS) - { - RX_STATS_INC(portId, rxFreeOverflow); - } -#endif - ixOsalFastMutexUnlock(&rxWriteMutex[portId]); - } - else - { - RX_STATS_INC(portId, rxFreeLock); - qStatus = IX_QMGR_Q_OVERFLOW; - } - return qStatus; -} - -/* - * Set the priority and write to a qmgr queue. - */ -PRIVATE IX_STATUS -ixEthAccQmgrTxWrite(IxEthAccPortId portId, UINT32 qBuffer, UINT32 priority) -{ - /* fill the priority field */ - qBuffer |= (priority << IX_ETHNPE_QM_Q_FIELD_PRIOR_R); - - return ixEthAccQmgrLockTxWrite(portId, qBuffer); -} - -/** - * - * @brief This function will discover the highest priority S/W Tx Q that - * has entries in it - * - * @param portId - (in) the id of the port whose S/W Tx queues are to be searched - * priorityPtr - (out) the priority of the highest priority occupied q will be written - * here - * - * @return IX_ETH_ACC_SUCCESS if an occupied Q is found - * IX_ETH_ACC_FAIL if no Q has entries - * - * @internal - */ -PRIVATE IxEthAccStatus -ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId, - IxEthAccTxPriority *priorityPtr) -{ - if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline - == FIFO_NO_PRIORITY) - { - if(IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. - ixEthAccTxData.txQ[IX_ETH_ACC_TX_DEFAULT_PRIORITY])) - { - return IX_ETH_ACC_FAIL; - } - else - { - *priorityPtr = IX_ETH_ACC_TX_DEFAULT_PRIORITY; - TX_STATS_INC(portId,txPriority[*priorityPtr]); - return IX_ETH_ACC_SUCCESS; - } - } - else - { - IxEthAccTxPriority highestPriority = IX_ETH_ACC_TX_PRIORITY_7; - while(1) - { - if(!IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. - ixEthAccTxData.txQ[highestPriority])) - { - - *priorityPtr = highestPriority; - TX_STATS_INC(portId,txPriority[highestPriority]); - return IX_ETH_ACC_SUCCESS; - - } - if (highestPriority == IX_ETH_ACC_TX_PRIORITY_0) - { - return IX_ETH_ACC_FAIL; - } - highestPriority--; - } - } -} - -/** - * - * @brief This function will take a buffer from a TX S/W Q and attempt - * to add it to the relevant TX H/W Q - * - * @param portId - the port whose TX queue is to be written to - * priority - identifies the queue from which the entry is to be read - * - * @internal - */ -PRIVATE IxEthAccStatus -ixEthAccTxFromSwQ(IxEthAccPortId portId, - IxEthAccTxPriority priority) -{ - IX_OSAL_MBUF *mbuf; - IX_STATUS qStatus; - - IX_OSAL_ENSURE((UINT32)priority <= (UINT32)7, "Invalid priority"); - - IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD( - ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], - mbuf); - - if (mbuf != NULL) - { - /* - * Add the Tx buffer to the H/W Tx Q - * We do not need to flush here as it is already done - * in TxFrameSubmit(). - */ - qStatus = ixEthAccQmgrTxWrite( - portId, - IX_OSAL_MMU_VIRT_TO_PHYS((UINT32)IX_ETHACC_NE_SHARED(mbuf)), - priority); - - if (qStatus == IX_SUCCESS) - { - TX_STATS_INC(portId,txFromSwQOK); - return IX_SUCCESS; - } - else if (qStatus == IX_QMGR_Q_OVERFLOW) - { - /* - * H/W Q overflow, need to save the buffer - * back on the s/w Q. - * we must put it back on the head of the q to avoid - * reordering packet tx - */ - TX_STATS_INC(portId,txFromSwQDelayed); - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( - ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], - mbuf); - - /*enable Q notification*/ - qStatus = ixQMgrNotificationEnable( - IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), - IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId)); - - if (qStatus != IX_SUCCESS && qStatus != IX_QMGR_WARNING) - { - TX_INC(portId,txUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccTxFromSwQ:Unexpected Error: %u\n", - qStatus, 0, 0, 0, 0, 0); - } - } - else - { - TX_INC(portId,txUnexpectedError); - - /* recovery attempt */ - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( - ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], - mbuf); - - IX_ETH_ACC_FATAL_LOG( - "ixEthAccTxFromSwQ:Error: unexpected QM status 0x%08X\n", - qStatus, 0, 0, 0, 0, 0); - } - } - else - { - /* sw queue is empty */ - } - return IX_ETH_ACC_FAIL; -} - -/** - * - * @brief This function will take a buffer from a RXfree S/W Q and attempt - * to add it to the relevant RxFree H/W Q - * - * @param portId - the port whose RXFree queue is to be written to - * - * @internal - */ -PRIVATE IxEthAccStatus -ixEthAccRxFreeFromSwQ(IxEthAccPortId portId) -{ - IX_OSAL_MBUF *mbuf; - IX_STATUS qStatus = IX_SUCCESS; - - IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD( - ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, - mbuf); - if (mbuf != NULL) - { - /* - * Add The Rx Buffer to the H/W Free buffer Q if possible - */ - qStatus = ixEthAccQmgrLockRxWrite(portId, - IX_OSAL_MMU_VIRT_TO_PHYS( - (UINT32)IX_ETHACC_NE_SHARED(mbuf))); - - if (qStatus == IX_SUCCESS) - { - RX_STATS_INC(portId,rxFreeRepFromSwQOK); - /* - * Buffer added to h/w Q. - */ - return IX_SUCCESS; - } - else if (qStatus == IX_QMGR_Q_OVERFLOW) - { - /* - * H/W Q overflow, need to save the buffer back on the s/w Q. - */ - RX_STATS_INC(portId,rxFreeRepFromSwQDelayed); - - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( - ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, - mbuf); - } - else - { - /* unexpected qmgr error */ - RX_INC(portId,rxUnexpectedError); - - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( - ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, - mbuf); - - IX_ETH_ACC_FATAL_LOG("IxEthAccRxFreeFromSwQ:Error: unexpected QM status 0x%08X\n", - qStatus, 0, 0, 0, 0, 0); - } - } - else - { - /* sw queue is empty */ - } - return IX_ETH_ACC_FAIL; -} - - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccInitDataPlane() -{ - UINT32 portId; - - /* - * Initialize the service and register callback to other services. - */ - - IX_ETH_ACC_MEMSET(&ixEthAccDataStats, - 0, - sizeof(ixEthAccDataStats)); - - for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - ixOsalFastMutexInit(&txWriteMutex[portId]); - ixOsalFastMutexInit(&rxWriteMutex[portId]); - - IX_ETH_ACC_MEMSET(&ixEthAccPortData[portId], - 0, - sizeof(ixEthAccPortData[portId])); - - ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = FIFO_NO_PRIORITY; - } - - return (IX_ETH_ACC_SUCCESS); -} - - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId, - IxEthAccPortTxDoneCallback - txCallbackFn, - UINT32 callbackTag) -{ - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - return (IX_ETH_ACC_INVALID_PORT); - } - -/* HACK: removing this code to enable NPE-A preliminary testing - * if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - * { - * IX_ETH_ACC_WARNING_LOG("ixEthAccPortTxDoneCallbackRegister: Unavailable Eth %d: Cannot register TxDone Callback.\n",(INT32)portId,0,0,0,0,0); - * return IX_ETH_ACC_SUCCESS ; - * } - */ - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - if (txCallbackFn == 0) - /* Check for null function pointer here. */ - { - return (IX_ETH_ACC_INVALID_ARG); - } - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = txCallbackFn; - ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = callbackTag; - return (IX_ETH_ACC_SUCCESS); -} - - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccPortRxCallbackRegister(IxEthAccPortId portId, - IxEthAccPortRxCallback - rxCallbackFn, - UINT32 callbackTag) -{ - IxEthAccPortId port; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - return (IX_ETH_ACC_INVALID_PORT); - } - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccPortRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* Check for null function pointer here. */ - if (rxCallbackFn == NULL) - { - return (IX_ETH_ACC_INVALID_ARG); - } - - /* Check the user is not changing the callback type - * when the port is enabled. - */ - if (ixEthAccMacState[portId].portDisableState == ACTIVE) - { - for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++) - { - if ((ixEthAccMacState[port].portDisableState == ACTIVE) - && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == TRUE)) - { - /* one of the active ports has a different rx callback type. - * Changing the callback type when the port is enabled - * is not safe - */ - return (IX_ETH_ACC_INVALID_ARG); - } - } - } - - /* update the callback pointer : this is done before - * registering the new qmgr callback - */ - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = rxCallbackFn; - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = callbackTag; - - /* update the qmgr callback for rx queues */ - if (ixEthAccQMgrRxCallbacksRegister(ixEthRxFrameQMCallback) - != IX_ETH_ACC_SUCCESS) - { - /* unexpected qmgr error */ - IX_ETH_ACC_FATAL_LOG("ixEthAccPortRxCallbackRegister: unexpected QMgr error, " \ - "could not register Rx single-buffer callback\n", 0, 0, 0, 0, 0, 0); - - RX_INC(portId,rxUnexpectedError); - return (IX_ETH_ACC_INVALID_ARG); - } - - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = FALSE; - - return (IX_ETH_ACC_SUCCESS); -} - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccPortMultiBufferRxCallbackRegister( - IxEthAccPortId portId, - IxEthAccPortMultiBufferRxCallback - rxCallbackFn, - UINT32 callbackTag) -{ - IxEthAccPortId port; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - return (IX_ETH_ACC_INVALID_PORT); - } - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccPortMultiBufferRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* Check for null function pointer here. */ - if (rxCallbackFn == NULL) - { - return (IX_ETH_ACC_INVALID_ARG); - } - - /* Check the user is not changing the callback type - * when the port is enabled. - */ - if (ixEthAccMacState[portId].portDisableState == ACTIVE) - { - for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++) - { - if ((ixEthAccMacState[port].portDisableState == ACTIVE) - && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == FALSE)) - { - /* one of the active ports has a different rx callback type. - * Changing the callback type when the port is enabled - * is not safe - */ - return (IX_ETH_ACC_INVALID_ARG); - } - } - } - - /* update the callback pointer : this is done before - * registering the new qmgr callback - */ - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = rxCallbackFn; - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = callbackTag; - - /* update the qmgr callback for rx queues */ - if (ixEthAccQMgrRxCallbacksRegister(ixEthRxMultiBufferQMCallback) - != IX_ETH_ACC_SUCCESS) - { - /* unexpected qmgr error */ - RX_INC(portId,rxUnexpectedError); - - IX_ETH_ACC_FATAL_LOG("ixEthAccPortMultiBufferRxCallbackRegister: unexpected QMgr error, " \ - "could not register Rx multi-buffer callback\n", 0, 0, 0, 0, 0, 0); - - return (IX_ETH_ACC_INVALID_ARG); - } - - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = TRUE; - - return (IX_ETH_ACC_SUCCESS); -} - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccPortTxFrameSubmit(IxEthAccPortId portId, - IX_OSAL_MBUF *buffer, - IxEthAccTxPriority priority) -{ - IX_STATUS qStatus = IX_SUCCESS; - UINT32 qBuffer; - IxEthAccTxPriority highestPriority; - IxQMgrQStatus txQStatus; - -#ifndef NDEBUG - if (buffer == NULL) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - return (IX_ETH_ACC_INVALID_PORT); - } - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_FATAL_LOG("ixEthAccPortTxFrameSubmit: Unavailable Eth %d: Cannot submit Tx Frame.\n", - (INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_PORT_UNINITIALIZED ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - if ((UINT32)priority > (UINT32)IX_ETH_ACC_TX_PRIORITY_7) - { - return (IX_ETH_ACC_INVALID_ARG); - } -#endif - - /* - * Need to Flush the MBUF and its contents (data) as it may be - * read from the NPE. Convert virtual addresses to physical addresses also. - */ - qBuffer = ixEthAccMbufTxQPrepare(buffer); - - /* - * If no fifo priority set on Xscale ... - */ - if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == - FIFO_NO_PRIORITY) - { - /* - * Add The Tx Buffer to the H/W Tx Q if possible - * (the priority is passed to the NPE, because - * the NPE is able to reorder the frames - * before transmission to the underlying hardware) - */ - qStatus = ixEthAccQmgrTxWrite(portId, - qBuffer, - IX_ETH_ACC_TX_DEFAULT_PRIORITY); - - if (qStatus == IX_SUCCESS) - { - TX_STATS_INC(portId,txQOK); - - /* - * "best case" scenario : Buffer added to h/w Q. - */ - return (IX_SUCCESS); - } - else if (qStatus == IX_QMGR_Q_OVERFLOW) - { - /* - * We were unable to write the buffer to the - * appropriate H/W Q, Save it in the sw Q. - * (use the default priority queue regardless of - * input parameter) - */ - priority = IX_ETH_ACC_TX_DEFAULT_PRIORITY; - } - else - { - /* unexpected qmgr error */ - TX_INC(portId,txUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccPortTxFrameSubmit:Error: qStatus = %u\n", - (UINT32)qStatus, 0, 0, 0, 0, 0); - return (IX_ETH_ACC_FAIL); - } - } - else if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == - FIFO_PRIORITY) - { - - /* - * For priority transmission, put the frame directly on the H/W queue - * if the H/W queue is empty, otherwise, put it in a S/W Q - */ - ixQMgrQStatusGet(IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), &txQStatus); - if((txQStatus & IX_QMGR_Q_STATUS_E_BIT_MASK) != 0) - { - /*The tx queue is empty, check whether there are buffers on the s/w queues*/ - if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) - !=IX_ETH_ACC_FAIL) - { - /*there are buffers on the s/w queues, submit them*/ - ixEthAccTxFromSwQ(portId, highestPriority); - - /* the queue was empty, 1 buffer is already supplied - * but is likely to be immediately transmitted and the - * hw queue is likely to be empty again, so submit - * more from the sw queues - */ - if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) - !=IX_ETH_ACC_FAIL) - { - ixEthAccTxFromSwQ(portId, highestPriority); - /* - * and force the buffer supplied to be placed - * on a priority queue - */ - qStatus = IX_QMGR_Q_OVERFLOW; - } - else - { - /*there are no buffers in the s/w queues, submit directly*/ - qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority); - } - } - else - { - /*there are no buffers in the s/w queues, submit directly*/ - qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority); - } - } - else - { - qStatus = IX_QMGR_Q_OVERFLOW; - } - } - else - { - TX_INC(portId,txUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccPortTxFrameSubmit:Error: wrong schedule discipline setup\n", - 0, 0, 0, 0, 0, 0); - return (IX_ETH_ACC_FAIL); - } - - if(qStatus == IX_SUCCESS ) - { - TX_STATS_INC(portId,txQOK); - return IX_ETH_ACC_SUCCESS; - } - else if(qStatus == IX_QMGR_Q_OVERFLOW) - { - TX_STATS_INC(portId,txQDelayed); - /* - * We were unable to write the buffer to the - * appropriate H/W Q, Save it in a s/w Q. - */ - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL( - ixEthAccPortData[portId]. - ixEthAccTxData.txQ[priority], - buffer); - - qStatus = ixQMgrNotificationEnable( - IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), - IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId)); - - if (qStatus != IX_SUCCESS) - { - if (qStatus == IX_QMGR_WARNING) - { - /* notification is enabled for a queue - * which is already empty (the condition is already met) - * and there will be no more queue event to drain the sw queue - */ - TX_STATS_INC(portId,txLateNotificationEnabled); - - /* pull a buffer from the sw queue */ - if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) - !=IX_ETH_ACC_FAIL) - { - /*there are buffers on the s/w queues, submit from them*/ - ixEthAccTxFromSwQ(portId, highestPriority); - } - } - else - { - TX_INC(portId,txUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n", - qStatus, 0, 0, 0, 0, 0); - } - } - } - else - { - TX_INC(portId,txUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n", - qStatus, 0, 0, 0, 0, 0); - return (IX_ETH_ACC_FAIL); - } - - return (IX_ETH_ACC_SUCCESS); -} - - -/** - * - * @brief replenish: convert a chain of mbufs to the format - * expected by the NPE - * - */ - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccPortRxFreeReplenish(IxEthAccPortId portId, - IX_OSAL_MBUF *buffer) -{ - IX_STATUS qStatus = IX_SUCCESS; - UINT32 qBuffer; - - /* - * Check buffer is valid. - */ - -#ifndef NDEBUG - /* check parameter value */ - if (buffer == 0) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - return (IX_ETH_ACC_INVALID_PORT); - } - - /* check initialisation is done */ - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_FATAL_LOG(" ixEthAccPortRxFreeReplenish: Unavailable Eth %d: Cannot replenish Rx Free Q.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_PORT_UNINITIALIZED ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - /* check boundaries and constraints */ - if (IX_OSAL_MBUF_MLEN(buffer) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN) - { - return (IX_ETH_ACC_FAIL); - } -#endif - - qBuffer = ixEthAccMbufRxQPrepare(buffer); - - /* - * Add The Rx Buffer to the H/W Free buffer Q if possible - */ - qStatus = ixEthAccQmgrLockRxWrite(portId, qBuffer); - - if (qStatus == IX_SUCCESS) - { - RX_STATS_INC(portId,rxFreeRepOK); - /* - * Buffer added to h/w Q. - */ - return (IX_SUCCESS); - } - else if (qStatus == IX_QMGR_Q_OVERFLOW) - { - RX_STATS_INC(portId,rxFreeRepDelayed); - /* - * We were unable to write the buffer to the approprate H/W Q, - * Save it in a s/w Q. - */ - IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL( - ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, - buffer); - - qStatus = ixQMgrNotificationEnable( - IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId), - IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(portId)); - - if (qStatus != IX_SUCCESS) - { - if (qStatus == IX_QMGR_WARNING) - { - /* notification is enabled for a queue - * which is already empty (the condition is already met) - * and there will be no more queue event to drain the sw queue - * move an entry from the sw queue to the hw queue */ - RX_STATS_INC(portId,rxFreeLateNotificationEnabled); - ixEthAccRxFreeFromSwQ(portId); - } - else - { - RX_INC(portId,rxUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccRxPortFreeReplenish:Error: %u\n", - qStatus, 0, 0, 0, 0, 0); - } - } - } - else - { - RX_INC(portId,rxUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthAccRxPortFreeReplenish:Error: qStatus = %u\n", - (UINT32)qStatus, 0, 0, 0, 0, 0); - return(IX_ETH_ACC_FAIL); - } - return (IX_ETH_ACC_SUCCESS); -} - - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId, - IxEthAccSchedulerDiscipline - sched) -{ - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - return (IX_ETH_ACC_INVALID_PORT); - } - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("ixEthAccTxSchedulingDisciplineSet: Unavailable Eth %d: Cannot set Tx Scheduling Discipline.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY) - { - return (IX_ETH_ACC_INVALID_ARG); - } - - ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = sched; - return (IX_ETH_ACC_SUCCESS); -} - -IX_ETH_ACC_PUBLIC -IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline - sched) -{ - if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY) - { - return (IX_ETH_ACC_INVALID_ARG); - } - - ixEthAccDataInfo.schDiscipline = sched; - - return (IX_ETH_ACC_SUCCESS); -} - - -/** - * @fn ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr) - * - * @brief process incoming frame : - * - * @param @ref IxQMgrCallback IxQMgrMultiBufferCallback - * - * @return none - * - * @internal - * - */ -IX_ETH_ACC_PRIVATE BOOL -ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr) -{ - UINT32 flags; - IxEthDBStatus result; - -#ifndef NDEBUG - /* Prudent to at least check the port is within range */ - if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFrameProcess: Illegal port: %u\n", - (UINT32)portId, 0, 0, 0, 0, 0); - return FALSE; - } -#endif - - /* convert fields from mbuf header */ - ixEthAccMbufFromRxQ(mbufPtr); - - /* check about any special processing for this frame */ - flags = IX_ETHACC_NE_FLAGS(mbufPtr); - if ((flags & (IX_ETHACC_NE_FILTERMASK | IX_ETHACC_NE_NEWSRCMASK)) == 0) - { - /* "best case" scenario : nothing special to do for this frame */ - return TRUE; - } - -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - /* if a new source MAC address is detected by the NPE, - * update IxEthDB with the portId and the MAC address. - */ - if ((flags & IX_ETHACC_NE_NEWSRCMASK & ixEthAccNewSrcMask) != 0) - { - result = ixEthDBFilteringDynamicEntryProvision(portId, - (IxEthDBMacAddr *) IX_ETHACC_NE_SOURCEMAC(mbufPtr)); - - if (result != IX_ETH_DB_SUCCESS && result != IX_ETH_DB_FEATURE_UNAVAILABLE) - { - if ((ixEthAccMacState[portId].portDisableState == ACTIVE) && (result != IX_ETH_DB_BUSY)) - { - RX_STATS_INC(portId, rxUnexpectedError); - IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to add source MAC \ - to the Learning/Filtering database\n", 0, 0, 0, 0, 0, 0); - } - else - { - /* we expect this to fail during PortDisable, as EthDB is disabled for - * that port and will refuse to learn new addresses - */ - } - } - else - { - RX_STATS_INC(portId, rxUnlearnedMacAddress); - } - } -#endif - - /* check if this frame should have been filtered - * by the NPE and take the appropriate action - */ - if (((flags & IX_ETHACC_NE_FILTERMASK) != 0) - && (ixEthAccMacState[portId].portDisableState == ACTIVE)) - { - /* If the mbuf was allocated with a small data size, or the current data pointer is not - * within the allocated data area, then the buffer is non-standard and has to be - * replenished with the minimum size only - */ - if( (IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN) - || ((UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) > IX_OSAL_MBUF_MDATA(mbufPtr)) - || ((UINT8 *)(IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) + - IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr)) - < IX_OSAL_MBUF_MDATA(mbufPtr)) ) - { - /* set to minimum length */ - IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) = - IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN; - } - else - { - /* restore original length */ - IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) = - ( IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) - - (IX_OSAL_MBUF_MDATA(mbufPtr) - (UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr)) ); - } - - /* replenish from here */ - if (ixEthAccPortRxFreeReplenish(portId, mbufPtr) != IX_ETH_ACC_SUCCESS) - { - IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to replenish with filtered frame\ - on port %d\n", portId, 0, 0, 0, 0, 0); - } - - RX_STATS_INC(portId, rxFiltered); - - /* indicate that frame should not be subjected to further processing */ - return FALSE; - } - - return TRUE; -} - - -/** - * @fn ixEthRxFrameQMCallback - * - * @brief receive callback for Frame receive Q from NPE - * - * Frames are passed one-at-a-time to the user - * - * @param @ref IxQMgrCallback - * - * @return none - * - * @internal - * - * Design note : while processing the entry X, entry X+1 is preloaded - * into memory to reduce the number of stall cycles - * - */ -void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) -{ - IX_OSAL_MBUF *mbufPtr; - IX_OSAL_MBUF *nextMbufPtr; - UINT32 qEntry; - UINT32 nextQEntry; - UINT32 *qEntryPtr; - UINT32 portId; - UINT32 destPortId; - UINT32 npeId; - UINT32 rxQReadStatus; - - /* - * Design note : entries are read in a buffer, This buffer contains - * an extra zeroed entry so the loop will - * always terminate on a null entry, whatever the result of Burst read is. - */ - UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; - - /* - * Indication of the number of times the callback is used. - */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter); - - do - { - /* - * Indication of the number of times the queue is drained - */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead); - - /* ensure the last entry of the array contains a zeroed value */ - qEntryPtr = rxQEntry; - qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0; - - rxQReadStatus = ixQMgrQBurstRead(qId, - IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK, - qEntryPtr); - -#ifndef NDEBUG - if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW) - && (rxQReadStatus != IX_SUCCESS)) - { - ixEthAccDataStats.unexpectedError++; - /*major error*/ - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFrameQMCallback:Error: %u\n", - (UINT32)rxQReadStatus, 0, 0, 0, 0, 0); - return; - } -#endif - - /* convert and preload the next entry - * (the conversion function takes care about null pointers which - * are used to mark the end of the loop) - */ - nextQEntry = *qEntryPtr; - nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, - IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); - - while(nextQEntry != 0) - { - /* get the next entry */ - qEntry = nextQEntry; - mbufPtr = nextMbufPtr; - -#ifndef NDEBUG - if (mbufPtr == NULL) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFrameQMCallback: Null Mbuf Ptr\n", - 0, 0, 0, 0, 0, 0); - return; - } -#endif - - /* convert the next entry - * (the conversion function takes care about null pointers which - * are used to mark the end of the loop) - */ - nextQEntry = *(++qEntryPtr); - nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, - IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); - - /* - * Get Port and Npe ID from message. - */ - npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK & - qEntry) >> IX_ETHNPE_QM_Q_FIELD_NPEID_R); - portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); - - /* process frame, check the return code and skip the remaining of - * the loop if the frame is to be filtered out - */ - if (ixEthRxFrameProcess(portId, mbufPtr)) - { - /* destination portId for this packet */ - destPortId = IX_ETHACC_NE_DESTPORTID(mbufPtr); - - if (destPortId != IX_ETH_DB_UNKNOWN_PORT) - { - destPortId = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(destPortId); - } - - /* test if QoS is enabled in ethAcc - */ - if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY) - { - /* check if there is a higher priority queue - * which may require processing and then process it. - */ - if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES) - { - ixEthRxFrameQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId], - callbackId); - } - } - - /* - * increment priority stats - */ - RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]); - - /* - * increment callback count stats - */ - RX_STATS_INC(portId,rxFrameClientCallback); - - /* - * Call user level callback. - */ - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn( - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag, - mbufPtr, - destPortId); - } - } - } while (rxQReadStatus == IX_SUCCESS); -} - -/** - * @fn ixEthRxMultiBufferQMCallback - * - * @brief receive callback for Frame receive Q from NPE - * - * Frames are passed as an array to the user - * - * @param @ref IxQMgrCallback - * - * @return none - * - * @internal - * - * Design note : while processing the entry X, entry X+1 is preloaded - * into memory to reduce the number of stall cycles - * - */ -void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) -{ - IX_OSAL_MBUF *mbufPtr; - IX_OSAL_MBUF *nextMbufPtr; - UINT32 qEntry; - UINT32 nextQEntry; - UINT32 *qEntryPtr; - UINT32 portId; - UINT32 npeId; - UINT32 rxQReadStatus; - /* - * Design note : entries are read in a static buffer, This buffer contains - * an extra zeroed entry so the loop will - * always terminate on a null entry, whatever the result of Burst read is. - */ - static UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; - static IX_OSAL_MBUF *rxMbufPortArray[IX_ETH_ACC_NUMBER_OF_PORTS][IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; - IX_OSAL_MBUF **rxMbufPtr[IX_ETH_ACC_NUMBER_OF_PORTS]; - - for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - rxMbufPtr[portId] = rxMbufPortArray[portId]; - } - - /* - * Indication of the number of times the callback is used. - */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter); - - do - { - /* - * Indication of the number of times the queue is drained - */ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead); - - /* ensure the last entry of the array contains a zeroed value */ - qEntryPtr = rxQEntry; - qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0; - - rxQReadStatus = ixQMgrQBurstRead(qId, - IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK, - qEntryPtr); - -#ifndef NDEBUG - if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW) - && (rxQReadStatus != IX_SUCCESS)) - { - ixEthAccDataStats.unexpectedError++; - /*major error*/ - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFrameMultiBufferQMCallback:Error: %u\n", - (UINT32)rxQReadStatus, 0, 0, 0, 0, 0); - return; - } -#endif - - /* convert and preload the next entry - * (the conversion function takes care about null pointers which - * are used to mark the end of the loop) - */ - nextQEntry = *qEntryPtr; - nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, - IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); - - while(nextQEntry != 0) - { - /* get the next entry */ - qEntry = nextQEntry; - mbufPtr = nextMbufPtr; - -#ifndef NDEBUG - if (mbufPtr == NULL) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFrameMultiBufferQMCallback:Error: Null Mbuf Ptr\n", - 0, 0, 0, 0, 0, 0); - return; - } -#endif - - /* convert the next entry - * (the conversion function takes care about null pointers which - * are used to mark the end of the loop) - */ - nextQEntry = *(++qEntryPtr); - nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, - IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); - - /* - * Get Port and Npe ID from message. - */ - npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK & - qEntry) >> - IX_ETHNPE_QM_Q_FIELD_NPEID_R); - portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); - - /* skip the remaining of the loop if the frame is - * to be filtered out - */ - if (ixEthRxFrameProcess(portId, mbufPtr)) - { - /* store a mbuf pointer in an array */ - *rxMbufPtr[portId]++ = mbufPtr; - - /* - * increment priority stats - */ - RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]); - } - - /* test for QoS enabled in ethAcc */ - if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY) - { - /* check if there is a higher priority queue - * which may require processing and then process it. - */ - if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES) - { - ixEthRxMultiBufferQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId], - callbackId); - } - } - } - - /* check if any of the the arrays contains any entry */ - for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - if (rxMbufPtr[portId] != rxMbufPortArray[portId]) - { - /* add a last NULL pointer at the end of the - * array of mbuf pointers - */ - *rxMbufPtr[portId] = NULL; - - /* - * increment callback count stats - */ - RX_STATS_INC(portId,rxFrameClientCallback); - - /* - * Call user level callback with an array of - * buffers (NULL terminated) - */ - ixEthAccPortData[portId].ixEthAccRxData. - rxMultiBufferCallbackFn( - ixEthAccPortData[portId].ixEthAccRxData. - rxMultiBufferCallbackTag, - rxMbufPortArray[portId]); - - /* reset the buffer pointer to the beginning of - * the array - */ - rxMbufPtr[portId] = rxMbufPortArray[portId]; - } - } - - } while (rxQReadStatus == IX_SUCCESS); -} - - -/** - * @brief rxFree low event handler - * - */ -void ixEthRxFreeQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) -{ - IxEthAccPortId portId = (IxEthAccPortId) callbackId; - int lockVal; - UINT32 maxQWritesToPerform = IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD; - IX_STATUS qStatus = IX_SUCCESS; - - /* - * We have reached a low threshold on one of the Rx Free Qs - */ - - /*note that due to the fact that we are working off an Empty threshold, this callback - need only write a single entry to the Rx Free queue in order to re-arm the notification - */ - - RX_STATS_INC(portId,rxFreeLowCallback); - - /* - * Get buffers from approprite S/W Rx freeBufferList Q. - */ - -#ifndef NDEBUG - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFreeQMCallback:Error: Invalid Port 0x%08X\n", - portId, 0, 0, 0, 0, 0); - return; - } -#endif - IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); - if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. - ixEthAccRxData.freeBufferList)) - { - /* - * Turn off Q callback notification for Q in Question. - */ - qStatus = ixQMgrNotificationDisable( - IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId)); - - - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); - - if (qStatus != IX_SUCCESS) - { - RX_INC(portId,rxUnexpectedError); - IX_ETH_ACC_FATAL_LOG( - "ixEthRxFreeQMCallback:Error: unexpected QM status 0x%08X\n", - qStatus, 0, 0, 0, 0, 0); - return; - } - } - else - { - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); - /* - * Load the H/W Q with buffers from the s/w Q. - */ - - do - { - /* - * Consume Q entries. - Note Q contains Physical addresss, - * and have already been flushed to memory, - * And endianess converted if required. - */ - if (ixEthAccRxFreeFromSwQ(portId) != IX_SUCCESS) - { - /* - * No more entries in s/w Q. - * Turn off Q callback indication - */ - - IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); - if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. - ixEthAccRxData.freeBufferList)) - { - qStatus = ixQMgrNotificationDisable( - IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId)); - } - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); - break; - } - } - while (--maxQWritesToPerform); - } -} -/** - * @fn Tx queue low event handler - * - */ -void -ixEthTxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) -{ - IxEthAccPortId portId = (IxEthAccPortId) callbackId; - int lockVal; - UINT32 maxQWritesToPerform = IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK; - IX_STATUS qStatus = IX_SUCCESS; - IxEthAccTxPriority highestPriority; - - - /* - * We have reached a low threshold on the Tx Q, and are being asked to - * supply a buffer for transmission from our S/W TX queues - */ - TX_STATS_INC(portId,txLowThreshCallback); - - /* - * Get buffers from approprite Q. - */ - -#ifndef NDEBUG - if (!IX_ETH_ACC_IS_PORT_VALID(portId)) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthTxFrameQMCallback:Error: Invalid Port 0x%08X\n", - portId, 0, 0, 0, 0, 0); - return; - } -#endif - - do - { - /* - * Consume Q entries. - Note Q contains Physical addresss, - * and have already been flushed to memory, - * and endianess already sone if required. - */ - - IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); - - if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) == - IX_ETH_ACC_FAIL) - { - /* - * No more entries in s/w Q. - * Turn off Q callback indication - */ - qStatus = ixQMgrNotificationDisable( - IX_ETH_ACC_PORT_TO_TX_Q_ID(portId)); - - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); - - if (qStatus != IX_SUCCESS) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthTxFrameQMCallback:Error: unexpected QM status 0x%08X\n", - qStatus, 0, 0, 0, 0, 0); - } - - return; - } - else - { - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); - if (ixEthAccTxFromSwQ(portId,highestPriority)!=IX_SUCCESS) - { - /* nothing left in the sw queue or the hw queues are - * full. There is no point to continue to drain the - * sw queues - */ - return; - } - } - } - while (--maxQWritesToPerform); -} - -/** - * @brief TxDone event handler - * - * Design note : while processing the entry X, entry X+1 is preloaded - * into memory to reduce the number of stall cycles - * - */ - -void -ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) -{ - IX_OSAL_MBUF *mbufPtr; - UINT32 qEntry; - UINT32 *qEntryPtr; - UINT32 txDoneQReadStatus; - UINT32 portId; - UINT32 npeId; - - /* - * Design note : entries are read in a static buffer, This buffer contains - * an extra entyry (which is zeroed by the compiler), so the loop will - * always terminate on a null entry, whatever the result of Burst read is. - */ - static UINT32 txDoneQEntry[IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK + 1]; - - /* - * Indication that Tx frames have been transmitted from the NPE. - */ - - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.txDoneCallbackCounter); - - do{ - qEntryPtr = txDoneQEntry; - txDoneQReadStatus = ixQMgrQBurstRead(IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, - IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK, - qEntryPtr); - -#ifndef NDEBUG - if (txDoneQReadStatus != IX_QMGR_Q_UNDERFLOW - && (txDoneQReadStatus != IX_SUCCESS)) - { - /*major error*/ - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthTxFrameDoneQMCallback:Error: %u\n", - (UINT32)txDoneQReadStatus, 0, 0, 0, 0, 0); - return; - } -#endif - - qEntry = *qEntryPtr; - - while(qEntry != 0) - { - mbufPtr = ixEthAccEntryFromQConvert(qEntry, - IX_ETHNPE_QM_Q_TXENET_ADDR_MASK); - -#ifndef NDEBUG - if (mbufPtr == NULL) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthTxFrameDoneQMCallback:Error: Null Mbuf Ptr\n", - 0, 0, 0, 0, 0, 0); - return; - } -#endif - - /* endianness conversions and stats updates */ - ixEthAccMbufFromTxQ(mbufPtr); - - /* - * Get NPE id from message, then convert to portId. - */ - npeId = ((IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK & - qEntry) >> - IX_ETHNPE_QM_Q_FIELD_NPEID_R); - portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); - -#ifndef NDEBUG - /* Prudent to at least check the port is within range */ - if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) - { - ixEthAccDataStats.unexpectedError++; - IX_ETH_ACC_FATAL_LOG( - "ixEthTxFrameDoneQMCallback: Illegal port: %u\n", - (UINT32)portId, 0, 0, 0, 0, 0); - return; - } -#endif - - TX_STATS_INC(portId,txDoneClientCallback); - - /* - * Call user level callback. - */ - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn( - ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag, - mbufPtr); - - /* move to next queue entry */ - qEntry = *(++qEntryPtr); - - } - } while( txDoneQReadStatus == IX_SUCCESS ); -} - -IX_ETH_ACC_PUBLIC -void ixEthAccDataPlaneShow(void) -{ - UINT32 numTx0Entries; - UINT32 numTx1Entries; - UINT32 numTxDoneEntries; - UINT32 numRxEntries; - UINT32 numRxFree0Entries; - UINT32 numRxFree1Entries; - UINT32 portId; -#ifdef __ixp46X - UINT32 numTx2Entries; - UINT32 numRxFree2Entries; -#endif -#ifndef NDEBUG - UINT32 priority; - UINT32 numBuffersInRx=0; - UINT32 numBuffersInTx=0; - UINT32 numBuffersInSwQ=0; - UINT32 totalBuffers=0; - UINT32 rxFreeCallbackCounter = 0; - UINT32 txCallbackCounter = 0; -#endif - UINT32 key; - - /* snapshot of stats */ - IxEthAccTxDataStats tx[IX_ETH_ACC_NUMBER_OF_PORTS]; - IxEthAccRxDataStats rx[IX_ETH_ACC_NUMBER_OF_PORTS]; - IxEthAccDataPlaneStats stats; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return; - } - - /* get a reliable snapshot */ - key = ixOsalIrqLock(); - - numTx0Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET0_Q, &numTx0Entries); - numTx1Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET1_Q, &numTx1Entries); - numTxDoneEntries = 0; - ixQMgrQNumEntriesGet( IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, &numTxDoneEntries); - numRxEntries = 0; - ixEthAccQMgrRxQEntryGet(&numRxEntries); - numRxFree0Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q, &numRxFree0Entries); - numRxFree1Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q, &numRxFree1Entries); - -#ifdef __ixp46X - numTx2Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET2_Q, &numTx2Entries); - numRxFree2Entries = 0; - ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q, &numRxFree2Entries); -#endif - - for(portId=IX_ETH_PORT_1; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - memcpy(&tx[portId], - &ixEthAccPortData[portId].ixEthAccTxData.stats, - sizeof(tx[portId])); - memcpy(&rx[portId], - &ixEthAccPortData[portId].ixEthAccRxData.stats, - sizeof(rx[portId])); - } - memcpy(&stats, &ixEthAccDataStats, sizeof(stats)); - - ixOsalIrqUnlock(key); - -#ifdef NDEBUG - printf("Detailed statistics collection not supported in this load\n"); -#endif - - /* print snapshot */ - for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */ - if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != - (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) - || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) - { - if ((IX_ETH_PORT_1 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - continue ; - } - if ((IX_ETH_PORT_2 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - continue ; - } - if ((IX_ETH_PORT_3 == portId) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - continue ; - } - } - - printf("PORT %u --------------------------------\n", - portId); -#ifndef NDEBUG - printf("Tx Done Frames : %u\n", - tx[portId].txDoneClientCallback + - tx[portId].txDoneSwQDuringDisable + - tx[portId].txDoneDuringDisable); - printf("Tx Frames : %u\n", - tx[portId].txQOK + tx[portId].txQDelayed); - printf("Tx H/W Q Added OK : %u\n", - tx[portId].txQOK); - printf("Tx H/W Q Delayed : %u\n", - tx[portId].txQDelayed); - printf("Tx From S/W Q Added OK : %u\n", - tx[portId].txFromSwQOK); - printf("Tx From S/W Q Delayed : %u\n", - tx[portId].txFromSwQDelayed); - printf("Tx Overflow : %u\n", - tx[portId].txOverflow); - printf("Tx Mutual Lock : %u\n", - tx[portId].txLock); - printf("Tx Late Ntf Enabled : %u\n", - tx[portId].txLateNotificationEnabled); - printf("Tx Low Thresh CB : %u\n", - tx[portId].txLowThreshCallback); - printf("Tx Done from H/W Q (Disable) : %u\n", - tx[portId].txDoneDuringDisable); - printf("Tx Done from S/W Q (Disable) : %u\n", - tx[portId].txDoneSwQDuringDisable); - for (priority = IX_ETH_ACC_TX_PRIORITY_0; - priority <= IX_ETH_ACC_TX_PRIORITY_7; - priority++) - { - if (tx[portId].txPriority[priority]) - { - printf("Tx Priority %u : %u\n", - priority, - tx[portId].txPriority[priority]); - } - } -#endif - printf("Tx unexpected errors : %u (should be 0)\n", - tx[portId].txUnexpectedError); - -#ifndef NDEBUG - printf("Rx Frames : %u\n", - rx[portId].rxFrameClientCallback + - rx[portId].rxSwQDuringDisable+ - rx[portId].rxDuringDisable); - printf("Rx Free Replenish : %u\n", - rx[portId].rxFreeRepOK + rx[portId].rxFreeRepDelayed); - printf("Rx Free H/W Q Added OK : %u\n", - rx[portId].rxFreeRepOK); - printf("Rx Free H/W Q Delayed : %u\n", - rx[portId].rxFreeRepDelayed); - printf("Rx Free From S/W Q Added OK : %u\n", - rx[portId].rxFreeRepFromSwQOK); - printf("Rx Free From S/W Q Delayed : %u\n", - rx[portId].rxFreeRepFromSwQDelayed); - printf("Rx Free Overflow : %u\n", - rx[portId].rxFreeOverflow); - printf("Rx Free Mutual Lock : %u\n", - rx[portId].rxFreeLock); - printf("Rx Free Late Ntf Enabled : %u\n", - rx[portId].rxFreeLateNotificationEnabled); - printf("Rx Free Low CB : %u\n", - rx[portId].rxFreeLowCallback); - printf("Rx From H/W Q (Disable) : %u\n", - rx[portId].rxDuringDisable); - printf("Rx From S/W Q (Disable) : %u\n", - rx[portId].rxSwQDuringDisable); - printf("Rx unlearned Mac Address : %u\n", - rx[portId].rxUnlearnedMacAddress); - printf("Rx Filtered (Rx => RxFree) : %u\n", - rx[portId].rxFiltered); - - for (priority = IX_ETH_ACC_TX_PRIORITY_0; - priority <= IX_ETH_ACC_TX_PRIORITY_7; - priority++) - { - if (rx[portId].rxPriority[priority]) - { - printf("Rx Priority %u : %u\n", - priority, - rx[portId].rxPriority[priority]); - } - } -#endif - printf("Rx unexpected errors : %u (should be 0)\n", - rx[portId].rxUnexpectedError); - -#ifndef NDEBUG - numBuffersInTx = tx[portId].txQOK + - tx[portId].txQDelayed - - tx[portId].txDoneClientCallback - - tx[portId].txDoneSwQDuringDisable - - tx[portId].txDoneDuringDisable; - - printf("# Tx Buffers currently for transmission : %u\n", - numBuffersInTx); - - numBuffersInRx = rx[portId].rxFreeRepOK + - rx[portId].rxFreeRepDelayed - - rx[portId].rxFrameClientCallback - - rx[portId].rxSwQDuringDisable - - rx[portId].rxDuringDisable; - - printf("# Rx Buffers currently for reception : %u\n", - numBuffersInRx); - - totalBuffers += numBuffersInRx + numBuffersInTx; -#endif - } - - printf("---------------------------------------\n"); - -#ifndef NDEBUG - printf("\n"); - printf("Mbufs :\n"); - printf("Tx Unchained mbufs : %u\n", - stats.unchainedTxMBufs); - printf("Tx Chained bufs : %u\n", - stats.chainedTxMBufs); - printf("TxDone Unchained mbufs : %u\n", - stats.unchainedTxDoneMBufs); - printf("TxDone Chained bufs : %u\n", - stats.chainedTxDoneMBufs); - printf("RxFree Unchained mbufs : %u\n", - stats.unchainedRxFreeMBufs); - printf("RxFree Chained bufs : %u\n", - stats.chainedRxFreeMBufs); - printf("Rx Unchained mbufs : %u\n", - stats.unchainedRxMBufs); - printf("Rx Chained bufs : %u\n", - stats.chainedRxMBufs); - - printf("\n"); - printf("Software queue usage :\n"); - printf("Buffers added to S/W Q : %u\n", - stats.addToSwQ); - printf("Buffers removed from S/W Q : %u\n", - stats.removeFromSwQ); - - printf("\n"); - printf("Hardware queues callbacks :\n"); - - for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - rxFreeCallbackCounter += rx[portId].rxFreeLowCallback; - txCallbackCounter += tx[portId].txLowThreshCallback; - } - printf("Tx Done QM Callback invoked : %u\n", - stats.txDoneCallbackCounter); - printf("Tx QM Callback invoked : %u\n", - txCallbackCounter); - printf("Rx QM Callback invoked : %u\n", - stats.rxCallbackCounter); - printf("Rx QM Callback burst read : %u\n", - stats.rxCallbackBurstRead); - printf("Rx Free QM Callback invoked : %u\n", - rxFreeCallbackCounter); -#endif - printf("Unexpected errors in CB : %u (should be 0)\n", - stats.unexpectedError); - printf("\n"); - - printf("Hardware queues levels :\n"); - printf("Transmit Port 1 Q : %u \n",numTx0Entries); - printf("Transmit Port 2 Q : %u \n",numTx1Entries); -#ifdef __ixp46X - printf("Transmit Port 3 Q : %u \n",numTx2Entries); -#endif - printf("Transmit Done Q : %u \n",numTxDoneEntries); - printf("Receive Q : %u \n",numRxEntries); - printf("Receive Free Port 1 Q : %u \n",numRxFree0Entries); - printf("Receive Free Port 2 Q : %u \n",numRxFree1Entries); -#ifdef __ixp46X - printf("Receive Free Port 3 Q : %u \n",numRxFree2Entries); -#endif - -#ifndef NDEBUG - printf("\n"); - printf("# Total Buffers accounted for : %u\n", - totalBuffers); - - numBuffersInSwQ = ixEthAccDataStats.addToSwQ - - ixEthAccDataStats.removeFromSwQ; - - printf(" Buffers in S/W Qs : %u\n", - numBuffersInSwQ); - printf(" Buffers in H/W Qs or NPEs : %u\n", - totalBuffers - numBuffersInSwQ); -#endif - - printf("Rx QoS Discipline : %s\n", - (ixEthAccDataInfo.schDiscipline == - FIFO_PRIORITY ) ? "Enabled" : "Disabled"); - - for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) - { - printf("Tx QoS Discipline port %u : %s\n", - portId, - (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == - FIFO_PRIORITY ) ? "Enabled" : "Disabled"); - } - printf("\n"); -} - - - - - diff --git a/arch/arm/cpu/ixp/npe/IxEthAccMac.c b/arch/arm/cpu/ixp/npe/IxEthAccMac.c deleted file mode 100644 index 369ee91..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthAccMac.c +++ /dev/null @@ -1,2641 +0,0 @@ -/** - * @file IxEthAccMac.c - * - * @author Intel Corporation - * @date - * - * @brief MAC control functions - * - * Design Notes: - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxOsal.h" -#include "IxNpeMh.h" -#ifdef CONFIG_IXP425_COMPONENT_ETHDB -#include "IxEthDB.h" -#endif -#include "IxEthDBPortDefs.h" -#include "IxEthNpe.h" -#include "IxEthAcc.h" -#include "IxEthAccDataPlane_p.h" -#include "IxEthAcc_p.h" -#include "IxEthAccMac_p.h" - -/* Maximum number of retries during ixEthAccPortDisable, which - * is approximately 10 seconds -*/ -#define IX_ETH_ACC_MAX_RETRY 500 - -/* Maximum number of retries during ixEthAccPortDisable when expecting - * timeout - */ -#define IX_ETH_ACC_MAX_RETRY_TIMEOUT 5 - -#define IX_ETH_ACC_VALIDATE_PORT_ID(portId) \ - do \ - { \ - if(!IX_ETH_ACC_IS_PORT_VALID(portId)) \ - { \ - return IX_ETH_ACC_INVALID_PORT; \ - } \ - } while(0) - -PUBLIC IxEthAccMacState ixEthAccMacState[IX_ETH_ACC_NUMBER_OF_PORTS]; - -PRIVATE UINT32 ixEthAccMacBase[IX_ETH_ACC_NUMBER_OF_PORTS]; - -/*Forward function declarations*/ -PRIVATE void -ixEthAccPortDisableRx (IxEthAccPortId portId, - IX_OSAL_MBUF * mBufPtr, - BOOL useMultiBufferCallback); - -PRIVATE void -ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId, - IX_OSAL_MBUF * mBufPtr, - BOOL useMultiBufferCallback); - -PRIVATE void -ixEthAccPortDisableTxDone (UINT32 cbTag, - IX_OSAL_MBUF *mbuf); - -PRIVATE void -ixEthAccPortDisableTxDoneAndSubmit (UINT32 cbTag, - IX_OSAL_MBUF *mbuf); - -PRIVATE void -ixEthAccPortDisableRxCallback (UINT32 cbTag, - IX_OSAL_MBUF * mBufPtr, - UINT32 learnedPortId); - -PRIVATE void -ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag, - IX_OSAL_MBUF **mBufPtr); - -PRIVATE IxEthAccStatus -ixEthAccPortDisableTryTransmit(UINT32 portId); - -PRIVATE IxEthAccStatus -ixEthAccPortDisableTryReplenish(UINT32 portId); - -PRIVATE IxEthAccStatus -ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - -PRIVATE IxEthAccStatus -ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - -PRIVATE void -ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId, - IxNpeMhMessage msg); - -PRIVATE void -ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId, - IxNpeMhMessage msg); - -PRIVATE void -ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId, - IxNpeMhMessage msg); - -PRIVATE void -ixEthAccMulticastAddressSet(IxEthAccPortId portId); - -PRIVATE BOOL -ixEthAccMacEqual(IxEthAccMacAddr *macAddr1, - IxEthAccMacAddr *macAddr2); - -PRIVATE void -ixEthAccMacPrint(IxEthAccMacAddr *m); - -PRIVATE void -ixEthAccMacStateUpdate(IxEthAccPortId portId); - -IxEthAccStatus -ixEthAccMacMemInit(void) -{ - ixEthAccMacBase[IX_ETH_PORT_1] = - (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, - IX_OSAL_IXP400_ETHA_MAP_SIZE); - ixEthAccMacBase[IX_ETH_PORT_2] = - (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_1_BASE, - IX_OSAL_IXP400_ETHB_MAP_SIZE); -#ifdef __ixp46X - ixEthAccMacBase[IX_ETH_PORT_3] = - (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_2_BASE, - IX_OSAL_IXP400_ETH_NPEA_MAP_SIZE); - if (ixEthAccMacBase[IX_ETH_PORT_3] == 0) - { - ixOsalLog(IX_OSAL_LOG_LVL_FATAL, - IX_OSAL_LOG_DEV_STDOUT, - "EthAcc: Could not map MAC I/O memory\n", - 0, 0, 0, 0, 0 ,0); - - return IX_ETH_ACC_FAIL; - } -#endif - - if (ixEthAccMacBase[IX_ETH_PORT_1] == 0 - || ixEthAccMacBase[IX_ETH_PORT_2] == 0) - { - ixOsalLog(IX_OSAL_LOG_LVL_FATAL, - IX_OSAL_LOG_DEV_STDOUT, - "EthAcc: Could not map MAC I/O memory\n", - 0, 0, 0, 0, 0 ,0); - - return IX_ETH_ACC_FAIL; - } - - return IX_ETH_ACC_SUCCESS; -} - -void -ixEthAccMacUnload(void) -{ - IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_1]); - IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_2]); -#ifdef __ixp46X - IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_3]); - ixEthAccMacBase[IX_ETH_PORT_3] = 0; -#endif - ixEthAccMacBase[IX_ETH_PORT_2] = 0; - ixEthAccMacBase[IX_ETH_PORT_1] = 0; -} - -IxEthAccStatus -ixEthAccPortEnablePriv(IxEthAccPortId portId) -{ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - printf("EthAcc: (Mac) cannot enable port %d, port not initialized\n", portId); - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - if (ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn == NULL) - { - /* TxDone callback not registered */ - printf("EthAcc: (Mac) cannot enable port %d, TxDone callback not registered\n", portId); - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - if ((ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn == NULL) - && (ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn == NULL)) - { - /* Receive callback not registered */ - printf("EthAcc: (Mac) cannot enable port %d, Rx callback not registered\n", portId); - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - if(!ixEthAccMacState[portId].initDone) - { - printf("EthAcc: (Mac) cannot enable port %d, MAC address not set\n", portId); - return (IX_ETH_ACC_MAC_UNINITIALIZED); - } - - /* if the state is being set to what it is already at, do nothing*/ - if (ixEthAccMacState[portId].enabled) - { - return IX_ETH_ACC_SUCCESS; - } - -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - /* enable ethernet database for this port */ - if (ixEthDBPortEnable(portId) != IX_ETH_DB_SUCCESS) - { - printf("EthAcc: (Mac) cannot enable port %d, EthDB failure\n", portId); - return IX_ETH_ACC_FAIL; - } -#endif - - /* set the MAC core registers */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL2, - IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RANDOM_SEED, - IX_ETH_ACC_RANDOM_SEED_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_THRESH_P_EMPTY, - IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_THRESH_P_FULL, - IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_DEFER, - IX_ETH_ACC_MAC_TX_DEFER_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_TWO_DEFER_1, - IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_TWO_DEFER_2, - IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_SLOT_TIME, - IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_INT_CLK_THRESH, - IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_BUF_SIZE_TX, - IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - IX_ETH_ACC_TX_CNTRL1_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - IX_ETH_ACC_RX_CNTRL1_DEFAULT); - - /* set the global state */ - ixEthAccMacState[portId].portDisableState = ACTIVE; - ixEthAccMacState[portId].enabled = TRUE; - - /* rewrite the setup (including mac filtering) depending - * on current options - */ - ixEthAccMacStateUpdate(portId); - - return IX_ETH_ACC_SUCCESS; -} - -/* - * PortDisable local variables. They contain the intermediate steps - * while the port is being disabled and the buffers being drained out - * of the NPE. - */ -typedef void (*IxEthAccPortDisableRx)(IxEthAccPortId portId, - IX_OSAL_MBUF * mBufPtr, - BOOL useMultiBufferCallback); -static IxEthAccPortRxCallback -ixEthAccPortDisableFn[IX_ETH_ACC_NUMBER_OF_PORTS]; -static IxEthAccPortMultiBufferRxCallback -ixEthAccPortDisableMultiBufferFn[IX_ETH_ACC_NUMBER_OF_PORTS]; -static IxEthAccPortDisableRx -ixEthAccPortDisableRxTable[IX_ETH_ACC_NUMBER_OF_PORTS]; -static UINT32 -ixEthAccPortDisableCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; -static UINT32 -ixEthAccPortDisableMultiBufferCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; - -static IxEthAccPortTxDoneCallback -ixEthAccPortDisableTxDoneFn[IX_ETH_ACC_NUMBER_OF_PORTS]; -static UINT32 -ixEthAccPortDisableTxDoneCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; - -static UINT32 -ixEthAccPortDisableUserBufferCount[IX_ETH_ACC_NUMBER_OF_PORTS]; - -/* - * PortDisable private callbacks functions. They handle the user - * traffic, and the special buffers (one for tx, one for rx) used - * in portDisable. - */ -PRIVATE void -ixEthAccPortDisableTxDone(UINT32 cbTag, - IX_OSAL_MBUF *mbuf) -{ - IxEthAccPortId portId = (IxEthAccPortId)cbTag; - volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; - - /* check for the special mbuf used in portDisable */ - if (mbuf == ixEthAccMacState[portId].portDisableTxMbufPtr) - { - *txState = TRANSMIT_DONE; - } - else - { - /* increment the count of user traffic during portDisable */ - ixEthAccPortDisableUserBufferCount[portId]++; - - /* call client TxDone function */ - ixEthAccPortDisableTxDoneFn[portId](ixEthAccPortDisableTxDoneCbTag[portId], mbuf); - } -} - -PRIVATE IxEthAccStatus -ixEthAccPortDisableTryTransmit(UINT32 portId) -{ - int key; - IxEthAccStatus status = IX_ETH_ACC_SUCCESS; - volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; - /* transmit the special buffer again if it is transmitted - * and update the txState - * This section is protected because the portDisable context - * run an identical code, so the system keeps transmitting at the - * maximum rate. - */ - key = ixOsalIrqLock(); - if (*txState == TRANSMIT_DONE) - { - IX_OSAL_MBUF *mbufTxPtr = ixEthAccMacState[portId].portDisableTxMbufPtr; - *txState = TRANSMIT; - status = ixEthAccPortTxFrameSubmit(portId, - mbufTxPtr, - IX_ETH_ACC_TX_DEFAULT_PRIORITY); - } - ixOsalIrqUnlock(key); - - return status; -} - -PRIVATE void -ixEthAccPortDisableTxDoneAndSubmit(UINT32 cbTag, - IX_OSAL_MBUF *mbuf) -{ - IxEthAccPortId portId = (IxEthAccPortId)cbTag; - - /* call the callback which forwards the traffic to the client */ - ixEthAccPortDisableTxDone(cbTag, mbuf); - - /* try to transmit the buffer used in portDisable - * if seen in TxDone - */ - ixEthAccPortDisableTryTransmit(portId); -} - -PRIVATE void -ixEthAccPortDisableRx (IxEthAccPortId portId, - IX_OSAL_MBUF * mBufPtr, - BOOL useMultiBufferCallback) -{ - volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; - IX_OSAL_MBUF *mNextPtr; - - while (mBufPtr) - { - mNextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr); - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr) = NULL; - - /* check for the special mbuf used in portDisable */ - if (mBufPtr == ixEthAccMacState[portId].portDisableRxMbufPtr) - { - *rxState = RECEIVE; - } - else - { - /* increment the count of user traffic during portDisable */ - ixEthAccPortDisableUserBufferCount[portId]++; - - /* reset the received payload length during portDisable */ - IX_OSAL_MBUF_MLEN(mBufPtr) = 0; - IX_OSAL_MBUF_PKT_LEN(mBufPtr) = 0; - - if (useMultiBufferCallback) - { - /* call the user callback with one unchained - * buffer, without payload. A small array is built - * to be used as a parameter (the user callback expects - * to receive an array ended by a NULL pointer. - */ - IX_OSAL_MBUF *mBufPtrArray[2]; - - mBufPtrArray[0] = mBufPtr; - mBufPtrArray[1] = NULL; - ixEthAccPortDisableMultiBufferFn[portId]( - ixEthAccPortDisableMultiBufferCbTag[portId], - mBufPtrArray); - } - else - { - /* call the user callback with a unchained - * buffer, without payload and the destination port is - * unknown. - */ - ixEthAccPortDisableFn[portId]( - ixEthAccPortDisableCbTag[portId], - mBufPtr, - IX_ETH_DB_UNKNOWN_PORT /* port not found */); - } - } - - mBufPtr = mNextPtr; - } -} - -PRIVATE IxEthAccStatus -ixEthAccPortDisableTryReplenish(UINT32 portId) -{ - int key; - IxEthAccStatus status = IX_ETH_ACC_SUCCESS; - volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; - /* replenish with the special buffer again if it is received - * and update the rxState - * This section is protected because the portDisable context - * run an identical code, so the system keeps replenishing at the - * maximum rate. - */ - key = ixOsalIrqLock(); - if (*rxState == RECEIVE) - { - IX_OSAL_MBUF *mbufRxPtr = ixEthAccMacState[portId].portDisableRxMbufPtr; - *rxState = REPLENISH; - IX_OSAL_MBUF_MLEN(mbufRxPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE; - status = ixEthAccPortRxFreeReplenish(portId, mbufRxPtr); - } - ixOsalIrqUnlock(key); - - return status; -} - -PRIVATE void -ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId, - IX_OSAL_MBUF * mBufPtr, - BOOL useMultiBufferCallback) -{ - /* call the callback which forwards the traffic to the client */ - ixEthAccPortDisableRx(portId, mBufPtr, useMultiBufferCallback); - - /* try to replenish with the buffer used in portDisable - * if seen in Rx - */ - ixEthAccPortDisableTryReplenish(portId); -} - -PRIVATE void -ixEthAccPortDisableRxCallback (UINT32 cbTag, - IX_OSAL_MBUF * mBufPtr, - UINT32 learnedPortId) -{ - IxEthAccPortId portId = (IxEthAccPortId)cbTag; - - /* call the portDisable receive callback */ - (ixEthAccPortDisableRxTable[portId])(portId, mBufPtr, FALSE); -} - -PRIVATE void -ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag, - IX_OSAL_MBUF **mBufPtr) -{ - IxEthAccPortId portId = (IxEthAccPortId)cbTag; - - while (*mBufPtr) - { - /* call the portDisable receive callback with one buffer at a time */ - (ixEthAccPortDisableRxTable[portId])(portId, *mBufPtr++, TRUE); - } -} - -IxEthAccStatus -ixEthAccPortDisablePriv(IxEthAccPortId portId) -{ - IxEthAccStatus status = IX_ETH_ACC_SUCCESS; - int key; - int retry, retryTimeout; - volatile IxEthAccPortDisableState *state = &ixEthAccMacState[portId].portDisableState; - volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; - volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable port.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* if the state is being set to what it is already at, do nothing */ - if (!ixEthAccMacState[portId].enabled) - { - return IX_ETH_ACC_SUCCESS; - } - - *state = DISABLED; - - /* disable MAC receive first */ - ixEthAccPortRxDisablePriv(portId); - -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - /* disable ethernet database for this port - It is done now to avoid - * issuing ELT maintenance after requesting 'port disable' in an NPE - */ - if (ixEthDBPortDisable(portId) != IX_ETH_DB_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - IX_ETH_ACC_FATAL_LOG("ixEthAccPortDisable: failed to disable EthDB for this port\n", 0, 0, 0, 0, 0, 0); - } -#endif - - /* enter the critical section */ - key = ixOsalIrqLock(); - - /* swap the Rx and TxDone callbacks */ - ixEthAccPortDisableFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn; - ixEthAccPortDisableMultiBufferFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn; - ixEthAccPortDisableCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag; - ixEthAccPortDisableMultiBufferCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag; - ixEthAccPortDisableTxDoneFn[portId] = ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn; - ixEthAccPortDisableTxDoneCbTag[portId] = ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag; - ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx; - - /* register temporary callbacks */ - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableRxCallback; - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = portId; - - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferRxCallback; - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = portId; - - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDone; - ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = portId; - - /* initialise the Rx state and Tx states */ - *txState = TRANSMIT_DONE; - *rxState = RECEIVE; - - /* exit the critical section */ - ixOsalIrqUnlock(key); - - /* enable a NPE loopback */ - if (ixEthAccNpeLoopbackEnablePriv(portId) != IX_ETH_ACC_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - - if (status == IX_ETH_ACC_SUCCESS) - { - retry = 0; - - /* Step 1 : Drain Tx traffic and TxDone queues : - * - * Transmit and replenish at least once with the - * special buffers until both of them are seen - * in the callback hook - * - * (the receive callback keeps replenishing, so once we see - * the special Tx buffer, we can be sure that Tx drain is complete) - */ - ixEthAccPortDisableRxTable[portId] - = ixEthAccPortDisableRxAndReplenish; - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn - = ixEthAccPortDisableTxDone; - - do - { - /* keep replenishing */ - status = ixEthAccPortDisableTryReplenish(portId); - if (status == IX_ETH_ACC_SUCCESS) - { - /* keep transmitting */ - status = ixEthAccPortDisableTryTransmit(portId); - } - if (status == IX_ETH_ACC_SUCCESS) - { - /* wait for some traffic being processed */ - ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); - } - } - while ((status == IX_ETH_ACC_SUCCESS) - && (retry++ < IX_ETH_ACC_MAX_RETRY) - && (*txState == TRANSMIT)); - - /* Step 2 : Drain Rx traffic, RxFree and Rx queues : - * - * Transmit and replenish at least once with the - * special buffers until both of them are seen - * in the callback hook - * (the transmit callback keeps transmitting, and when we see - * the special Rx buffer, we can be sure that rxFree drain - * is complete) - * - * The nested loop helps to retry if the user was keeping - * replenishing or transmitting during portDisable. - * - * The 2 nested loops ensure more retries if user traffic is - * seen during portDisable : the user should not replenish - * or transmit while portDisable is running. However, because of - * the queueing possibilities in ethAcc dataplane, it is possible - * that a lot of traffic is left in the queues (e.g. when - * transmitting over a low speed link) and therefore, more - * retries are allowed to help flushing the buffers out. - */ - ixEthAccPortDisableRxTable[portId] - = ixEthAccPortDisableRx; - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn - = ixEthAccPortDisableTxDoneAndSubmit; - - do - { - do - { - ixEthAccPortDisableUserBufferCount[portId] = 0; - - /* keep replenishing */ - status = ixEthAccPortDisableTryReplenish(portId); - if (status == IX_ETH_ACC_SUCCESS) - { - /* keep transmitting */ - status = ixEthAccPortDisableTryTransmit(portId); - } - if (status == IX_ETH_ACC_SUCCESS) - { - /* wait for some traffic being processed */ - ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); - } - } - while ((status == IX_ETH_ACC_SUCCESS) - && (retry++ < IX_ETH_ACC_MAX_RETRY) - && ((ixEthAccPortDisableUserBufferCount[portId] != 0) - || (*rxState == REPLENISH))); - - /* After the first iteration, change the receive callbacks, - * to process only 1 buffer at a time - */ - ixEthAccPortDisableRxTable[portId] - = ixEthAccPortDisableRx; - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn - = ixEthAccPortDisableTxDone; - - /* repeat the whole process while user traffic is seen in TxDone - * - * The conditions to stop the loop are - * - Xscale has both Rx and Tx special buffers - * (txState = transmit, rxState = receive) - * - any error in txSubmit or rxReplenish - * - no user traffic seen - * - an excessive amount of retries - */ - } - while ((status == IX_ETH_ACC_SUCCESS) - && (retry < IX_ETH_ACC_MAX_RETRY) - && (*txState == TRANSMIT)); - - /* check the loop exit conditions. The NPE should not hold - * the special buffers. - */ - if ((*rxState == REPLENISH) || (*txState == TRANSMIT)) - { - status = IX_ETH_ACC_FAIL; - } - - if (status == IX_ETH_ACC_SUCCESS) - { - /* Step 3 : Replenish without transmitting until a timeout - * occurs, in order to drain the internal NPE fifos - * - * we can expect a few frames srill held - * in the NPE. - * - * The 2 nested loops take care about the NPE dropping traffic - * (including loopback traffic) when the Rx queue is full. - * - * The timeout value is very conservative - * since the loopback used keeps replenishhing. - * - */ - do - { - ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRxAndReplenish; - ixEthAccPortDisableUserBufferCount[portId] = 0; - retryTimeout = 0; - do - { - /* keep replenishing */ - status = ixEthAccPortDisableTryReplenish(portId); - if (status == IX_ETH_ACC_SUCCESS) - { - /* wait for some traffic being processed */ - ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); - } - } - while ((status == IX_ETH_ACC_SUCCESS) - && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT)); - - /* Step 4 : Transmit once. Stop replenish - * - * After the Rx timeout, we are sure that the NPE does not - * hold any frame in its internal NPE fifos. - * - * At this point, the NPE still holds the last rxFree buffer. - * By transmitting a single frame, this should unblock the - * last rxFree buffer. This code just transmit once and - * wait for both frames seen in TxDone and in rxFree. - * - */ - ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx; - status = ixEthAccPortDisableTryTransmit(portId); - - /* the NPE should immediatelyt release - * the last Rx buffer and the last transmitted buffer - * unless the last Tx frame was dropped (rx queue full) - */ - if (status == IX_ETH_ACC_SUCCESS) - { - retryTimeout = 0; - do - { - ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); - } - while ((*rxState == REPLENISH) - && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT)); - } - - /* the NPE may have dropped the traffic because of Rx - * queue being full. This code ensures that the last - * Tx and Rx frames are both received. - */ - } - while ((status == IX_ETH_ACC_SUCCESS) - && (retry++ < IX_ETH_ACC_MAX_RETRY) - && ((*txState == TRANSMIT) - || (*rxState == REPLENISH) - || (ixEthAccPortDisableUserBufferCount[portId] != 0))); - - /* Step 5 : check the final states : the NPE has - * no buffer left, nor in Tx , nor in Rx directions. - */ - if ((*rxState == REPLENISH) || (*txState == TRANSMIT)) - { - status = IX_ETH_ACC_FAIL; - } - } - - /* now all the buffers are drained, disable NPE loopback - * This is done regardless of the logic to drain the queues and - * the internal buffers held by the NPE. - */ - if (ixEthAccNpeLoopbackDisablePriv(portId) != IX_ETH_ACC_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - } - - /* disable MAC Tx and Rx services */ - ixEthAccMacState[portId].enabled = FALSE; - ixEthAccMacStateUpdate(portId); - - /* restore the Rx and TxDone callbacks (within a critical section) */ - key = ixOsalIrqLock(); - - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableFn[portId]; - ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = ixEthAccPortDisableCbTag[portId]; - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferFn[portId]; - ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = ixEthAccPortDisableMultiBufferCbTag[portId]; - ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDoneFn[portId]; - ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = ixEthAccPortDisableTxDoneCbTag[portId]; - - ixOsalIrqUnlock(key); - - /* the MAC core rx/tx disable may left the MAC hardware in an - * unpredictable state. A hw reset is executed before resetting - * all the MAC parameters to a known value. - */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_RESET); - - ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); - - /* rewrite all parameters to their current value */ - ixEthAccMacStateUpdate(portId); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_INT_CLK_THRESH, - IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_MDC_EN); - - return status; -} - -IxEthAccStatus -ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled) -{ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0); - - /* Since Eth NPE is not available, port must be disabled */ - *enabled = FALSE ; - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - /* Since Eth NPE is not available, port must be disabled */ - *enabled = FALSE ; - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - *enabled = ixEthAccMacState[portId].enabled; - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortMacResetPriv(IxEthAccPortId portId) -{ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot reset Ethernet coprocessor.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_RESET); - - ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); - - /* rewrite all parameters to their current value */ - ixEthAccMacStateUpdate(portId); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_INT_CLK_THRESH, - IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_MDC_EN); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortLoopbackEnable(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable loopback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* read register */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - /* update register */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval | IX_ETH_ACC_RX_CNTRL1_LOOP_EN); - - return IX_ETH_ACC_SUCCESS; -} - -PRIVATE void -ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId, - IxNpeMhMessage msg) -{ - IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); - -#ifndef NDEBUG - /* Prudent to at least check the port is within range */ - if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) - { - IX_ETH_ACC_FATAL_LOG("IXETHACC:ixEthAccPortDisableMessageCallback: Illegal port: %u\n", - (UINT32) portId, 0, 0, 0, 0, 0); - - return; - } -#endif - - /* unlock message reception mutex */ - ixOsalMutexUnlock(&ixEthAccMacState[portId].npeLoopbackMessageLock); -} - -IxEthAccStatus -ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId) -{ - IX_STATUS npeMhStatus; - IxNpeMhMessage message; - IxEthAccStatus status = IX_ETH_ACC_SUCCESS; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* enable NPE loopback (lsb of the message contains the value 1) */ - message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL) - | 0x01; - message.data[1] = 0; - - npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), - message, - IX_ETHNPE_SETLOOPBACK_MODE_ACK, - ixEthAccNpeLoopbackMessageCallback, - IX_NPEMH_SEND_RETRIES_DEFAULT); - - if (npeMhStatus != IX_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - else - { - /* wait for NPE loopbackEnable response */ - if (ixOsalMutexLock(&ixEthAccMacState[portId]. npeLoopbackMessageLock, - IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS) - != IX_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - } - - return status; -} - -IxEthAccStatus -ixEthAccPortTxEnablePriv(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable TX.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* read register */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval); - - /* update register */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval | IX_ETH_ACC_TX_CNTRL1_TX_EN); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortRxEnablePriv(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable RX.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* read register */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - /* update register */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval | IX_ETH_ACC_RX_CNTRL1_RX_EN); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortLoopbackDisable(IxEthAccPortId portId) -{ - UINT32 regval; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable loopback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /*disable MAC loopabck */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - (regval & ~IX_ETH_ACC_RX_CNTRL1_LOOP_EN)); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId) -{ - IX_STATUS npeMhStatus; - IxNpeMhMessage message; - IxEthAccStatus status = IX_ETH_ACC_SUCCESS; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* disable NPE loopback (lsb of the message contains the value 0) */ - message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL); - message.data[1] = 0; - - npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), - message, - IX_ETHNPE_SETLOOPBACK_MODE_ACK, - ixEthAccNpeLoopbackMessageCallback, - IX_NPEMH_SEND_RETRIES_DEFAULT); - - if (npeMhStatus != IX_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - else - { - /* wait for NPE loopbackEnable response */ - if (ixOsalMutexLock(&ixEthAccMacState[portId].npeLoopbackMessageLock, - IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS) - != IX_SUCCESS) - { - status = IX_ETH_ACC_FAIL; - } - } - - return status; -} - -IxEthAccStatus -ixEthAccPortTxDisablePriv(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable TX.\n", (INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* read register */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval); - - /* update register */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - (regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN)); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortRxDisablePriv(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable RX.\n", (INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* read register */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - /* update register */ - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - (regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN)); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId) -{ - UINT32 regval; - - /* Turn off promiscuous mode */ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear promiscuous mode.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /*set bit 5 of Rx control 1 - enable address filtering*/ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN); - - ixEthAccMacState[portId].promiscuous = FALSE; - - ixEthAccMulticastAddressSet(portId); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId) -{ - UINT32 regval; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set promiscuous mode.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* - * Set bit 5 of Rx control 1 - We enable address filtering even in - * promiscuous mode because we want the MAC to set the appropriate - * bits in m_flags which doesn't happen if we turn off filtering. - */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN); - - ixEthAccMacState[portId].promiscuous = TRUE; - - ixEthAccMulticastAddressSet(portId); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortUnicastMacAddressSetPriv (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - UINT32 i; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - - if (macAddr == NULL) - { - return IX_ETH_ACC_FAIL; - } - - if ( macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT ) - { - /* This is a multicast/broadcast address cant set it ! */ - return IX_ETH_ACC_FAIL; - } - - if ( macAddr->macAddress[0] == 0 && - macAddr->macAddress[1] == 0 && - macAddr->macAddress[2] == 0 && - macAddr->macAddress[3] == 0 && - macAddr->macAddress[4] == 0 && - macAddr->macAddress[5] == 0 ) - { - /* This is an invalid mac address cant set it ! */ - return IX_ETH_ACC_FAIL; - } - -#ifdef CONFIG_IXP425_COMPONENT_ETHDB - /* update the MAC address in the ethernet database */ - if (ixEthDBPortAddressSet(portId, (IxEthDBMacAddr *) macAddr) != IX_ETH_DB_SUCCESS) - { - return IX_ETH_ACC_FAIL; - } -#endif - - /*Set the Unicast MAC to the specified value*/ - for(i=0;imacAddress[i]); - } - ixEthAccMacState[portId].initDone = TRUE; - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortUnicastMacAddressGetPriv (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - /*Return the current value of the Unicast MAC from h/w - for the specified port*/ - UINT32 i; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0); - /* Since Eth Npe is unavailable, return invalid MAC Address = 00:00:00:00:00:00 */ - for(i=0;imacAddress[i] = 0; - } - return IX_ETH_ACC_SUCCESS ; - } - - if(!ixEthAccMacState[portId].initDone) - { - return (IX_ETH_ACC_MAC_UNINITIALIZED); - } - - if (macAddr == NULL) - { - return IX_ETH_ACC_FAIL; - } - - - for(i=0;imacAddress[i]); - } - return IX_ETH_ACC_SUCCESS; -} - -PRIVATE IxEthAccStatus -ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - /*Return the current value of the Multicast MAC from h/w - for the specified port*/ - UINT32 i; - - for(i=0;imacAddress[i]); - } - - return IX_ETH_ACC_SUCCESS; -} - -PRIVATE IxEthAccStatus -ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - /*Return the current value of the Multicast MAC from h/w - for the specified port*/ - UINT32 i; - - for(i=0;imacAddress[i]); - } - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortMulticastAddressJoinPriv (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - UINT32 i; - IxEthAccMacAddr broadcastAddr = {{0xff,0xff,0xff,0xff,0xff,0xff}}; - - /*Check that the port parameter is valid*/ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join Multicast Mac Address.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /*Check that the mac address is valid*/ - if(macAddr == NULL) - { - return IX_ETH_ACC_FAIL; - } - - /* Check that this is a multicast address */ - if (!(macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT)) - { - return IX_ETH_ACC_FAIL; - } - - /* We don't add the Broadcast address */ - if(ixEthAccMacEqual(&broadcastAddr, macAddr)) - { - return IX_ETH_ACC_FAIL; - } - - for (i = 0; - i= IX_ETH_ACC_MAX_MULTICAST_ADDRESSES) - { - return IX_ETH_ACC_FAIL; - } - - /*First add the address to the multicast table for the - specified port*/ - i=ixEthAccMacState[portId].mcastAddrIndex; - - memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i], - &macAddr->macAddress, - IX_IEEE803_MAC_ADDRESS_SIZE); - - /*Increment the index into the table, this must be done here - as MulticastAddressSet below needs to know about the latest - entry. - */ - ixEthAccMacState[portId].mcastAddrIndex++; - - /*Then calculate the new value to be written to the address and - address mask registers*/ - ixEthAccMulticastAddressSet(portId); - - return IX_ETH_ACC_SUCCESS; -} - - -IxEthAccStatus -ixEthAccPortMulticastAddressJoinAllPriv (IxEthAccPortId portId) -{ - IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; - - /*Check that the port parameter is valid*/ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join all Multicast Address.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /* remove all entries from the database and - * insert a multicast entry - */ - memcpy(&ixEthAccMacState[portId].mcastAddrsTable[0], - &mcastMacAddr.macAddress, - IX_IEEE803_MAC_ADDRESS_SIZE); - - ixEthAccMacState[portId].mcastAddrIndex = 1; - ixEthAccMacState[portId].joinAll = TRUE; - - ixEthAccMulticastAddressSet(portId); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccPortMulticastAddressLeavePriv (IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) -{ - UINT32 i; - IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; - - /*Check that the port parameter is valid*/ - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave Multicast Address.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - /*Check that the mac address is valid*/ - if(macAddr == NULL) - { - return IX_ETH_ACC_FAIL; - } - /* Remove this mac address from the mask for the specified port - * we copy down all entries above the blanked entry, and - * decrement the index - */ - i=0; - - while(i= IX_ETH_ACC_NUMBER_OF_PORTS) - { - IX_ETH_ACC_FATAL_LOG( - "IXETHACC:ixEthAccMacNpeStatsMessageCallback: Illegal port: %u\n", - (UINT32)portId, 0, 0, 0, 0, 0); - return; - } -#endif - - /*Unblock Stats Get call*/ - ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsLock); - -} - -PRIVATE void -ixEthAccMibIIStatsEndianConvert (IxEthEthObjStats *retStats) -{ - /* endianness conversion */ - - /* Rx stats */ - retStats->dot3StatsAlignmentErrors = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsAlignmentErrors); - retStats->dot3StatsFCSErrors = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsFCSErrors); - retStats->dot3StatsInternalMacReceiveErrors = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacReceiveErrors); - retStats->RxOverrunDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxOverrunDiscards); - retStats->RxLearnedEntryDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLearnedEntryDiscards); - retStats->RxLargeFramesDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLargeFramesDiscards); - retStats->RxSTPBlockedDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxSTPBlockedDiscards); - retStats->RxVLANTypeFilterDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANTypeFilterDiscards); - retStats->RxVLANIdFilterDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANIdFilterDiscards); - retStats->RxInvalidSourceDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxInvalidSourceDiscards); - retStats->RxBlackListDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxBlackListDiscards); - retStats->RxWhiteListDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxWhiteListDiscards); - retStats->RxUnderflowEntryDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxUnderflowEntryDiscards); - - /* Tx stats */ - retStats->dot3StatsSingleCollisionFrames = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsSingleCollisionFrames); - retStats->dot3StatsMultipleCollisionFrames = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsMultipleCollisionFrames); - retStats->dot3StatsDeferredTransmissions = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsDeferredTransmissions); - retStats->dot3StatsLateCollisions = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsLateCollisions); - retStats->dot3StatsExcessiveCollsions = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsExcessiveCollsions); - retStats->dot3StatsInternalMacTransmitErrors = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacTransmitErrors); - retStats->dot3StatsCarrierSenseErrors = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsCarrierSenseErrors); - retStats->TxLargeFrameDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxLargeFrameDiscards); - retStats->TxVLANIdFilterDiscards = - IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxVLANIdFilterDiscards); -} - -IxEthAccStatus -ixEthAccMibIIStatsGet (IxEthAccPortId portId, - IxEthEthObjStats *retStats ) -{ - IxNpeMhMessage message; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - printf("EthAcc: ixEthAccMibIIStatsGet (Mac) EthAcc service is not initialized\n"); - return (IX_ETH_ACC_FAIL); - } - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (retStats == NULL) - { - printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NULL argument\n"); - return (IX_ETH_ACC_FAIL); - } - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NPE for port %d is not available\n", portId); - - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get MIB II Stats.\n",(INT32)portId,0,0,0,0,0); - - /* Return all zero stats */ - IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats)); - - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - printf("EthAcc: ixEthAccMibIIStatsGet (Mac) port %d is not initialized\n", portId); - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats)); - - message.data[0] = IX_ETHNPE_GETSTATS << IX_ETH_ACC_MAC_MSGID_SHL; - message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats); - - /* Permit only one task to request MIB statistics Get operation - at a time */ - ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetAccessLock, IX_OSAL_WAIT_FOREVER); - - if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), - message, - IX_ETHNPE_GETSTATS, - ixEthAccMacNpeStatsMessageCallback, - IX_NPEMH_SEND_RETRIES_DEFAULT) - != IX_SUCCESS) - { - ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock); - - printf("EthAcc: (Mac) StatsGet failed to send NPE message\n"); - - return IX_ETH_ACC_FAIL; - } - - /* Wait for callback invocation indicating response to - this request - we need this mutex in order to ensure - that the return from this function is synchronous */ - ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS); - - /* Permit other tasks to perform MIB statistics Get operation */ - ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock); - - ixEthAccMibIIStatsEndianConvert (retStats); - - return IX_ETH_ACC_SUCCESS; -} - - -PRIVATE void -ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId, - IxNpeMhMessage msg) -{ - IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); - -#ifndef NDEBUG - /* Prudent to at least check the port is within range */ - if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) - { - IX_ETH_ACC_FATAL_LOG( - "IXETHACC:ixEthAccMacNpeStatsResetMessageCallback: Illegal port: %u\n", - (UINT32)portId, 0, 0, 0, 0, 0); - return; - } -#endif - - /*Unblock Stats Get & reset call*/ - ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsResetLock); - -} - - - -IxEthAccStatus -ixEthAccMibIIStatsGetClear (IxEthAccPortId portId, - IxEthEthObjStats *retStats) -{ - IxNpeMhMessage message; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) EthAcc service is not initialized\n"); - return (IX_ETH_ACC_FAIL); - } - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (retStats == NULL) - { - printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NULL argument\n"); - return (IX_ETH_ACC_FAIL); - } - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NPE for port %d is not available\n", portId); - - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get and clear MIB II Stats.\n", (INT32)portId, 0, 0, 0, 0, 0); - - /* Return all zero stats */ - IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats)); - - return IX_ETH_ACC_SUCCESS ; - } - - if (!IX_ETH_IS_PORT_INITIALIZED(portId)) - { - printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) port %d is not initialized\n", portId); - return (IX_ETH_ACC_PORT_UNINITIALIZED); - } - - IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats)); - - message.data[0] = IX_ETHNPE_RESETSTATS << IX_ETH_ACC_MAC_MSGID_SHL; - message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats); - - /* Permit only one task to request MIB statistics Get-Reset operation at a time */ - ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock, IX_OSAL_WAIT_FOREVER); - - if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), - message, - IX_ETHNPE_RESETSTATS, - ixEthAccMacNpeStatsResetMessageCallback, - IX_NPEMH_SEND_RETRIES_DEFAULT) - != IX_SUCCESS) - { - ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); - - printf("EthAcc: (Mac) ixEthAccMibIIStatsGetClear failed to send NPE message\n"); - - return IX_ETH_ACC_FAIL; - } - - /* Wait for callback invocation indicating response to this request */ - ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS); - - /* permit other tasks to get and reset MIB stats*/ - ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); - - ixEthAccMibIIStatsEndianConvert(retStats); - - return IX_ETH_ACC_SUCCESS; -} - -IxEthAccStatus -ixEthAccMibIIStatsClear (IxEthAccPortId portId) -{ - static IxEthEthObjStats retStats; - IxEthAccStatus status; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear MIB II Stats.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - /* there is no reset operation without a corresponding Get */ - status = ixEthAccMibIIStatsGetClear(portId, &retStats); - - return status; -} - -/* Initialize the ethernet MAC settings */ -IxEthAccStatus -ixEthAccMacInit(IxEthAccPortId portId) -{ - IX_OSAL_MBUF_POOL* portDisablePool; - UINT8 *data; - - IX_ETH_ACC_VALIDATE_PORT_ID(portId); - - if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) - { - IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Mac.\n",(INT32)portId,0,0,0,0,0); - return IX_ETH_ACC_SUCCESS ; - } - - if(ixEthAccMacState[portId].macInitialised == FALSE) - { - ixEthAccMacState[portId].fullDuplex = TRUE; - ixEthAccMacState[portId].rxFCSAppend = TRUE; - ixEthAccMacState[portId].txFCSAppend = TRUE; - ixEthAccMacState[portId].txPADAppend = TRUE; - ixEthAccMacState[portId].enabled = FALSE; - ixEthAccMacState[portId].promiscuous = TRUE; - ixEthAccMacState[portId].joinAll = FALSE; - ixEthAccMacState[portId].initDone = FALSE; - ixEthAccMacState[portId].macInitialised = TRUE; - - /* initialize MIB stats mutexes */ - ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsLock); - ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_OSAL_WAIT_FOREVER); - - ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsResetLock); - ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_OSAL_WAIT_FOREVER); - - ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetAccessLock); - - ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); - - ixOsalMutexInit(&ixEthAccMacState[portId].npeLoopbackMessageLock); - - ixEthAccMacState[portId].portDisableRxMbufPtr = NULL; - ixEthAccMacState[portId].portDisableTxMbufPtr = NULL; - - portDisablePool = IX_OSAL_MBUF_POOL_INIT(2, - IX_ETHACC_RX_MBUF_MIN_SIZE, - "portDisable Pool"); - - IX_OSAL_ENSURE(portDisablePool != NULL, "Failed to initialize PortDisable pool"); - - ixEthAccMacState[portId].portDisableRxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool); - ixEthAccMacState[portId].portDisableTxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool); - - IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableRxMbufPtr != NULL, - "Pool allocation failed"); - IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableTxMbufPtr != NULL, - "Pool allocation failed"); - /* fill the payload of the Rx mbuf used in portDisable */ - IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableRxMbufPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE; - - memset(IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableRxMbufPtr), - 0xAA, - IX_ETHACC_RX_MBUF_MIN_SIZE); - - /* fill the payload of the Tx mbuf used in portDisable (64 bytes) */ - IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64; - IX_OSAL_MBUF_PKT_LEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64; - - data = (UINT8 *) IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableTxMbufPtr); - memset(data, 0xBB, 64); - data[0] = 0x00; /* unicast destination MAC address */ - data[6] = 0x00; /* unicast source MAC address */ - data[12] = 0x08; /* typelength : IP frame */ - data[13] = 0x00; /* typelength : IP frame */ - - IX_OSAL_CACHE_FLUSH(data, 64); - } - - IX_OSAL_ASSERT (ixEthAccMacBase[portId] != 0); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_RESET); - - ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_CORE_CNTRL, - IX_ETH_ACC_CORE_MDC_EN); - - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_INT_CLK_THRESH, - IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); - - ixEthAccMacStateUpdate(portId); - - return IX_ETH_ACC_SUCCESS; -} - -/* PRIVATE Functions*/ - -PRIVATE void -ixEthAccMacStateUpdate(IxEthAccPortId portId) -{ - UINT32 regval; - - if ( ixEthAccMacState[portId].enabled == FALSE ) - { - /* Just disable both the transmitter and reciver in the MAC. */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN); - - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval); - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN); - } - - if(ixEthAccMacState[portId].fullDuplex) - { - ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_FULL_DUPLEX); - } - else - { - ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_HALF_DUPLEX); - } - - if(ixEthAccMacState[portId].rxFCSAppend) - { - ixEthAccPortRxFrameAppendFCSEnablePriv (portId); - } - else - { - ixEthAccPortRxFrameAppendFCSDisablePriv (portId); - } - - if(ixEthAccMacState[portId].txFCSAppend) - { - ixEthAccPortTxFrameAppendFCSEnablePriv (portId); - } - else - { - ixEthAccPortTxFrameAppendFCSDisablePriv (portId); - } - - if(ixEthAccMacState[portId].txPADAppend) - { - ixEthAccPortTxFrameAppendPaddingEnablePriv (portId); - } - else - { - ixEthAccPortTxFrameAppendPaddingDisablePriv (portId); - } - - if(ixEthAccMacState[portId].promiscuous) - { - ixEthAccPortPromiscuousModeSetPriv(portId); - } - else - { - ixEthAccPortPromiscuousModeClearPriv(portId); - } - - if ( ixEthAccMacState[portId].enabled == TRUE ) - { - /* Enable both the transmitter and reciver in the MAC. */ - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval); - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_RX_CNTRL1, - regval | IX_ETH_ACC_RX_CNTRL1_RX_EN); - - REG_READ(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval); - REG_WRITE(ixEthAccMacBase[portId], - IX_ETH_ACC_MAC_TX_CNTRL1, - regval | IX_ETH_ACC_TX_CNTRL1_TX_EN); - } -} - - -PRIVATE BOOL -ixEthAccMacEqual(IxEthAccMacAddr *macAddr1, - IxEthAccMacAddr *macAddr2) -{ - UINT32 i; - for(i=0;imacAddress[i] != macAddr2->macAddress[i]) - { - return FALSE; - } - } - return TRUE; -} - -PRIVATE void -ixEthAccMacPrint(IxEthAccMacAddr *m) -{ - printf("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", - m->macAddress[0], m->macAddress[1], - m->macAddress[2], m->macAddress[3], - m->macAddress[4], m->macAddress[5]); -} - -/* Set the multicast address and address mask registers - * - * A bit in the address mask register must be set if - * all multicast addresses always have that bit set, or if - * all multicast addresses always have that bit cleared. - * - * A bit in the address register must be set if all multicast - * addresses have that bit set, otherwise, it should be cleared - */ - -PRIVATE void -ixEthAccMulticastAddressSet(IxEthAccPortId portId) -{ - UINT32 i; - UINT32 j; - IxEthAccMacAddr addressMask; - IxEthAccMacAddr address; - IxEthAccMacAddr alwaysClearBits; - IxEthAccMacAddr alwaysSetBits; - - /* calculate alwaysClearBits and alwaysSetBits: - * alwaysClearBits is calculated by ORing all - * multicast addresses, those bits that are always - * clear are clear in the result - * - * alwaysSetBits is calculated by ANDing all - * multicast addresses, those bits that are always set - * are set in the result - */ - - if (ixEthAccMacState[portId].promiscuous == TRUE) - { - /* Promiscuous Mode is set, and filtering - * allow all packets, and enable the mcast and - * bcast detection. - */ - memset(&addressMask.macAddress, - 0, - IX_IEEE803_MAC_ADDRESS_SIZE); - memset(&address.macAddress, - 0, - IX_IEEE803_MAC_ADDRESS_SIZE); - } - else - { - if(ixEthAccMacState[portId].joinAll == TRUE) - { - /* Join all is set. The mask and address are - * the multicast settings. - */ - IxEthAccMacAddr macAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; - - memcpy(addressMask.macAddress, - macAddr.macAddress, - IX_IEEE803_MAC_ADDRESS_SIZE); - memcpy(address.macAddress, - macAddr.macAddress, - IX_IEEE803_MAC_ADDRESS_SIZE); - } - else if(ixEthAccMacState[portId].mcastAddrIndex == 0) - { - /* No entry in the filtering database, - * Promiscuous Mode is cleared, Broadcast filtering - * is configured. - */ - memset(addressMask.macAddress, - IX_ETH_ACC_MAC_ALL_BITS_SET, - IX_IEEE803_MAC_ADDRESS_SIZE); - memset(address.macAddress, - IX_ETH_ACC_MAC_ALL_BITS_SET, - IX_IEEE803_MAC_ADDRESS_SIZE); - } - else - { - /* build a mask and an address which mix all entreis - * from the list of multicast addresses - */ - memset(alwaysClearBits.macAddress, - 0, - IX_IEEE803_MAC_ADDRESS_SIZE); - memset(alwaysSetBits.macAddress, - IX_ETH_ACC_MAC_ALL_BITS_SET, - IX_IEEE803_MAC_ADDRESS_SIZE); - - for(i=0;i> 8) & 0xff); - - REG_WRITE(miiBaseAddressVirt, - IX_ETH_ACC_MAC_MDIO_CMD_3, - (mdioCommand >> 16) & 0xff); - - REG_WRITE(miiBaseAddressVirt, - IX_ETH_ACC_MAC_MDIO_CMD_4, - (mdioCommand >> 24) & 0xff); -} - -PRIVATE void -ixEthAccMdioCmdRead(UINT32 *data) -{ - UINT32 regval; - - REG_READ(miiBaseAddressVirt, - IX_ETH_ACC_MAC_MDIO_CMD_1, - regval); - - *data = regval & 0xff; - - REG_READ(miiBaseAddressVirt, - IX_ETH_ACC_MAC_MDIO_CMD_2, - regval); - - *data |= (regval & 0xff) << 8; - - REG_READ(miiBaseAddressVirt, - IX_ETH_ACC_MAC_MDIO_CMD_3, - regval); - - *data |= (regval & 0xff) << 16; - - REG_READ(miiBaseAddressVirt, - IX_ETH_ACC_MAC_MDIO_CMD_4, - regval); - - *data |= (regval & 0xff) << 24; - -} - -PRIVATE void -ixEthAccMdioStatusRead(UINT32 *data) -{ - UINT32 regval; - - REG_READ(miiBaseAddressVirt, - IX_ETH_ACC_MAC_MDIO_STS_1, - regval); - - *data = regval & 0xff; - - REG_READ(miiBaseAddressVirt, - IX_ETH_ACC_MAC_MDIO_STS_2, - regval); - - *data |= (regval & 0xff) << 8; - - REG_READ(miiBaseAddressVirt, - IX_ETH_ACC_MAC_MDIO_STS_3, - regval); - - *data |= (regval & 0xff) << 16; - - REG_READ(miiBaseAddressVirt, - IX_ETH_ACC_MAC_MDIO_STS_4, - regval); - - *data |= (regval & 0xff) << 24; - -} - - -/******************************************************************** - * ixEthAccMiiInit - */ -IxEthAccStatus -ixEthAccMiiInit() -{ - if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS) - { - return IX_ETH_ACC_FAIL; - } - - miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETHA_MAP_SIZE); - - if (miiBaseAddressVirt == 0) - { - ixOsalLog(IX_OSAL_LOG_LVL_FATAL, - IX_OSAL_LOG_DEV_STDOUT, - "EthAcc: Could not map MII I/O mapped memory\n", - 0, 0, 0, 0, 0, 0); - - return IX_ETH_ACC_FAIL; - } - - return IX_ETH_ACC_SUCCESS; -} - -void -ixEthAccMiiUnload(void) -{ - IX_OSAL_MEM_UNMAP(miiBaseAddressVirt); - - miiBaseAddressVirt = 0; -} - -PUBLIC IxEthAccStatus -ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount) -{ - if (retryCount < 1) return IX_ETH_ACC_FAIL; - - ixEthAccMiiRetryCount = retryCount; - ixEthAccMiiAccessTimeout = timeout; - - return IX_ETH_ACC_SUCCESS; -} - -/********************************************************************* - * ixEthAccMiiReadRtn - read a 16 bit value from a PHY - */ -IxEthAccStatus -ixEthAccMiiReadRtn (UINT8 phyAddr, - UINT8 phyReg, - UINT16 *value) -{ - UINT32 mdioCommand; - UINT32 regval; - UINT32 miiTimeout; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR) - || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG)) - { - return (IX_ETH_ACC_FAIL); - } - - if (value == NULL) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER); - mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL - | phyAddr << IX_ETH_ACC_MII_ADDR_SHL; - mdioCommand |= IX_ETH_ACC_MII_GO; - - ixEthAccMdioCmdWrite(mdioCommand); - - miiTimeout = ixEthAccMiiRetryCount; - - while(miiTimeout) - { - - ixEthAccMdioCmdRead(®val); - - if((regval & IX_ETH_ACC_MII_GO) == 0x0) - { - break; - } - /* Sleep for a while */ - ixOsalSleep(ixEthAccMiiAccessTimeout); - miiTimeout--; - } - - - - if(miiTimeout == 0) - { - ixOsalMutexUnlock(&miiAccessLock); - *value = 0xffff; - return IX_ETH_ACC_FAIL; - } - - - ixEthAccMdioStatusRead(®val); - if(regval & IX_ETH_ACC_MII_READ_FAIL) - { - ixOsalMutexUnlock(&miiAccessLock); - *value = 0xffff; - return IX_ETH_ACC_FAIL; - } - - *value = regval & 0xffff; - ixOsalMutexUnlock(&miiAccessLock); - return IX_ETH_ACC_SUCCESS; - -} - - -/********************************************************************* - * ixEthAccMiiWriteRtn - write a 16 bit value to a PHY - */ -IxEthAccStatus -ixEthAccMiiWriteRtn (UINT8 phyAddr, - UINT8 phyReg, - UINT16 value) -{ - UINT32 mdioCommand; - UINT32 regval; - UINT16 readVal; - UINT32 miiTimeout; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR) - || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG)) - { - return (IX_ETH_ACC_FAIL); - } - - /* ensure that a PHY is present at this address */ - if(ixEthAccMiiReadRtn(phyAddr, - IX_ETH_ACC_MII_CTRL_REG, - &readVal) != IX_ETH_ACC_SUCCESS) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER); - mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL - | phyAddr << IX_ETH_ACC_MII_ADDR_SHL ; - mdioCommand |= IX_ETH_ACC_MII_GO | IX_ETH_ACC_MII_WRITE | value; - - ixEthAccMdioCmdWrite(mdioCommand); - - miiTimeout = ixEthAccMiiRetryCount; - - while(miiTimeout) - { - - ixEthAccMdioCmdRead(®val); - - /*The "GO" bit is reset to 0 when the write completes*/ - if((regval & IX_ETH_ACC_MII_GO) == 0x0) - { - break; - } - /* Sleep for a while */ - ixOsalSleep(ixEthAccMiiAccessTimeout); - miiTimeout--; - } - - ixOsalMutexUnlock(&miiAccessLock); - if(miiTimeout == 0) - { - return IX_ETH_ACC_FAIL; - } - return IX_ETH_ACC_SUCCESS; -} - - -/***************************************************************** - * - * Phy query functions - * - */ -IxEthAccStatus -ixEthAccMiiStatsShow (UINT32 phyAddr) -{ - UINT16 regval; - printf("Regisers on PHY at address 0x%x\n", phyAddr); - ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_CTRL_REG, ®val); - printf(" Control Register : 0x%4.4x\n", regval); - ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_STAT_REG, ®val); - printf(" Status Register : 0x%4.4x\n", regval); - ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID1_REG, ®val); - printf(" PHY ID1 Register : 0x%4.4x\n", regval); - ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID2_REG, ®val); - printf(" PHY ID2 Register : 0x%4.4x\n", regval); - ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_ADS_REG, ®val); - printf(" Auto Neg ADS Register : 0x%4.4x\n", regval); - ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_PRTN_REG, ®val); - printf(" Auto Neg Partner Ability Register : 0x%4.4x\n", regval); - ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_EXP_REG, ®val); - printf(" Auto Neg Expansion Register : 0x%4.4x\n", regval); - ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_NEXT_REG, ®val); - printf(" Auto Neg Next Register : 0x%4.4x\n", regval); - - return IX_ETH_ACC_SUCCESS; -} - - -/***************************************************************** - * - * Interface query functions - * - */ -IxEthAccStatus -ixEthAccMdioShow (void) -{ - UINT32 regval; - - if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) - { - return (IX_ETH_ACC_FAIL); - } - - ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER); - ixEthAccMdioCmdRead(®val); - ixOsalMutexUnlock(&miiAccessLock); - - printf("MDIO command register\n"); - printf(" Go bit : 0x%x\n", (regval & BIT(31)) >> 31); - printf(" MDIO Write : 0x%x\n", (regval & BIT(26)) >> 26); - printf(" PHY address : 0x%x\n", (regval >> 21) & 0x1f); - printf(" Reg address : 0x%x\n", (regval >> 16) & 0x1f); - - ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER); - ixEthAccMdioStatusRead(®val); - ixOsalMutexUnlock(&miiAccessLock); - - printf("MDIO status register\n"); - printf(" Read OK : 0x%x\n", (regval & BIT(31)) >> 31); - printf(" Read Data : 0x%x\n", (regval >> 16) & 0xff); - - return IX_ETH_ACC_SUCCESS; -} - diff --git a/arch/arm/cpu/ixp/npe/IxEthDBAPI.c b/arch/arm/cpu/ixp/npe/IxEthDBAPI.c deleted file mode 100644 index b2bfb72..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBAPI.c +++ /dev/null @@ -1,448 +0,0 @@ -/** - * @file IxEthDBAPI.c - * - * @brief Implementation of the public API - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxEthDB_p.h" -#include "IxFeatureCtrl.h" - -extern HashTable dbHashtable; -extern IxEthDBPortMap overflowUpdatePortList; -extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1]; - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING); - - return ixEthDBTriggerAddPortUpdate(macAddr, portID, TRUE); -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING); - - return ixEthDBTriggerAddPortUpdate(macAddr, portID, FALSE); -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr) -{ - HashNode *searchResult; - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); - - if (searchResult == NULL) - { - return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ - } - - ixEthDBReleaseHashNode(searchResult); - - /* build a remove event and place it on the event queue */ - return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID); -} - -IX_ETH_DB_PUBLIC -void ixEthDBDatabaseMaintenance() -{ - HashIterator iterator; - UINT32 portIndex; - BOOL agingRequired = FALSE; - - /* ports who will have deleted records and therefore will need updating */ - IxEthDBPortMap triggerPorts; - - if (IX_FEATURE_CTRL_SWCONFIG_ENABLED != - ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING)) - { - return; - } - - SET_EMPTY_DEPENDENCY_MAP(triggerPorts); - - /* check if there's at least a port that needs aging */ - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled) - { - agingRequired = TRUE; - } - } - - if (agingRequired) - { - /* ask each NPE port to write back the database for aging inspection */ - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE - && ixEthDBPortInfo[portIndex].agingEnabled - && ixEthDBPortInfo[portIndex].enabled) - { - IxNpeMhMessage message; - IX_STATUS result; - - /* send EDB_GetMACAddressDatabase message */ - FILL_GETMACADDRESSDATABASE(message, - 0 /* unused */, - IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone)); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), message, result); - - if (result == IX_SUCCESS) - { - /* analyze NPE copy */ - ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE); - - IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex); - } - else - { - ixEthDBPortInfo[portIndex].agingEnabled = FALSE; - ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = FALSE; - ixEthDBPortInfo[portIndex].updateMethod.userControlled = TRUE; - - ixOsalLog(IX_OSAL_LOG_LVL_FATAL, - IX_OSAL_LOG_DEV_STDOUT, - "EthDB: (Maintenance) warning, disabling aging and updates for port %d (assumed dead)\n", - portIndex, 0, 0, 0, 0, 0); - - ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES); - } - } - } - - /* browse database and age entries */ - BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); - - while (IS_ITERATOR_VALID(&iterator)) - { - MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; - UINT32 *age = NULL; - BOOL staticEntry = TRUE; - - if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) - { - age = &descriptor->recordData.filteringData.age; - staticEntry = descriptor->recordData.filteringData.staticEntry; - } - else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) - { - age = &descriptor->recordData.filteringVlanData.age; - staticEntry = descriptor->recordData.filteringVlanData.staticEntry; - } - else - { - staticEntry = TRUE; - } - - if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == FALSE)) - { - /* manually increment the age if the port has no such capability */ - if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0) - { - *age += (IX_ETH_DB_MAINTENANCE_TIME / 60); - } - - /* age entry if it exceeded the maximum time to live */ - if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60)) - { - /* add port to the set of update trigger ports */ - JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID); - - /* delete entry */ - BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator)); - } - else - { - /* move to the next record */ - BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); - } - } - else - { - /* move to the next record */ - BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); - } - } - - /* update ports which lost records */ - ixEthDBUpdatePortLearningTrees(triggerPorts); - } -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType) -{ - IxEthDBPortMap triggerPorts; - HashIterator iterator; - - if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS) - { - return IX_ETH_DB_INVALID_PORT; - } - - /* check if the user passes some extra bits */ - if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES) - { - return IX_ETH_DB_INVALID_ARG; - } - - SET_EMPTY_DEPENDENCY_MAP(triggerPorts); - - /* browse database and age entries */ - BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); - - while (IS_ITERATOR_VALID(&iterator)) - { - MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; - - if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS)) - && ((descriptor->type & recordType) != 0)) - { - /* add to trigger if automatic updates are required */ - if (ixEthDBPortUpdateRequired[descriptor->type]) - { - /* add port to the set of update trigger ports */ - JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID); - } - - /* delete entry */ - BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator)); - } - else - { - /* move to the next record */ - BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); - } - } - - /* update ports which lost records */ - ixEthDBUpdatePortLearningTrees(triggerPorts); - - return IX_ETH_DB_SUCCESS; -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) -{ - HashNode *searchResult; - IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING); - - searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); - - if (searchResult == NULL) - { - return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ - } - - if (((MacDescriptor *) (searchResult->data))->portID == portID) - { - result = IX_ETH_DB_SUCCESS; /* address and port match */ - } - - ixEthDBReleaseHashNode(searchResult); - - return result; -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) -{ - HashNode *searchResult; - - IX_ETH_DB_CHECK_REFERENCE(portID); - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); - - if (searchResult == NULL) - { - return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ - } - - /* return the port ID */ - *portID = ((MacDescriptor *) searchResult->data)->portID; - - ixEthDBReleaseHashNode(searchResult); - - return IX_ETH_DB_SUCCESS; -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING); - - ixEthDBPortInfo[portID].agingEnabled = FALSE; - - return IX_ETH_DB_SUCCESS; -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING); - - ixEthDBPortInfo[portID].agingEnabled = TRUE; - - return IX_ETH_DB_SUCCESS; -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) -{ - HashNode *searchResult; - MacDescriptor *descriptor; - - IX_ETH_DB_CHECK_REFERENCE(portID); - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); - - if (searchResult == NULL) - { - return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ - } - - descriptor = (MacDescriptor *) searchResult->data; - - /* return the port ID */ - *portID = descriptor->portID; - - /* reset entry age */ - if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) - { - descriptor->recordData.filteringData.age = 0; - } - else - { - descriptor->recordData.filteringVlanData.age = 0; - } - - ixEthDBReleaseHashNode(searchResult); - - return IX_ETH_DB_SUCCESS; -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING); - - /* force bit at offset 255 to 0 (reserved) */ - dependencyPortMap[31] &= 0xFE; - - COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap); - - return IX_ETH_DB_SUCCESS; -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING); - - COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap); - - return IX_ETH_DB_SUCCESS; -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING); - - ixEthDBPortInfo[portID].updateMethod.updateEnabled = enableUpdate; - ixEthDBPortInfo[portID].updateMethod.userControlled = TRUE; - - return IX_ETH_DB_SUCCESS; -} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c b/arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c deleted file mode 100644 index 36bc200..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBAPISupport.c +++ /dev/null @@ -1,675 +0,0 @@ -/** - * @file IxEthDBAPISupport.c - * - * @brief Public API support functions - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include -#include -#include - -#include "IxEthDB_p.h" -#include "IxEthDBMessages_p.h" -#include "IxEthDB_p.h" -#include "IxEthDBLog_p.h" - -#ifdef IX_UNIT_TEST - -int dbAccessCounter = 0; -int overflowEvent = 0; - -#endif - -/* - * External declaration - */ -extern HashTable dbHashtable; - -/* - * Internal declaration - */ -IX_ETH_DB_PUBLIC -PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS]; - -IX_ETH_DB_PRIVATE -struct -{ - BOOL saved; - IxEthDBPriorityTable priorityTable; - IxEthDBVlanSet vlanMembership; - IxEthDBVlanSet transmitTaggingInfo; - IxEthDBFrameFilter frameFilter; - IxEthDBTaggingAction taggingAction; - IxEthDBFirewallMode firewallMode; - BOOL stpBlocked; - BOOL srcAddressFilterEnabled; - UINT32 maxRxFrameSize; - UINT32 maxTxFrameSize; -} ixEthDBPortState[IX_ETH_DB_NUMBER_OF_PORTS]; - -#define IX_ETH_DB_DEFAULT_FRAME_SIZE (1518) - -/** - * @brief initializes a port - * - * @param portID ID of the port to be initialized - * - * Note that redundant initializations are silently - * dealt with and do not constitute an error - * - * This function is fully documented in the main - * header file, IxEthDB.h - */ -IX_ETH_DB_PUBLIC -void ixEthDBPortInit(IxEthDBPortId portID) -{ - PortInfo *portInfo; - - if (portID >= IX_ETH_DB_NUMBER_OF_PORTS) - { - return; - } - - portInfo = &ixEthDBPortInfo[portID]; - - if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS) - { - WARNING_LOG("EthDB: Unavailable Eth %d: Cannot initialize EthDB Port.\n", (UINT32) portID); - - return; - } - - if (portInfo->initialized) - { - /* redundant */ - return; - } - - /* initialize core fields */ - portInfo->portID = portID; - SET_DEPENDENCY_MAP(portInfo->dependencyPortMap, portID); - - /* default values */ - portInfo->agingEnabled = FALSE; - portInfo->enabled = FALSE; - portInfo->macAddressUploaded = FALSE; - portInfo->maxRxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE; - portInfo->maxTxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE; - - /* default update control values */ - portInfo->updateMethod.searchTree = NULL; - portInfo->updateMethod.searchTreePendingWrite = FALSE; - portInfo->updateMethod.treeInitialized = FALSE; - portInfo->updateMethod.updateEnabled = FALSE; - portInfo->updateMethod.userControlled = FALSE; - - /* default WiFi parameters */ - memset(portInfo->bbsid, 0, sizeof (portInfo->bbsid)); - portInfo->frameControlDurationID = 0; - - /* Ethernet NPE-specific initializations */ - if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) - { - /* update handler */ - portInfo->updateMethod.updateHandler = ixEthDBNPEUpdateHandler; - } - - /* initialize state save */ - ixEthDBPortState[portID].saved = FALSE; - - portInfo->initialized = TRUE; -} - -/** - * @brief enables a port - * - * @param portID ID of the port to enable - * - * This function is fully documented in the main - * header file, IxEthDB.h - * - * @return IX_ETH_DB_SUCCESS if enabling was - * accomplished, or a meaningful error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID) -{ - IxEthDBPortMap triggerPorts; - PortInfo *portInfo; - - IX_ETH_DB_CHECK_PORT_EXISTS(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - portInfo = &ixEthDBPortInfo[portID]; - - if (portInfo->enabled) - { - /* redundant */ - return IX_ETH_DB_SUCCESS; - } - - SET_DEPENDENCY_MAP(triggerPorts, portID); - - /* mark as enabled */ - portInfo->enabled = TRUE; - - /* Operation stops here when Ethernet Learning is not enabled */ - if(IX_FEATURE_CTRL_SWCONFIG_DISABLED == - ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) - { - return IX_ETH_DB_SUCCESS; - } - - if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE && !portInfo->macAddressUploaded) - { - IX_ETH_DB_SUPPORT_TRACE("DB: (Support) MAC address not set on port %d, enable failed\n", portID); - - /* must use UnicastAddressSet() before enabling an NPE port */ - return IX_ETH_DB_MAC_UNINITIALIZED; - } - - if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) - { - IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Attempting to enable the NPE callback for port %d...\n", portID); - - if (!portInfo->updateMethod.userControlled - && ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0)) - { - portInfo->updateMethod.updateEnabled = TRUE; - } - - /* if this is first time initialization then we already have - write access to the tree and can AccessRelease directly */ - if (!portInfo->updateMethod.treeInitialized) - { - IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Initializing tree for port %d\n", portID); - - /* create an initial tree and release access into it */ - ixEthDBUpdatePortLearningTrees(triggerPorts); - - /* mark tree as being initialized */ - portInfo->updateMethod.treeInitialized = TRUE; - } - } - - if (ixEthDBPortState[portID].saved) - { - /* previous configuration data stored, restore state */ - if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0) - { - ixEthDBFirewallModeSet(portID, ixEthDBPortState[portID].firewallMode); - ixEthDBFirewallInvalidAddressFilterEnable(portID, ixEthDBPortState[portID].srcAddressFilterEnabled); - } - -#if 0 /* test-only */ - if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) - { - ixEthDBAcceptableFrameTypeSet(portID, ixEthDBPortState[portID].frameFilter); - ixEthDBIngressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].taggingAction); - - ixEthDBEgressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].transmitTaggingInfo); - ixEthDBPortVlanMembershipSet(portID, ixEthDBPortState[portID].vlanMembership); - - ixEthDBPriorityMappingTableSet(portID, ixEthDBPortState[portID].priorityTable); - } -#endif - - if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) - { - ixEthDBSpanningTreeBlockingStateSet(portID, ixEthDBPortState[portID].stpBlocked); - } - - ixEthDBFilteringPortMaximumRxFrameSizeSet(portID, ixEthDBPortState[portID].maxRxFrameSize); - ixEthDBFilteringPortMaximumTxFrameSizeSet(portID, ixEthDBPortState[portID].maxTxFrameSize); - - /* discard previous save */ - ixEthDBPortState[portID].saved = FALSE; - } - - IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Enabling succeeded for port %d\n", portID); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief disables a port - * - * @param portID ID of the port to disable - * - * This function is fully documented in the - * main header file, IxEthDB.h - * - * @return IX_ETH_DB_SUCCESS if disabling was - * successful or an appropriate error message - * otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID) -{ - HashIterator iterator; - IxEthDBPortMap triggerPorts; /* ports who will have deleted records and therefore will need updating */ - BOOL result; - PortInfo *portInfo; - IxEthDBFeature learningEnabled; -#if 0 /* test-only */ - IxEthDBPriorityTable classZeroTable; -#endif - - IX_ETH_DB_CHECK_PORT_EXISTS(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - portInfo = &ixEthDBPortInfo[portID]; - - if (!portInfo->enabled) - { - /* redundant */ - return IX_ETH_DB_SUCCESS; - } - - if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) - { - /* save filtering state */ - ixEthDBPortState[portID].firewallMode = portInfo->firewallMode; - ixEthDBPortState[portID].frameFilter = portInfo->frameFilter; - ixEthDBPortState[portID].taggingAction = portInfo->taggingAction; - ixEthDBPortState[portID].stpBlocked = portInfo->stpBlocked; - ixEthDBPortState[portID].srcAddressFilterEnabled = portInfo->srcAddressFilterEnabled; - ixEthDBPortState[portID].maxRxFrameSize = portInfo->maxRxFrameSize; - ixEthDBPortState[portID].maxTxFrameSize = portInfo->maxTxFrameSize; - - memcpy(ixEthDBPortState[portID].vlanMembership, portInfo->vlanMembership, sizeof (IxEthDBVlanSet)); - memcpy(ixEthDBPortState[portID].transmitTaggingInfo, portInfo->transmitTaggingInfo, sizeof (IxEthDBVlanSet)); - memcpy(ixEthDBPortState[portID].priorityTable, portInfo->priorityTable, sizeof (IxEthDBPriorityTable)); - - ixEthDBPortState[portID].saved = TRUE; - - /* now turn off all EthDB filtering features on the port */ - -#if 0 /* test-only */ - /* VLAN & QoS */ - if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) - { - ixEthDBPortVlanMembershipRangeAdd((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID); - ixEthDBEgressVlanRangeTaggingEnabledSet((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID, FALSE); - ixEthDBAcceptableFrameTypeSet((IxEthDBPortId) portID, IX_ETH_DB_ACCEPT_ALL_FRAMES); - ixEthDBIngressVlanTaggingEnabledSet((IxEthDBPortId) portID, IX_ETH_DB_PASS_THROUGH); - - memset(classZeroTable, 0, sizeof (classZeroTable)); - ixEthDBPriorityMappingTableSet((IxEthDBPortId) portID, classZeroTable); - } -#endif - - /* STP */ - if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) - { - ixEthDBSpanningTreeBlockingStateSet((IxEthDBPortId) portID, FALSE); - } - - /* Firewall */ - if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0) - { - ixEthDBFirewallModeSet((IxEthDBPortId) portID, IX_ETH_DB_FIREWALL_BLACK_LIST); - ixEthDBFirewallTableDownload((IxEthDBPortId) portID); - ixEthDBFirewallInvalidAddressFilterEnable((IxEthDBPortId) portID, FALSE); - } - - /* Frame size filter */ - ixEthDBFilteringPortMaximumFrameSizeSet((IxEthDBPortId) portID, IX_ETH_DB_DEFAULT_FRAME_SIZE); - - /* WiFi */ - if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) - { - ixEthDBWiFiConversionTableDownload((IxEthDBPortId) portID); - } - - /* save and disable the learning feature bit */ - learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING; - portInfo->featureStatus &= ~IX_ETH_DB_LEARNING; - } - else - { - /* save the learning feature bit */ - learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING; - } - - SET_EMPTY_DEPENDENCY_MAP(triggerPorts); - - ixEthDBUpdateLock(); - - /* wipe out current entries for this port */ - BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); - - while (IS_ITERATOR_VALID(&iterator)) - { - MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; - - /* check if the port match. If so, remove the entry */ - if (descriptor->portID == portID - && (descriptor->type == IX_ETH_DB_FILTERING_RECORD || descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) - && !descriptor->recordData.filteringData.staticEntry) - { - /* delete entry */ - BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator)); - - /* add port to the set of update trigger ports */ - JOIN_PORT_TO_MAP(triggerPorts, portID); - } - else - { - /* move to the next record */ - BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); - } - } - - if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) - { - if (portInfo->updateMethod.searchTree != NULL) - { - ixEthDBFreeMacTreeNode(portInfo->updateMethod.searchTree); - portInfo->updateMethod.searchTree = NULL; - } - - ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FILTERING_RECORD); - } - - /* mark as disabled */ - portInfo->enabled = FALSE; - - /* disable updates unless the user has specifically altered the default behavior */ - if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) - { - if (!portInfo->updateMethod.userControlled) - { - portInfo->updateMethod.updateEnabled = FALSE; - } - - /* make sure we re-initialize the NPE learning tree when the port is re-enabled */ - portInfo->updateMethod.treeInitialized = FALSE; - } - - ixEthDBUpdateUnlock(); - - /* restore learning feature bit */ - portInfo->featureStatus |= learningEnabled; - - /* if we've removed any records or lost any events make sure to force an update */ - IS_EMPTY_DEPENDENCY_MAP(result, triggerPorts); - - if (!result) - { - ixEthDBUpdatePortLearningTrees(triggerPorts); - } - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief sends the updated maximum Tx/Rx frame lengths to the NPE - * - * @param portID ID of the port to update - * - * @return IX_ETH_DB_SUCCESS if the update completed - * successfully or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBPortFrameLengthsUpdate(IxEthDBPortId portID) -{ - IxNpeMhMessage message; - PortInfo *portInfo = &ixEthDBPortInfo[portID]; - IX_STATUS result; - - FILL_SETMAXFRAMELENGTHS_MSG(message, portID, portInfo->maxRxFrameSize, portInfo->maxTxFrameSize); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief sets the port maximum Rx frame size - * - * @param portID ID of the port to set the frame size on - * @param maximumRxFrameSize maximum Rx frame size - * - * This function updates the internal data structures and - * calls ixEthDBPortFrameLengthsUpdate() for NPE update. - * - * This function is fully documented in the main header - * file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation was - * successfull or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize) -{ - IX_ETH_DB_CHECK_PORT_EXISTS(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - if (!ixEthDBPortInfo[portID].initialized) - { - return IX_ETH_DB_PORT_UNINITIALIZED; - } - - if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) - { - if ((maximumRxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) || - (maximumRxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE)) - { - return IX_ETH_DB_INVALID_ARG; - } - } - else - { - return IX_ETH_DB_NO_PERMISSION; - } - - /* update internal structure */ - ixEthDBPortInfo[portID].maxRxFrameSize = maximumRxFrameSize; - - /* update the maximum frame size in the NPE */ - return ixEthDBPortFrameLengthsUpdate(portID); -} - -/** - * @brief sets the port maximum Tx frame size - * - * @param portID ID of the port to set the frame size on - * @param maximumTxFrameSize maximum Tx frame size - * - * This function updates the internal data structures and - * calls ixEthDBPortFrameLengthsUpdate() for NPE update. - * - * This function is fully documented in the main header - * file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation was - * successfull or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize) -{ - IX_ETH_DB_CHECK_PORT_EXISTS(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - if (!ixEthDBPortInfo[portID].initialized) - { - return IX_ETH_DB_PORT_UNINITIALIZED; - } - - if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) - { - if ((maximumTxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) || - (maximumTxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE)) - { - return IX_ETH_DB_INVALID_ARG; - } - } - else - { - return IX_ETH_DB_NO_PERMISSION; - } - - /* update internal structure */ - ixEthDBPortInfo[portID].maxTxFrameSize = maximumTxFrameSize; - - /* update the maximum frame size in the NPE */ - return ixEthDBPortFrameLengthsUpdate(portID); -} - -/** - * @brief sets the port maximum Tx and Rx frame sizes - * - * @param portID ID of the port to set the frame size on - * @param maximumFrameSize maximum Tx and Rx frame sizes - * - * This function updates the internal data structures and - * calls ixEthDBPortFrameLengthsUpdate() for NPE update. - * - * Note that both the maximum Tx and Rx frame size are set - * to the same value. This function is kept for compatibility - * reasons. - * - * This function is fully documented in the main header - * file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation was - * successfull or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize) -{ - IX_ETH_DB_CHECK_PORT_EXISTS(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - if (!ixEthDBPortInfo[portID].initialized) - { - return IX_ETH_DB_PORT_UNINITIALIZED; - } - - if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) - { - if ((maximumFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) || - (maximumFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE)) - { - return IX_ETH_DB_INVALID_ARG; - } - } - else - { - return IX_ETH_DB_NO_PERMISSION; - } - - /* update internal structure */ - ixEthDBPortInfo[portID].maxRxFrameSize = maximumFrameSize; - ixEthDBPortInfo[portID].maxTxFrameSize = maximumFrameSize; - - /* update the maximum frame size in the NPE */ - return ixEthDBPortFrameLengthsUpdate(portID); -} - -/** - * @brief sets the MAC address of an NPE port - * - * @param portID port ID to set the MAC address on - * @param macAddr pointer to the 6-byte MAC address - * - * This function is called by the EthAcc - * ixEthAccUnicastMacAddressSet() and should not be - * manually invoked unless required by special circumstances. - * - * @return IX_ETH_DB_SUCCESS if the operation succeeded - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) -{ - IxNpeMhMessage message; - IX_STATUS result; - - /* use this macro instead CHECK_PORT - as the port doesn't need to be enabled */ - IX_ETH_DB_CHECK_PORT_EXISTS(portID); - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - if (!ixEthDBPortInfo[portID].initialized) - { - return IX_ETH_DB_PORT_UNINITIALIZED; - } - - /* Operation stops here when Ethernet Learning is not enabled */ - if(IX_FEATURE_CTRL_SWCONFIG_DISABLED == - ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) - { - return IX_ETH_DB_SUCCESS; - } - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - /* exit if the port is not an Ethernet NPE */ - if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE) - { - return IX_ETH_DB_INVALID_PORT; - } - - /* populate message */ - FILL_SETPORTADDRESS_MSG(message, portID, macAddr->macAddress); - - IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Sending SetPortAddress on port %d...\n", portID); - - /* send a SetPortAddress message */ - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - if (result == IX_SUCCESS) - { - ixEthDBPortInfo[portID].macAddressUploaded = TRUE; - } - - return result; -} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBCore.c b/arch/arm/cpu/ixp/npe/IxEthDBCore.c deleted file mode 100644 index 25b7cbb..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBCore.c +++ /dev/null @@ -1,463 +0,0 @@ -/** - * @file IxEthDBDBCore.c - * - * @brief Database support functions - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxEthDB_p.h" - -/* list of database hashtables */ -IX_ETH_DB_PUBLIC HashTable dbHashtable; -IX_ETH_DB_PUBLIC MatchFunction matchFunctions[IX_ETH_DB_MAX_KEY_INDEX + 1]; -IX_ETH_DB_PUBLIC BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1]; -IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyType[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1]; - -/* private initialization flag */ -IX_ETH_DB_PRIVATE BOOL ethDBInitializationComplete = FALSE; - -/** - * @brief initializes EthDB - * - * This function must be called to initialize the component. - * - * It does the following things: - * - checks the port definition structure - * - scans the capabilities of the NPE images and sets the - * capabilities of the ports accordingly - * - initializes the memory pools internally used in EthDB - * for storing database records and handling data - * - registers automatic update handlers for add and remove - * operations - * - registers hashing match functions, depending on key sets - * - initializes the main database hashtable - * - allocates contiguous memory zones to be used for NPE - * updates - * - registers the serialize methods used to convert data - * into NPE-readable format - * - starts the event processor - * - * Note that this function is documented in the public - * component header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS or an appropriate error if the - * component failed to initialize correctly - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBInit(void) -{ - IxEthDBStatus result; - - if (ethDBInitializationComplete) - { - /* redundant */ - return IX_ETH_DB_SUCCESS; - } - - /* trap an invalid port definition structure */ - IX_ETH_DB_PORTS_ASSERTION; - - /* memory management */ - ixEthDBInitMemoryPools(); - - /* register hashing search methods */ - ixEthDBMatchMethodsRegister(matchFunctions); - - /* register type-based automatic port updates */ - ixEthDBUpdateTypeRegister(ixEthDBPortUpdateRequired); - - /* register record to key type mappings */ - ixEthDBKeyTypeRegister(ixEthDBKeyType); - - /* hash table */ - ixEthDBInitHash(&dbHashtable, NUM_BUCKETS, ixEthDBEntryXORHash, matchFunctions, (FreeFunction) ixEthDBFreeMacDescriptor); - - /* NPE update zones */ - ixEthDBNPEUpdateAreasInit(); - - /* register record serialization methods */ - ixEthDBRecordSerializeMethodsRegister(); - - /* start the event processor */ - result = ixEthDBEventProcessorInit(); - - /* scan NPE features */ - if (result == IX_ETH_DB_SUCCESS) - { - ixEthDBFeatureCapabilityScan(); - } - - ethDBInitializationComplete = TRUE; - - return result; -} - -/** - * @brief prepares EthDB for unloading - * - * This function must be called before removing the - * EthDB component from memory (e.g. doing rmmod in - * Linux) if the component is to be re-initialized again - * without rebooting the platform. - * - * All the EthDB ports must be disabled before this - * function is to be called. Failure to disable all - * the ports will return the IX_ETH_DB_BUSY error. - * - * This function will destroy mutexes, deallocate - * memory and stop the event processor. - * - * Note that this function is fully documented in the - * main component header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if de-initialization - * completed successfully or an appropriate error - * message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUnload(void) -{ - IxEthDBPortId portIndex; - - if (!ethDBInitializationComplete) - { - /* redundant */ - return IX_ETH_DB_SUCCESS; - } - - /* check if any ports are enabled */ - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - if (ixEthDBPortInfo[portIndex].enabled) - { - return IX_ETH_DB_BUSY; - } - } - - /* free port resources */ - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) - { - ixOsalMutexDestroy(&ixEthDBPortInfo[portIndex].npeAckLock); - } - - ixEthDBPortInfo[portIndex].initialized = FALSE; - } - - /* shutdown event processor */ - ixEthDBStopLearningFunction(); - - /* deallocate NPE update zones */ - ixEthDBNPEUpdateAreasUnload(); - - ethDBInitializationComplete = FALSE; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief adds a new entry to the Ethernet database - * - * @param newRecordTemplate address of the record template to use - * @param updateTrigger port map containing the update triggers - * resulting from this update operation - * - * Creates a new database entry, populates it with the data - * copied from the given template and adds the record to the - * database hash table. - * It also checks whether the new record type is registered to trigger - * automatic updates; if it is, the update trigger will contain the - * port on which the record insertion was performed, as well as the - * old port in case the addition was a record migration (from one port - * to the other). The caller can use the updateTrigger to trigger - * automatic updates on the ports changed as a result of this addition. - * - * @retval IX_ETH_DB_SUCCESS addition successful - * @retval IX_ETH_DB_NOMEM insertion failed, no memory left in the mac descriptor memory pool - * @retval IX_ETH_DB_BUSY database busy, cannot insert due to locking - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger) -{ - IxEthDBStatus result; - MacDescriptor *newDescriptor; - IxEthDBPortId originalPortID; - HashNode *node = NULL; - - BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, ixEthDBKeyType[newRecordTemplate->type], newRecordTemplate, &node)); - - TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; - - if (node == NULL) - { - /* not found, create a new one */ - newDescriptor = ixEthDBAllocMacDescriptor(); - - if (newDescriptor == NULL) - { - return IX_ETH_DB_NOMEM; /* no memory */ - } - - /* old port does not exist, avoid unnecessary updates */ - originalPortID = newRecordTemplate->portID; - } - else - { - /* a node with the same key exists, will update node */ - newDescriptor = (MacDescriptor *) node->data; - - /* save original port id */ - originalPortID = newDescriptor->portID; - } - - /* copy/update fields into new record */ - memcpy(newDescriptor->macAddress, newRecordTemplate->macAddress, sizeof (IxEthDBMacAddr)); - memcpy(&newDescriptor->recordData, &newRecordTemplate->recordData, sizeof (IxEthDBRecordData)); - - newDescriptor->type = newRecordTemplate->type; - newDescriptor->portID = newRecordTemplate->portID; - newDescriptor->user = newRecordTemplate->user; - - if (node == NULL) - { - /* new record, insert into hashtable */ - BUSY_RETRY_WITH_RESULT(ixEthDBAddHashEntry(&dbHashtable, newDescriptor), result); - - if (result != IX_ETH_DB_SUCCESS) - { - ixEthDBFreeMacDescriptor(newDescriptor); - - return result; /* insertion failed */ - } - } - - if (node != NULL) - { - /* release access */ - ixEthDBReleaseHashNode(node); - } - - /* trigger add/remove update if required by type */ - if (updateTrigger != NULL && - ixEthDBPortUpdateRequired[newRecordTemplate->type]) - { - /* add new port to update list */ - JOIN_PORT_TO_MAP(updateTrigger, newRecordTemplate->portID); - - /* check if record has moved, we'll need to update the old port as well */ - if (originalPortID != newDescriptor->portID) - { - JOIN_PORT_TO_MAP(updateTrigger, originalPortID); - } - } - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief remove a record from the Ethernet database - * - * @param templateRecord template record used to determine - * what record is to be removed - * @param updateTrigger port map containing the update triggers - * resulting from this update operation - * - * This function will examine the template record it receives - * and attempts to delete a record of the same type and containing - * the same keys as the template record. If deletion is successful - * and the record type is registered for automatic port updates the - * port will also be set in the updateTrigger port map, so that the - * client can perform an update of the port. - * - * @retval IX_ETH_DB_SUCCESS removal was successful - * @retval IX_ETH_DB_NO_SUCH_ADDR the record with the given MAC address was not found - * @retval IX_ETH_DB_BUSY database busy, cannot remove due to locking - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger) -{ - IxEthDBStatus result; - - TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; - - BUSY_RETRY_WITH_RESULT(ixEthDBRemoveHashEntry(&dbHashtable, ixEthDBKeyType[templateRecord->type], templateRecord), result); - - if (result != IX_ETH_DB_SUCCESS) - { - return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ - } - - /* trigger add/remove update if required by type */ - if (updateTrigger != NULL - &&ixEthDBPortUpdateRequired[templateRecord->type]) - { - /* add new port to update list */ - JOIN_PORT_TO_MAP(updateTrigger, templateRecord->portID); - } - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief register record key types - * - * This function registers the appropriate key types, - * depending on record types. - * - * All filtering records use the MAC address as the key. - * WiFi and Firewall records use a compound key consisting - * in both the MAC address and the port ID. - * - * @return the number of registered record types - */ -IX_ETH_DB_PUBLIC -UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType) -{ - /* safety */ - memset(keyType, 0, sizeof (keyType)); - - /* register all known record types */ - keyType[IX_ETH_DB_FILTERING_RECORD] = IX_ETH_DB_MAC_KEY; - keyType[IX_ETH_DB_FILTERING_VLAN_RECORD] = IX_ETH_DB_MAC_KEY; - keyType[IX_ETH_DB_ALL_FILTERING_RECORDS] = IX_ETH_DB_MAC_KEY; - keyType[IX_ETH_DB_WIFI_RECORD] = IX_ETH_DB_MAC_PORT_KEY; - keyType[IX_ETH_DB_FIREWALL_RECORD] = IX_ETH_DB_MAC_PORT_KEY; - - return 5; -} - -/** - * @brief Sets a user-defined field into a database record - * - * Note that this function is fully documented in the main component - * header file. - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field) -{ - HashNode *result = NULL; - - if (macAddr == NULL) - { - return IX_ETH_DB_INVALID_ARG; - } - - if (recordType == IX_ETH_DB_FILTERING_RECORD) - { - result = ixEthDBSearch(macAddr, recordType); - } - else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD) - { - result = ixEthDBVlanSearch(macAddr, vlanID, recordType); - } - else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD) - { - IX_ETH_DB_CHECK_PORT_EXISTS(portID); - - result = ixEthDBPortSearch(macAddr, portID, recordType); - } - else - { - return IX_ETH_DB_INVALID_ARG; - } - - if (result == NULL) - { - return IX_ETH_DB_NO_SUCH_ADDR; - } - - ((MacDescriptor *) result->data)->user = field; - - ixEthDBReleaseHashNode(result); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief Retrieves a user-defined field from a database record - * - * Note that this function is fully documented in the main component - * header file. - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field) -{ - HashNode *result = NULL; - - if (macAddr == NULL || field == NULL) - { - return IX_ETH_DB_INVALID_ARG; - } - - if (recordType == IX_ETH_DB_FILTERING_RECORD) - { - result = ixEthDBSearch(macAddr, recordType); - } - else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD) - { - result = ixEthDBVlanSearch(macAddr, vlanID, recordType); - } - else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD) - { - IX_ETH_DB_CHECK_PORT_EXISTS(portID); - - result = ixEthDBPortSearch(macAddr, portID, recordType); - } - else - { - return IX_ETH_DB_INVALID_ARG; - } - - if (result == NULL) - { - return IX_ETH_DB_NO_SUCH_ADDR; - } - - *field = ((MacDescriptor *) result->data)->user; - - ixEthDBReleaseHashNode(result); - - return IX_ETH_DB_SUCCESS; -} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBEvents.c b/arch/arm/cpu/ixp/npe/IxEthDBEvents.c deleted file mode 100644 index 4d44e03..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBEvents.c +++ /dev/null @@ -1,520 +0,0 @@ -/** - * @file IxEthDBEvents.c - * - * @brief Implementation of the event processor component - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include -#include - -#include "IxEthDB_p.h" - -/* forward prototype declarations */ -IX_ETH_DB_PUBLIC void ixEthDBEventProcessorLoop(void *); -IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); -IX_ETH_DB_PRIVATE void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts); -IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void); - -/* data */ -IX_ETH_DB_PRIVATE IxOsalSemaphore eventQueueSemaphore; -IX_ETH_DB_PRIVATE PortEventQueue eventQueue; -IX_ETH_DB_PRIVATE IxOsalMutex eventQueueLock; -IX_ETH_DB_PRIVATE IxOsalMutex portUpdateLock; - -IX_ETH_DB_PRIVATE BOOL ixEthDBLearningShutdown = FALSE; -IX_ETH_DB_PRIVATE BOOL ixEthDBEventProcessorRunning = FALSE; - -/* imported data */ -extern HashTable dbHashtable; - -/** - * @brief initializes the event processor - * - * Initializes the event processor queue and processing thread. - * Called from ixEthDBInit() DB-subcomponent master init function. - * - * @warning do not call directly - * - * @retval IX_ETH_DB_SUCCESS initialization was successful - * @retval IX_ETH_DB_FAIL initialization failed (OSAL or mutex init failure) - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEventProcessorInit(void) -{ - if (ixOsalMutexInit(&portUpdateLock) != IX_SUCCESS) - { - return IX_ETH_DB_FAIL; - } - - if (ixOsalMutexInit(&eventQueueLock) != IX_SUCCESS) - { - return IX_ETH_DB_FAIL; - } - - if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == - ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING)) - { - - /* start processor loop thread */ - if (ixEthDBStartLearningFunction() != IX_ETH_DB_SUCCESS) - { - return IX_ETH_DB_FAIL; - } - } - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief initializes the event queue and the event processor - * - * This function is called by the component initialization - * function, ixEthDBInit(). - * - * @warning do not call directly - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or IX_ETH_DB_FAIL otherwise - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBStartLearningFunction(void) -{ - IxOsalThread eventProcessorThread; - IxOsalThreadAttr threadAttr; - - threadAttr.name = "EthDB event thread"; - threadAttr.stackSize = 32 * 1024; /* 32kbytes */ - threadAttr.priority = 128; - - /* reset event queue */ - ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); - - RESET_QUEUE(&eventQueue); - - ixOsalMutexUnlock(&eventQueueLock); - - /* init event queue semaphore */ - if (ixOsalSemaphoreInit(&eventQueueSemaphore, 0) != IX_SUCCESS) - { - return IX_ETH_DB_FAIL; - } - - ixEthDBLearningShutdown = FALSE; - - /* create processor loop thread */ - if (ixOsalThreadCreate(&eventProcessorThread, &threadAttr, ixEthDBEventProcessorLoop, NULL) != IX_SUCCESS) - { - return IX_ETH_DB_FAIL; - } - - /* start event processor */ - ixOsalThreadStart(&eventProcessorThread); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief stops the event processor - * - * Stops the event processor and frees the event queue semaphore - * Called by the component de-initialization function, ixEthDBUnload() - * - * @warning do not call directly - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or IX_ETH_DB_FAIL otherwise; - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBStopLearningFunction(void) -{ - ixEthDBLearningShutdown = TRUE; - - /* wake up event processing loop to actually process the shutdown event */ - ixOsalSemaphorePost(&eventQueueSemaphore); - - if (ixOsalSemaphoreDestroy(&eventQueueSemaphore) != IX_SUCCESS) - { - return IX_ETH_DB_FAIL; - } - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief default NPE event processing callback - * - * @param npeID ID of the NPE that generated the event - * @param msg NPE message (encapsulated event) - * - * Creates an event object on the Ethernet event processor queue - * and signals the new event by incrementing the event queue semaphore. - * Events are processed by @ref ixEthDBEventProcessorLoop() which runs - * at user level. - * - * @see ixEthDBEventProcessorLoop() - * - * @warning do not call directly - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg) -{ - PortEvent *local_event; - - IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) new event received by processor callback from port %d, id 0x%X\n", IX_ETH_DB_NPE_TO_PORT_ID(npeID), NPE_MSG_ID(msg), 0, 0, 0, 0); - - if (CAN_ENQUEUE(&eventQueue)) - { - TEST_FIXTURE_LOCK_EVENT_QUEUE; - - local_event = QUEUE_HEAD(&eventQueue); - - /* create event structure on queue */ - local_event->eventType = NPE_MSG_ID(msg); - local_event->portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID); - - /* update queue */ - PUSH_UPDATE_QUEUE(&eventQueue); - - TEST_FIXTURE_UNLOCK_EVENT_QUEUE; - - IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Waking up main processor loop...\n", 0, 0, 0, 0, 0, 0); - - /* increment event queue semaphore */ - ixOsalSemaphorePost(&eventQueueSemaphore); - } - else - { - IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Warning: could not enqueue event (overflow)\n", 0, 0, 0, 0, 0, 0); - } -} - -/** - * @brief Ethernet event processor loop - * - * Extracts at most EVENT_PROCESSING_LIMIT batches of events and - * sends them for processing to @ref ixEthDBProcessEvent(). - * Triggers port updates which normally follow learning events. - * - * @warning do not call directly, executes in separate thread - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBEventProcessorLoop(void *unused1) -{ - IxEthDBPortMap triggerPorts; - IxEthDBPortId portIndex; - - ixEthDBEventProcessorRunning = TRUE; - - IX_ETH_DB_EVENTS_TRACE("DB: (Events) Event processor loop was started\n"); - - while (!ixEthDBLearningShutdown) - { - BOOL keepProcessing = TRUE; - UINT32 processedEvents = 0; - - IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Waiting for new learning event...\n"); - - ixOsalSemaphoreWait(&eventQueueSemaphore, IX_OSAL_WAIT_FOREVER); - - IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Received new event\n"); - - if (!ixEthDBLearningShutdown) - { - /* port update handling */ - SET_EMPTY_DEPENDENCY_MAP(triggerPorts); - - while (keepProcessing) - { - PortEvent local_event; - UINT32 intLockKey; - - /* lock queue */ - ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); - - /* lock NPE interrupts */ - intLockKey = ixOsalIrqLock(); - - /* extract event */ - local_event = *(QUEUE_TAIL(&eventQueue)); - - SHIFT_UPDATE_QUEUE(&eventQueue); - - ixOsalIrqUnlock(intLockKey); - - ixOsalMutexUnlock(&eventQueueLock); - - IX_ETH_DB_EVENTS_TRACE("DB: (Events) Processing event with ID 0x%X\n", local_event.eventType); - - ixEthDBProcessEvent(&local_event, triggerPorts); - - processedEvents++; - - if (processedEvents > EVENT_PROCESSING_LIMIT /* maximum burst reached? */ - || ixOsalSemaphoreTryWait(&eventQueueSemaphore) != IX_SUCCESS) /* or empty queue? */ - { - keepProcessing = FALSE; - } - } - - ixEthDBUpdatePortLearningTrees(triggerPorts); - } - } - - /* turn off automatic updates */ - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = FALSE; - } - - ixEthDBEventProcessorRunning = FALSE; -} - -/** - * @brief event processor routine - * - * @param event event to be processed - * @param triggerPorts port map accumulating ports to be updated - * - * Processes learning events by synchronizing the database with - * newly learnt data. Called only by @ref ixEthDBEventProcessorLoop(). - * - * @warning do not call directly - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts) -{ - MacDescriptor recordTemplate; - - switch (local_event->eventType) - { - case IX_ETH_DB_ADD_FILTERING_RECORD: - /* add record */ - memset(&recordTemplate, 0, sizeof (recordTemplate)); - memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr)); - - recordTemplate.type = IX_ETH_DB_FILTERING_RECORD; - recordTemplate.portID = local_event->portID; - recordTemplate.recordData.filteringData.staticEntry = local_event->staticEntry; - - ixEthDBAdd(&recordTemplate, triggerPorts); - - IX_ETH_DB_EVENTS_TRACE("DB: (Events) Added record on port %d\n", local_event->portID); - - break; - - case IX_ETH_DB_REMOVE_FILTERING_RECORD: - /* remove record */ - memset(&recordTemplate, 0, sizeof (recordTemplate)); - memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr)); - - recordTemplate.type = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD; - - ixEthDBRemove(&recordTemplate, triggerPorts); - - IX_ETH_DB_EVENTS_TRACE("DB: (Events) Removed record on port %d\n", local_event->portID); - - break; - - default: - /* can't handle/not interested in this event type */ - ERROR_LOG("DB: (Events) Event processor received an unknown event type (0x%X)\n", local_event->eventType); - - return; - } -} - -/** - * @brief asynchronously adds a filtering record - * by posting an ADD_FILTERING_RECORD event to the event queue - * - * @param macAddr MAC address of the new record - * @param portID port ID of the new record - * @param staticEntry TRUE if record is static, FALSE if dynamic - * - * @return IX_ETH_DB_SUCCESS if the event creation was - * successfull or IX_ETH_DB_BUSY if the event queue is full - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry) -{ - MacDescriptor reference; - - TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; - - /* fill search fields */ - memcpy(reference.macAddress, macAddr, sizeof (IxEthDBMacAddr)); - reference.portID = portID; - - /* set acceptable record types */ - reference.type = IX_ETH_DB_ALL_FILTERING_RECORDS; - - if (ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference) == IX_ETH_DB_SUCCESS) - { - /* already have an identical record */ - return IX_ETH_DB_SUCCESS; - } - else - { - return ixEthDBTriggerPortUpdate(IX_ETH_DB_ADD_FILTERING_RECORD, macAddr, portID, staticEntry); - } -} - -/** - * @brief asynchronously removes a filtering record - * by posting a REMOVE_FILTERING_RECORD event to the event queue - * - * @param macAddr MAC address of the record to remove - * @param portID port ID of the record to remove - * - * @return IX_ETH_DB_SUCCESS if the event creation was - * successfull or IX_ETH_DB_BUSY if the event queue is full - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID) -{ - if (ixEthDBPeek(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS) != IX_ETH_DB_NO_SUCH_ADDR) - { - return ixEthDBTriggerPortUpdate(IX_ETH_DB_REMOVE_FILTERING_RECORD, macAddr, portID, FALSE); - } - else - { - return IX_ETH_DB_NO_SUCH_ADDR; - } -} - -/** - * @brief adds an ADD or REMOVE event to the main event queue - * - * @param eventType event type - IX_ETH_DB_ADD_FILTERING_RECORD - * to add and IX_ETH_DB_REMOVE_FILTERING_RECORD to remove a - * record. - * - * @return IX_ETH_DB_SUCCESS if the event was successfully - * sent or IX_ETH_DB_BUSY if the event queue is full - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry) -{ - UINT32 intLockKey; - - /* lock interrupts to protect queue */ - intLockKey = ixOsalIrqLock(); - - if (CAN_ENQUEUE(&eventQueue)) - { - PortEvent *queueEvent = QUEUE_HEAD(&eventQueue); - - /* update fields on the queue */ - memcpy(queueEvent->macAddr.macAddress, macAddr->macAddress, sizeof (IxEthDBMacAddr)); - - queueEvent->eventType = eventType; - queueEvent->portID = portID; - queueEvent->staticEntry = staticEntry; - - PUSH_UPDATE_QUEUE(&eventQueue); - - /* imcrement event queue semaphore */ - ixOsalSemaphorePost(&eventQueueSemaphore); - - /* unlock interrupts */ - ixOsalIrqUnlock(intLockKey); - - return IX_ETH_DB_SUCCESS; - } - else /* event queue full */ - { - /* unlock interrupts */ - ixOsalIrqUnlock(intLockKey); - - return IX_ETH_DB_BUSY; - } -} - -/** - * @brief Locks learning tree updates and port disable - * - * - * This function locks portUpdateLock single mutex. It is primarily used - * to avoid executing 'port disable' during ELT maintenance. - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBUpdateLock(void) -{ - ixOsalMutexLock(&portUpdateLock, IX_OSAL_WAIT_FOREVER); -} - -/** - * @brief Unlocks learning tree updates and port disable - * - * - * This function unlocks a portUpdateLock mutex. It is primarily used - * to avoid executing 'port disable' during ELT maintenance. - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBUpdateUnlock(void) -{ - ixOsalMutexUnlock(&portUpdateLock); -} - diff --git a/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c b/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c deleted file mode 100644 index 7a58d26..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBFeatures.c +++ /dev/null @@ -1,662 +0,0 @@ -/** - * @file IxEthDBFeatures.c - * - * @brief Implementation of the EthDB feature control API - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxNpeDl.h" -#include "IxEthDBQoS.h" -#include "IxEthDB_p.h" - -/** - * @brief scans the capabilities of the loaded NPE images - * - * This function MUST be called by the ixEthDBInit() function. - * No EthDB features (including learning and filtering) are enabled - * before this function is called. - * - * @return none - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBFeatureCapabilityScan(void) -{ - IxNpeDlImageId imageId, npeAImageId; - IxEthDBPortId portIndex; - PortInfo *portInfo; - IxEthDBPriorityTable defaultPriorityTable; - IX_STATUS result; - UINT32 queueIndex; - UINT32 queueStructureIndex; - UINT32 trafficClassDefinitionIndex; - - /* read version of NPE A - required to set the AQM queues for B and C */ - npeAImageId.functionalityId = 0; - ixNpeDlLoadedImageGet(IX_NPEDL_NPEID_NPEA, &npeAImageId); - - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - IxNpeMhMessage msg; - - portInfo = &ixEthDBPortInfo[portIndex]; - - /* check and bypass if NPE B or C is fused out */ - if (ixEthDBSingleEthNpeCheck(portIndex) != IX_ETH_DB_SUCCESS) continue; - - /* all ports are capable of LEARNING by default */ - portInfo->featureCapability |= IX_ETH_DB_LEARNING; - portInfo->featureStatus |= IX_ETH_DB_LEARNING; - - if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) - { - - if (ixNpeDlLoadedImageGet(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), &imageId) != IX_SUCCESS) - { - WARNING_LOG("DB: (FeatureScan) NpeDl did not provide the image ID for NPE port %d\n", portIndex); - } - else - { - /* initialize and empty NPE response mutex */ - ixOsalMutexInit(&portInfo->npeAckLock); - ixOsalMutexLock(&portInfo->npeAckLock, IX_OSAL_WAIT_FOREVER); - - /* check NPE response to GetStatus */ - msg.data[0] = IX_ETHNPE_NPE_GETSTATUS << 24; - msg.data[1] = 0; - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), msg, result); - if (result != IX_SUCCESS) - { - WARNING_LOG("DB: (FeatureScan) warning, could not send message to the NPE\n"); - continue; - } - - - if (imageId.functionalityId == 0x00 - || imageId.functionalityId == 0x03 - || imageId.functionalityId == 0x04 - || imageId.functionalityId == 0x80) - { - portInfo->featureCapability |= IX_ETH_DB_FILTERING; - portInfo->featureCapability |= IX_ETH_DB_FIREWALL; - portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; - } - else if (imageId.functionalityId == 0x01 - || imageId.functionalityId == 0x81) - { - portInfo->featureCapability |= IX_ETH_DB_FILTERING; - portInfo->featureCapability |= IX_ETH_DB_FIREWALL; - portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; - portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS; - } - else if (imageId.functionalityId == 0x02 - || imageId.functionalityId == 0x82) - { - portInfo->featureCapability |= IX_ETH_DB_WIFI_HEADER_CONVERSION; - portInfo->featureCapability |= IX_ETH_DB_FIREWALL; - portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; - portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS; - } - - /* reset AQM queues */ - memset(portInfo->ixEthDBTrafficClassAQMAssignments, 0, sizeof (portInfo->ixEthDBTrafficClassAQMAssignments)); - - /* ensure there's at least one traffic class record in the definition table, otherwise we have no default case, hence no queues */ - IX_ENSURE(sizeof (ixEthDBTrafficClassDefinitions) != 0, "DB: no traffic class definitions found, check IxEthDBQoS.h"); - - /* find the traffic class definition index compatible with the current NPE A functionality ID */ - for (trafficClassDefinitionIndex = 0 ; - trafficClassDefinitionIndex < sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]); - trafficClassDefinitionIndex++) - { - if (ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX] == npeAImageId.functionalityId) - { - /* found it */ - break; - } - } - - /* select the default case if we went over the array boundary */ - if (trafficClassDefinitionIndex == sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0])) - { - trafficClassDefinitionIndex = 0; /* the first record is the default case */ - } - - /* select queue assignment structure based on the traffic class configuration index */ - queueStructureIndex = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX]; - - /* only traffic class 0 is active at initialization time */ - portInfo->ixEthDBTrafficClassCount = 1; - - /* enable port, VLAN and Firewall feature bits to initialize QoS/VLAN/Firewall configuration */ - portInfo->featureStatus |= IX_ETH_DB_VLAN_QOS; - portInfo->featureStatus |= IX_ETH_DB_FIREWALL; - portInfo->enabled = TRUE; - -#define CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ -#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ - /* set VLAN initial configuration (permissive) */ - if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) /* QoS-enabled image */ - { - /* QoS capable */ - portInfo->ixEthDBTrafficClassAvailable = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX]; - - /* set AQM queues */ - for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++) - { - portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][queueIndex]; - } - - /* set default PVID (0) and default traffic class 0 */ - ixEthDBPortVlanTagSet(portIndex, 0); - - /* enable reception of all frames */ - ixEthDBAcceptableFrameTypeSet(portIndex, IX_ETH_DB_ACCEPT_ALL_FRAMES); - - /* clear full VLAN membership */ - ixEthDBPortVlanMembershipRangeRemove(portIndex, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID); - - /* clear TTI table - no VLAN tagged frames will be transmitted */ - ixEthDBEgressVlanRangeTaggingEnabledSet(portIndex, 0, 4094, FALSE); - - /* set membership on 0, otherwise no Tx or Rx is working */ - ixEthDBPortVlanMembershipAdd(portIndex, 0); - } - else /* QoS not available in this image */ -#endif /* test-only */ - { - /* initialize traffic class availability (only class 0 is available) */ - portInfo->ixEthDBTrafficClassAvailable = 1; - - /* point all AQM queues to traffic class 0 */ - for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++) - { - portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = - ixEthDBQueueAssignments[queueStructureIndex][0]; - } - } - -#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ - /* download priority mapping table and Rx queue configuration */ - memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable)); - ixEthDBPriorityMappingTableSet(portIndex, defaultPriorityTable); -#endif - - /* by default we turn off invalid source MAC address filtering */ - ixEthDBFirewallInvalidAddressFilterEnable(portIndex, FALSE); - - /* disable port, VLAN, Firewall feature bits */ - portInfo->featureStatus &= ~IX_ETH_DB_VLAN_QOS; - portInfo->featureStatus &= ~IX_ETH_DB_FIREWALL; - portInfo->enabled = FALSE; - - /* enable filtering by default if present */ - if ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0) - { - portInfo->featureStatus |= IX_ETH_DB_FILTERING; - } - } - } - } -} - -/** - * @brief returns the capability of a port - * - * @param portID ID of the port - * @param featureSet location to store the port capability in - * - * This function will save the capability set of the given port - * into the given location. Capabilities are bit-ORed, each representing - * a bit of the feature set. - * - * Note that this function is documented in the main component - * public header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or IX_ETH_DB_INVALID_PORT if the given port is invalid - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet) -{ - IX_ETH_DB_CHECK_PORT_INITIALIZED(portID); - - IX_ETH_DB_CHECK_REFERENCE(featureSet); - - *featureSet = ixEthDBPortInfo[portID].featureCapability; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief enables or disables a port capability - * - * @param portID ID of the port - * @param feature feature to enable or disable - * @param enabled TRUE to enable the selected feature or FALSE to disable it - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enable) -{ - PortInfo *portInfo; - IxEthDBPriorityTable defaultPriorityTable; - IxEthDBVlanSet vlanSet; - IxEthDBStatus status = IX_ETH_DB_SUCCESS; - BOOL portEnabled; - - IX_ETH_DB_CHECK_PORT_INITIALIZED(portID); - - portInfo = &ixEthDBPortInfo[portID]; - portEnabled = portInfo->enabled; - - /* check that only one feature is selected */ - if (!ixEthDBCheckSingleBitValue(feature)) - { - return IX_ETH_DB_FEATURE_UNAVAILABLE; - } - - /* port capable of this feature? */ - if ((portInfo->featureCapability & feature) == 0) - { - return IX_ETH_DB_FEATURE_UNAVAILABLE; - } - - /* mutual exclusion between learning and WiFi header conversion */ - if (enable && ((feature | portInfo->featureStatus) & (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION)) - == (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION)) - { - return IX_ETH_DB_NO_PERMISSION; - } - - /* learning must be enabled before filtering */ - if (enable && (feature == IX_ETH_DB_FILTERING) && ((portInfo->featureStatus & IX_ETH_DB_LEARNING) == 0)) - { - return IX_ETH_DB_NO_PERMISSION; - } - - /* filtering must be disabled before learning */ - if (!enable && (feature == IX_ETH_DB_LEARNING) && ((portInfo->featureStatus & IX_ETH_DB_FILTERING) != 0)) - { - return IX_ETH_DB_NO_PERMISSION; - } - - /* redundant enabling or disabling */ - if ((!enable && ((portInfo->featureStatus & feature) == 0)) - || (enable && ((portInfo->featureStatus & feature) != 0))) - { - /* do nothing */ - return IX_ETH_DB_SUCCESS; - } - - /* force port enabled */ - portInfo->enabled = TRUE; - - if (enable) - { - /* turn on enable bit */ - portInfo->featureStatus |= feature; - -#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ - /* if this is VLAN/QoS set the default priority table */ - if (feature == IX_ETH_DB_VLAN_QOS) - { - /* turn on VLAN/QoS (most permissive mode): - - set default 802.1Q priority mapping table, in accordance to the - availability of traffic classes - - set the acceptable frame filter to accept all - - set the Ingress tagging mode to pass-through - - set full VLAN membership list - - set full TTI table - - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0) - - enable TPID port extraction - */ - - portInfo->ixEthDBTrafficClassCount = portInfo->ixEthDBTrafficClassAvailable; - - /* set default 802.1Q priority mapping table - note that C indexing starts from 0, so we substract 1 here */ - memcpy (defaultPriorityTable, - (const void *) ixEthIEEE802_1QUserPriorityToTrafficClassMapping[portInfo->ixEthDBTrafficClassCount - 1], - sizeof (defaultPriorityTable)); - - /* update priority mapping and AQM queue assignments */ - status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable); - - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES); - } - - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH); - } - - /* set membership and TTI tables */ - memset (vlanSet, 0xFF, sizeof (vlanSet)); - - if (status == IX_ETH_DB_SUCCESS) - { - /* use the internal function to bypass PVID check */ - status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet); - } - - if (status == IX_ETH_DB_SUCCESS) - { - /* use the internal function to bypass PVID check */ - status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet); - } - - /* reset the PVID */ - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBPortVlanTagSet(portID, 0); - } - - /* enable TPID port extraction */ - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBVlanPortExtractionEnable(portID, TRUE); - } - } - else if (feature == IX_ETH_DB_FIREWALL) -#endif - { - /* firewall starts in black-list mode unless otherwise configured before * - * note that invalid source MAC address filtering is disabled by default */ - if (portInfo->firewallMode != IX_ETH_DB_FIREWALL_BLACK_LIST - && portInfo->firewallMode != IX_ETH_DB_FIREWALL_WHITE_LIST) - { - status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST); - - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE); - } - } - } - - if (status != IX_ETH_DB_SUCCESS) - { - /* checks failed, disable */ - portInfo->featureStatus &= ~feature; - } - } - else - { - /* turn off features */ - if (feature == IX_ETH_DB_FIREWALL) - { - /* turning off the firewall is equivalent to: - - set to black-list mode - - clear all the entries and download the new table - - turn off the invalid source address checking - */ - - status = ixEthDBDatabaseClear(portID, IX_ETH_DB_FIREWALL_RECORD); - - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST); - } - - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE); - } - - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBFirewallTableDownload(portID); - } - } - else if (feature == IX_ETH_DB_WIFI_HEADER_CONVERSION) - { - /* turn off header conversion */ - status = ixEthDBDatabaseClear(portID, IX_ETH_DB_WIFI_RECORD); - - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBWiFiConversionTableDownload(portID); - } - } -#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ - else if (feature == IX_ETH_DB_VLAN_QOS) - { - /* turn off VLAN/QoS: - - set a priority mapping table with one traffic class - - set the acceptable frame filter to accept all - - set the Ingress tagging mode to pass-through - - clear the VLAN membership list - - clear the TTI table - - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0) - - disable TPID port extraction - */ - - /* initialize all => traffic class 0 priority mapping table */ - memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable)); - portInfo->ixEthDBTrafficClassCount = 1; - status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable); - - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES); - } - - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH); - } - - /* clear membership and TTI tables */ - memset (vlanSet, 0, sizeof (vlanSet)); - - if (status == IX_ETH_DB_SUCCESS) - { - /* use the internal function to bypass PVID check */ - status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet); - } - - if (status == IX_ETH_DB_SUCCESS) - { - /* use the internal function to bypass PVID check */ - status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet); - } - - /* reset the PVID */ - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBPortVlanTagSet(portID, 0); - } - - /* disable TPID port extraction */ - if (status == IX_ETH_DB_SUCCESS) - { - status = ixEthDBVlanPortExtractionEnable(portID, FALSE); - } - } -#endif - - if (status == IX_ETH_DB_SUCCESS) - { - /* checks passed, disable */ - portInfo->featureStatus &= ~feature; - } - } - - /* restore port enabled state */ - portInfo->enabled = portEnabled; - - return status; -} - -/** - * @brief returns the status of a feature - * - * @param portID port ID - * @param present location to store a boolean value indicating - * if the feature is present (TRUE) or not (FALSE) - * @param enabled location to store a booleam value indicating - * if the feature is present (TRUE) or not (FALSE) - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled) -{ - PortInfo *portInfo; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_REFERENCE(present); - - IX_ETH_DB_CHECK_REFERENCE(enabled); - - portInfo = &ixEthDBPortInfo[portID]; - - *present = (portInfo->featureCapability & feature) != 0; - *enabled = (portInfo->featureStatus & feature) != 0; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief returns the value of an EthDB property - * - * @param portID ID of the port - * @param feature feature owning the property - * @param property ID of the property - * @param type location to store the property type into - * @param value location to store the property value into - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value) -{ - IX_ETH_DB_CHECK_PORT_EXISTS(portID); - - IX_ETH_DB_CHECK_REFERENCE(type); - - IX_ETH_DB_CHECK_REFERENCE(value); - - if (feature == IX_ETH_DB_VLAN_QOS) - { - if (property == IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY) - { - * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount; - *type = IX_ETH_DB_INTEGER_PROPERTY; - - return IX_ETH_DB_SUCCESS; - } - else if (property >= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY - && property <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY) - { - UINT32 classDelta = property - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; - - if (classDelta >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) - { - return IX_ETH_DB_FAIL; - } - - * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[classDelta]; - *type = IX_ETH_DB_INTEGER_PROPERTY; - - return IX_ETH_DB_SUCCESS; - } - } - - return IX_ETH_DB_INVALID_ARG; -} - -/** - * @brief sets the value of an EthDB property - * - * @param portID ID of the port - * @param feature feature owning the property - * @param property ID of the property - * @param value location containing the property value - * - * This function implements a private property intended - * only for EthAcc usage. Upon setting the IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE - * property (the value is ignored), the availability of traffic classes is - * frozen to whatever traffic class structure is currently in use. - * This means that if VLAN_QOS has been enabled before EthAcc - * initialization then all the defined traffic classes will be available; - * otherwise only one traffic class (0) will be available. - * - * Note that this function is documented in the main component - * header file, IxEthDB.h as not accepting any parameters. The - * current implementation is only intended for the private use of EthAcc. - * - * Also note that once this function is called the effect is irreversible, - * unless EthDB is complete unloaded and re-initialized. - * - * @return IX_ETH_DB_INVALID_ARG (no read-write properties are - * supported in this release) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value) -{ - IX_ETH_DB_CHECK_PORT_EXISTS(portID); - - if ((feature == IX_ETH_DB_VLAN_QOS) && (property == IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE)) - { - ixEthDBPortInfo[portID].ixEthDBTrafficClassAvailable = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount; - - return IX_ETH_DB_SUCCESS; - } - - return IX_ETH_DB_INVALID_ARG; -} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBFirewall.c b/arch/arm/cpu/ixp/npe/IxEthDBFirewall.c deleted file mode 100644 index eb46174..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBFirewall.c +++ /dev/null @@ -1,266 +0,0 @@ -/** - * @file IxEthDBFirewall.c - * - * @brief Implementation of the firewall API - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - - -#include "IxEthDB_p.h" - -/** - * @brief updates the NPE firewall operating mode and - * firewall address table - * - * @param portID ID of the port - * @param epDelta initial entry point for binary searches (NPE optimization) - * @param address address of the firewall MAC address table - * - * This function will send a message to the NPE configuring the - * firewall mode (white list or black list), invalid source - * address filtering and downloading a new MAC address database - * to be used for firewall matching. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or IX_ETH_DB_FAIL otherwise - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta) -{ - IxNpeMhMessage message; - IX_STATUS result; - - UINT32 mode = 0; - PortInfo *portInfo = &ixEthDBPortInfo[portID]; - - mode = (portInfo->srcAddressFilterEnabled != FALSE) << 1 | (portInfo->firewallMode == IX_ETH_DB_FIREWALL_WHITE_LIST); - - FILL_SETFIREWALLMODE_MSG(message, - IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), - epDelta, - mode, - IX_OSAL_MMU_VIRT_TO_PHYS(address)); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief configures the firewall white list/black list - * access mode - * - * @param portID ID of the port - * @param mode firewall filtering mode (IX_ETH_DB_FIREWALL_WHITE_LIST - * or IX_ETH_DB_FIREWALL_BLACK_LIST) - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL); - - if (mode != IX_ETH_DB_FIREWALL_WHITE_LIST - && mode != IX_ETH_DB_FIREWALL_BLACK_LIST) - { - return IX_ETH_DB_INVALID_ARG; - } - - ixEthDBPortInfo[portID].firewallMode = mode; - - return ixEthDBFirewallTableDownload(portID); -} - -/** - * @brief enables or disables the invalid source MAC address filter - * - * @param portID ID of the port - * @param enable TRUE to enable invalid source MAC address filtering - * or FALSE to disable it - * - * The invalid source MAC address filter will discard, when enabled, - * frames whose source MAC address is a multicast or the broadcast MAC - * address. - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL); - - ixEthDBPortInfo[portID].srcAddressFilterEnabled = enable; - - return ixEthDBFirewallTableDownload(portID); -} - -/** - * @brief adds a firewall record - * - * @param portID ID of the port - * @param macAddr MAC address of the new record - * - * This function will add a new firewall record - * on the specified port, using the specified - * MAC address. If the record already exists this - * function will silently return IX_ETH_DB_SUCCESS, - * although no duplicate records are added. - * - * Note that this function is documented in the main - * component header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) -{ - MacDescriptor recordTemplate; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL); - - memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr)); - - recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD; - recordTemplate.portID = portID; - - return ixEthDBAdd(&recordTemplate, NULL); -} - -/** - * @brief removes a firewall record - * - * @param portID ID of the port - * @param macAddr MAC address of the record to remove - * - * This function will attempt to remove a firewall - * record from the given port, using the specified - * MAC address. - * - * Note that this function is documented in the main - * component header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully of an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) -{ - MacDescriptor recordTemplate; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL); - - memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr)); - - recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD; - recordTemplate.portID = portID; - - return ixEthDBRemove(&recordTemplate, NULL); -} - -/** - * @brief downloads the firewall address table to an NPE - * - * @param portID ID of the port - * - * This function will download the firewall address table to - * an NPE port. - * - * Note that this function is documented in the main - * component header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or IX_ETH_DB_FAIL otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID) -{ - IxEthDBPortMap query; - IxEthDBStatus result; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL); - - SET_DEPENDENCY_MAP(query, portID); - - ixEthDBUpdateLock(); - - ixEthDBPortInfo[portID].updateMethod.searchTree = ixEthDBQuery(NULL, query, IX_ETH_DB_FIREWALL_RECORD, MAX_FW_SIZE); - - result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FIREWALL_RECORD); - - ixEthDBUpdateUnlock(); - - return result; -} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBHashtable.c b/arch/arm/cpu/ixp/npe/IxEthDBHashtable.c deleted file mode 100644 index f1b18e6..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBHashtable.c +++ /dev/null @@ -1,642 +0,0 @@ -/** - * @file ethHash.c - * - * @brief Hashtable implementation - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - - -#include "IxEthDB_p.h" -#include "IxEthDBLocks_p.h" - -/** - * @addtogroup EthDB - * - * @{ - */ - -/** - * @brief initializes a hash table object - * - * @param hashTable uninitialized hash table structure - * @param numBuckets number of buckets to use - * @param entryHashFunction hash function used - * to hash entire hash node data block (for adding) - * @param matchFunctions array of match functions, indexed on type, - * used to differentiate records with the same hash value - * @param freeFunction function used to free node data blocks - * - * Initializes the given hash table object. - * - * @internal - */ -void ixEthDBInitHash(HashTable *hashTable, - UINT32 numBuckets, - HashFunction entryHashFunction, - MatchFunction *matchFunctions, - FreeFunction freeFunction) -{ - UINT32 bucketIndex; - UINT32 hashSize = numBuckets * sizeof(HashNode *); - - /* entry hashing, matching and freeing methods */ - hashTable->entryHashFunction = entryHashFunction; - hashTable->matchFunctions = matchFunctions; - hashTable->freeFunction = freeFunction; - - /* buckets */ - hashTable->numBuckets = numBuckets; - - /* set to 0 all buckets */ - memset(hashTable->hashBuckets, 0, hashSize); - - /* init bucket locks - note that initially all mutexes are unlocked after MutexInit()*/ - for (bucketIndex = 0 ; bucketIndex < numBuckets ; bucketIndex++) - { - ixOsalFastMutexInit(&hashTable->bucketLocks[bucketIndex]); - } -} - -/** - * @brief adds an entry to the hash table - * - * @param hashTable hash table to add the entry to - * @param entry entry to add - * - * The entry will be hashed using the entry hashing function and added to the - * hash table, unless a locking blockage occurs, in which case the caller - * should retry. - * - * @retval IX_ETH_DB_SUCCESS if adding entry has succeeded - * @retval IX_ETH_DB_NOMEM if there's no memory left in the hash node pool - * @retval IX_ETH_DB_BUSY if there's a locking failure on the insertion path - * - * @internal - */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry) -{ - UINT32 hashValue = hashTable->entryHashFunction(entry); - UINT32 bucketIndex = hashValue % hashTable->numBuckets; - HashNode *bucket = hashTable->hashBuckets[bucketIndex]; - HashNode *newNode; - - LockStack locks; - - INIT_STACK(&locks); - - /* lock bucket */ - PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]); - - /* lock insertion element (first in chain), if any */ - if (bucket != NULL) - { - PUSH_LOCK(&locks, &bucket->lock); - } - - /* get new node */ - newNode = ixEthDBAllocHashNode(); - - if (newNode == NULL) - { - /* unlock everything */ - UNROLL_STACK(&locks); - - return IX_ETH_DB_NOMEM; - } - - /* init lock - note that mutexes are unlocked after MutexInit */ - ixOsalFastMutexInit(&newNode->lock); - - /* populate new link */ - newNode->data = entry; - - /* add to bucket */ - newNode->next = bucket; - hashTable->hashBuckets[bucketIndex] = newNode; - - /* unlock bucket and insertion point */ - UNROLL_STACK(&locks); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief removes an entry from the hashtable - * - * @param hashTable hash table to remove entry from - * @param keyType type of record key used for matching - * @param reference reference key used to identify the entry - * - * The reference key will be hashed using the key hashing function, - * the entry is searched using the hashed value and then examined - * against the reference entry using the match function. A positive - * match will trigger the deletion of the entry. - * Locking failures are reported and the caller should retry. - * - * @retval IX_ETH_DB_SUCCESS if the removal was successful - * @retval IX_ETH_DB_NO_SUCH_ADDR if the entry was not found - * @retval IX_ETH_DB_BUSY if a locking failure occured during the process - * - * @internal - */ -IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference) -{ - UINT32 hashValue = hashTable->entryHashFunction(reference); - UINT32 bucketIndex = hashValue % hashTable->numBuckets; - HashNode *node = hashTable->hashBuckets[bucketIndex]; - HashNode *previousNode = NULL; - - LockStack locks; - - INIT_STACK(&locks); - - while (node != NULL) - { - /* try to lock node */ - PUSH_LOCK(&locks, &node->lock); - - if (hashTable->matchFunctions[keyType](reference, node->data)) - { - /* found entry */ - if (node->next != NULL) - { - PUSH_LOCK(&locks, &node->next->lock); - } - - if (previousNode == NULL) - { - /* node is head of chain */ - PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]); - - hashTable->hashBuckets[bucketIndex] = node->next; - - POP_LOCK(&locks); - } - else - { - /* relink */ - previousNode->next = node->next; - } - - UNROLL_STACK(&locks); - - /* free node */ - hashTable->freeFunction(node->data); - ixEthDBFreeHashNode(node); - - return IX_ETH_DB_SUCCESS; - } - else - { - if (previousNode != NULL) - { - /* unlock previous node */ - SHIFT_STACK(&locks); - } - - /* advance to next element in chain */ - previousNode = node; - node = node->next; - } - } - - UNROLL_STACK(&locks); - - /* not found */ - return IX_ETH_DB_NO_SUCH_ADDR; -} - -/** - * @brief retrieves an entry from the hash table - * - * @param hashTable hash table to perform the search into - * @param reference search key (a MAC address) - * @param keyType type of record key used for matching - * @param searchResult pointer where a reference to the located hash node - * is placed - * - * Searches the entry with the same key as reference and places the - * pointer to the resulting node in searchResult. - * An implicit write access lock is granted after a search, which gives the - * caller the opportunity to modify the entry. - * Access should be released as soon as possible using @ref ixEthDBReleaseHashNode(). - * - * @see ixEthDBReleaseHashNode() - * - * @retval IX_ETH_DB_SUCCESS if the search was completed successfully - * @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found - * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case - * the caller should retry - * - * @warning unless the return value is IX_ETH_DB_SUCCESS the searchResult - * location is NOT modified and therefore using a NULL comparison test when the - * value was not properly initialized would be an error - * - * @internal - */ -IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult) -{ - UINT32 hashValue; - HashNode *node; - - hashValue = hashTable->entryHashFunction(reference); - node = hashTable->hashBuckets[hashValue % hashTable->numBuckets]; - - while (node != NULL) - { - TRY_LOCK(&node->lock); - - if (hashTable->matchFunctions[keyType](reference, node->data)) - { - *searchResult = node; - - return IX_ETH_DB_SUCCESS; - } - else - { - UNLOCK(&node->lock); - - node = node->next; - } - } - - /* not found */ - return IX_ETH_DB_NO_SUCH_ADDR; -} - -/** - * @brief reports the existence of an entry in the hash table - * - * @param hashTable hash table to perform the search into - * @param reference search key (a MAC address) - * @param keyType type of record key used for matching - * - * Searches the entry with the same key as reference. - * No implicit write access lock is granted after a search, hence the - * caller cannot access or modify the entry. The result is only temporary. - * - * @see ixEthDBReleaseHashNode() - * - * @retval IX_ETH_DB_SUCCESS if the search was completed successfully - * @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found - * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case - * the caller should retry - * - * @internal - */ -IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference) -{ - UINT32 hashValue; - HashNode *node; - - hashValue = hashTable->entryHashFunction(reference); - node = hashTable->hashBuckets[hashValue % hashTable->numBuckets]; - - while (node != NULL) - { - TRY_LOCK(&node->lock); - - if (hashTable->matchFunctions[keyType](reference, node->data)) - { - UNLOCK(&node->lock); - - return IX_ETH_DB_SUCCESS; - } - else - { - UNLOCK(&node->lock); - - node = node->next; - } - } - - /* not found */ - return IX_ETH_DB_NO_SUCH_ADDR; -} - -/** - * @brief releases the write access lock - * - * @pre the node should have been obtained via @ref ixEthDBSearchHashEntry() - * - * @see ixEthDBSearchHashEntry() - * - * @internal - */ -void ixEthDBReleaseHashNode(HashNode *node) -{ - UNLOCK(&node->lock); -} - -/** - * @brief initializes a hash iterator - * - * @param hashTable hash table to be iterated - * @param iterator iterator object - * - * If the initialization is successful the iterator will point to the - * first hash table record (if any). - * Testing if the iterator has not passed the end of the table should be - * done using the IS_ITERATOR_VALID(iteratorPtr) macro. - * An implicit write access lock is granted on the entry pointed by the iterator. - * The access is automatically revoked when the iterator is incremented. - * If the caller decides to terminate the iteration before the end of the table is - * passed then the manual access release method, @ref ixEthDBReleaseHashIterator, - * must be called. - * - * @see ixEthDBReleaseHashIterator() - * - * @retval IX_ETH_DB_SUCCESS if initialization was successful and the iterator points - * to the first valid table node - * @retval IX_ETH_DB_FAIL if the table is empty - * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller - * should retry - * - * @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this - * might place the database in a permanent invalid lock state - * - * @internal - */ -IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator) -{ - iterator->bucketIndex = 0; - iterator->node = NULL; - iterator->previousNode = NULL; - - return ixEthDBIncrementHashIterator(hashTable, iterator); -} - -/** - * @brief releases the write access locks of the iterator nodes - * - * @warning use of this function is required only when the caller terminates an iteration - * before reaching the end of the table - * - * @see ixEthDBInitHashIterator() - * @see ixEthDBIncrementHashIterator() - * - * @param iterator iterator whose node(s) should be unlocked - * - * @internal - */ -void ixEthDBReleaseHashIterator(HashIterator *iterator) -{ - if (iterator->previousNode != NULL) - { - UNLOCK(&iterator->previousNode->lock); - } - - if (iterator->node != NULL) - { - UNLOCK(&iterator->node->lock); - } -} - -/** - * @brief incremenents an iterator so that it points to the next valid entry of the table - * (if any) - * - * @param hashTable hash table to iterate - * @param iterator iterator object - * - * @pre the iterator object must be initialized using @ref ixEthDBInitHashIterator() - * - * If the increment operation is successful the iterator will point to the - * next hash table record (if any). - * Testing if the iterator has not passed the end of the table should be - * done using the IS_ITERATOR_VALID(iteratorPtr) macro. - * An implicit write access lock is granted on the entry pointed by the iterator. - * The access is automatically revoked when the iterator is re-incremented. - * If the caller decides to terminate the iteration before the end of the table is - * passed then the manual access release method, @ref ixEthDBReleaseHashIterator, - * must be called. - * Is is guaranteed that no other thread can remove or change the iterated entry until - * the iterator is incremented successfully. - * - * @see ixEthDBReleaseHashIterator() - * - * @retval IX_ETH_DB_SUCCESS if the operation was successful and the iterator points - * to the next valid table node - * @retval IX_ETH_DB_FAIL if the iterator has passed the end of the table - * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller - * should retry - * - * @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this - * might place the database in a permanent invalid lock state - * - * @internal - */ -IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator) -{ - /* unless iterator is just initialized... */ - if (iterator->node != NULL) - { - /* try next in chain */ - if (iterator->node->next != NULL) - { - TRY_LOCK(&iterator->node->next->lock); - - if (iterator->previousNode != NULL) - { - UNLOCK(&iterator->previousNode->lock); - } - - iterator->previousNode = iterator->node; - iterator->node = iterator->node->next; - - return IX_ETH_DB_SUCCESS; - } - else - { - /* last in chain, prepare for next bucket */ - iterator->bucketIndex++; - } - } - - /* try next used bucket */ - for (; iterator->bucketIndex < hashTable->numBuckets ; iterator->bucketIndex++) - { - HashNode **nodePtr = &(hashTable->hashBuckets[iterator->bucketIndex]); - HashNode *node = *nodePtr; -#if (CPU!=SIMSPARCSOLARIS) && !defined (__wince) - if (((iterator->bucketIndex & IX_ETHDB_BUCKET_INDEX_MASK) == 0) && - (iterator->bucketIndex < (hashTable->numBuckets - IX_ETHDB_BUCKETPTR_AHEAD))) - { - /* preload next cache line (2 cache line ahead) */ - nodePtr += IX_ETHDB_BUCKETPTR_AHEAD; - __asm__ ("pld [%0];\n": : "r" (nodePtr)); - } -#endif - if (node != NULL) - { - TRY_LOCK(&node->lock); - - /* unlock last one or two nodes in the previous chain */ - if (iterator->node != NULL) - { - UNLOCK(&iterator->node->lock); - - if (iterator->previousNode != NULL) - { - UNLOCK(&iterator->previousNode->lock); - } - } - - /* redirect iterator */ - iterator->previousNode = NULL; - iterator->node = node; - - return IX_ETH_DB_SUCCESS; - } - } - - /* could not advance iterator */ - if (iterator->node != NULL) - { - UNLOCK(&iterator->node->lock); - - if (iterator->previousNode != NULL) - { - UNLOCK(&iterator->previousNode->lock); - } - - iterator->node = NULL; - } - - return IX_ETH_DB_END; -} - -/** - * @brief removes an entry pointed by an iterator - * - * @param hashTable iterated hash table - * @param iterator iterator object - * - * Removes the entry currently pointed by the iterator and repositions the iterator - * on the next valid entry (if any). Handles locking issues automatically and - * implicitely grants write access lock to the new pointed entry. - * Failures due to concurrent threads having write access locks in the same region - * preserve the state of the database and the iterator object, leaving the caller - * free to retry without loss of access. It is guaranteed that only the thread owning - * the iterator can remove the object pointed by the iterator. - * - * @retval IX_ETH_DB_SUCCESS if removal has succeeded - * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller - * should retry - * - * @internal - */ -IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator) -{ - HashIterator nextIteratorPos; - LockStack locks; - - INIT_STACK(&locks); - - /* set initial bucket index for next position */ - nextIteratorPos.bucketIndex = iterator->bucketIndex; - - /* compute iterator position before removing anything and lock ahead */ - if (iterator->node->next != NULL) - { - PUSH_LOCK(&locks, &iterator->node->next->lock); - - /* reposition on the next node in the chain */ - nextIteratorPos.node = iterator->node->next; - nextIteratorPos.previousNode = iterator->previousNode; - } - else - { - /* try next chain - don't know yet if we'll find anything */ - nextIteratorPos.node = NULL; - - /* if we find something it's a chain head */ - nextIteratorPos.previousNode = NULL; - - /* browse up in the buckets to find a non-null chain */ - while (++nextIteratorPos.bucketIndex < hashTable->numBuckets) - { - nextIteratorPos.node = hashTable->hashBuckets[nextIteratorPos.bucketIndex]; - - if (nextIteratorPos.node != NULL) - { - /* found a non-empty chain, try to lock head */ - PUSH_LOCK(&locks, &nextIteratorPos.node->lock); - - break; - } - } - } - - /* restore links over the to-be-deleted item */ - if (iterator->previousNode == NULL) - { - /* first in chain, lock bucket */ - PUSH_LOCK(&locks, &hashTable->bucketLocks[iterator->bucketIndex]); - - hashTable->hashBuckets[iterator->bucketIndex] = iterator->node->next; - - POP_LOCK(&locks); - } - else - { - /* relink */ - iterator->previousNode->next = iterator->node->next; - - /* unlock last remaining node in current chain when moving between chains */ - if (iterator->node->next == NULL) - { - UNLOCK(&iterator->previousNode->lock); - } - } - - /* delete entry */ - hashTable->freeFunction(iterator->node->data); - ixEthDBFreeHashNode(iterator->node); - - /* reposition iterator */ - *iterator = nextIteratorPos; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @} - */ diff --git a/arch/arm/cpu/ixp/npe/IxEthDBLearning.c b/arch/arm/cpu/ixp/npe/IxEthDBLearning.c deleted file mode 100644 index 2287dbe..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBLearning.c +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @file IxEthDBLearning.c - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxEthDB_p.h" - -/** - * @brief hashes the mac address in a mac descriptor with a XOR function - * - * @param entry pointer to a mac descriptor to be hashed - * - * This function only extracts the mac address and employs ixEthDBKeyXORHash() - * to do the actual hashing. - * Used only to add a whole entry to a hash table, as opposed to searching which - * takes only a key and uses the key hashing directly. - * - * @see ixEthDBKeyXORHash() - * - * @return the hash value - * - * @internal - */ -UINT32 ixEthDBEntryXORHash(void *entry) -{ - MacDescriptor *descriptor = (MacDescriptor *) entry; - - return ixEthDBKeyXORHash(descriptor->macAddress); -} - -/** - * @brief hashes a mac address - * - * @param key pointer to a 6 byte structure (typically an IxEthDBMacAddr pointer) - * to be hashed - * - * Given a 6 bytes MAC address, the hash used is: - * - * hash(MAC[0:5]) = MAC[0:1] ^ MAC[2:3] ^ MAC[4:5] - * - * Used by the hash table to search and remove entries based - * solely on their keys (mac addresses). - * - * @return the hash value - * - * @internal - */ -UINT32 ixEthDBKeyXORHash(void *key) -{ - UINT32 hashValue; - UINT8 *value = (UINT8 *) key; - - hashValue = (value[5] << 8) | value[4]; - hashValue ^= (value[3] << 8) | value[2]; - hashValue ^= (value[1] << 8) | value[0]; - - return hashValue; -} - -/** - * @brief mac descriptor match function - * - * @param reference mac address (typically an IxEthDBMacAddr pointer) structure - * @param entry pointer to a mac descriptor whose key (mac address) is to be - * matched against the reference key - * - * Used by the hash table to retrieve entries. Hashing entries can produce - * collisions, i.e. descriptors with different mac addresses and the same - * hash value, where this function is used to differentiate entries. - * - * @retval TRUE if the entry matches the reference key (equal addresses) - * @retval FALSE if the entry does not match the reference key - * - * @internal - */ -BOOL ixEthDBAddressMatch(void *reference, void *entry) -{ - return (ixEthDBAddressCompare(reference, ((MacDescriptor *) entry)->macAddress) == 0); -} - -/** - * @brief compares two mac addresses - * - * @param mac1 first mac address to compare - * @param mac2 second mac address to compare - * - * This comparison works in a similar way to strcmp, producing similar results. - * Used to insert values keyed on mac addresses into binary search trees. - * - * @retval -1 if mac1 < mac2 - * @retval 0 if ma1 == mac2 - * @retval 1 if mac1 > mac2 - */ -UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2) -{ - UINT32 local_index; - - for (local_index = 0 ; local_index < IX_IEEE803_MAC_ADDRESS_SIZE ; local_index++) - { - if (mac1[local_index] > mac2[local_index]) - { - return 1; - } - else if (mac1[local_index] < mac2[local_index]) - { - return -1; - } - } - - return 0; -} - diff --git a/arch/arm/cpu/ixp/npe/IxEthDBMem.c b/arch/arm/cpu/ixp/npe/IxEthDBMem.c deleted file mode 100644 index 133cbef..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBMem.c +++ /dev/null @@ -1,649 +0,0 @@ -/** - * @file IxEthDBDBMem.c - * - * @brief Memory handling routines for the MAC address database - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - - -#include "IxEthDB_p.h" - -IX_ETH_DB_PRIVATE HashNode *nodePool = NULL; -IX_ETH_DB_PRIVATE MacDescriptor *macPool = NULL; -IX_ETH_DB_PRIVATE MacTreeNode *treePool = NULL; - -IX_ETH_DB_PRIVATE HashNode nodePoolArea[NODE_POOL_SIZE]; -IX_ETH_DB_PRIVATE MacDescriptor macPoolArea[MAC_POOL_SIZE]; -IX_ETH_DB_PRIVATE MacTreeNode treePoolArea[TREE_POOL_SIZE]; - -IX_ETH_DB_PRIVATE IxOsalMutex nodePoolLock; -IX_ETH_DB_PRIVATE IxOsalMutex macPoolLock; -IX_ETH_DB_PRIVATE IxOsalMutex treePoolLock; - -#define LOCK_NODE_POOL { ixOsalMutexLock(&nodePoolLock, IX_OSAL_WAIT_FOREVER); } -#define UNLOCK_NODE_POOL { ixOsalMutexUnlock(&nodePoolLock); } - -#define LOCK_MAC_POOL { ixOsalMutexLock(&macPoolLock, IX_OSAL_WAIT_FOREVER); } -#define UNLOCK_MAC_POOL { ixOsalMutexUnlock(&macPoolLock); } - -#define LOCK_TREE_POOL { ixOsalMutexLock(&treePoolLock, IX_OSAL_WAIT_FOREVER); } -#define UNLOCK_TREE_POOL { ixOsalMutexUnlock(&treePoolLock); } - -/* private function prototypes */ -IX_ETH_DB_PRIVATE MacDescriptor* ixEthDBPoolAllocMacDescriptor(void); -IX_ETH_DB_PRIVATE void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor); - -/** - * @addtogroup EthMemoryManagement - * - * @{ - */ - -/** - * @brief initializes the memory pools used by the ethernet database component - * - * Initializes the hash table node, mac descriptor and mac tree node pools. - * Called at initialization time by @ref ixEthDBInit(). - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBInitMemoryPools(void) -{ - int local_index; - - /* HashNode pool */ - ixOsalMutexInit(&nodePoolLock); - - for (local_index = 0 ; local_index < NODE_POOL_SIZE ; local_index++) - { - HashNode *freeNode = &nodePoolArea[local_index]; - - freeNode->nextFree = nodePool; - nodePool = freeNode; - } - - /* MacDescriptor pool */ - ixOsalMutexInit(&macPoolLock); - - for (local_index = 0 ; local_index < MAC_POOL_SIZE ; local_index++) - { - MacDescriptor *freeDescriptor = &macPoolArea[local_index]; - - freeDescriptor->nextFree = macPool; - macPool = freeDescriptor; - } - - /* MacTreeNode pool */ - ixOsalMutexInit(&treePoolLock); - - for (local_index = 0 ; local_index < TREE_POOL_SIZE ; local_index++) - { - MacTreeNode *freeNode = &treePoolArea[local_index]; - - freeNode->nextFree = treePool; - treePool = freeNode; - } -} - -/** - * @brief allocates a hash node from the pool - * - * Allocates a hash node and resets its value. - * - * @return the allocated hash node or NULL if the pool is empty - * - * @internal - */ -IX_ETH_DB_PUBLIC -HashNode* ixEthDBAllocHashNode(void) -{ - HashNode *allocatedNode = NULL; - - if (nodePool != NULL) - { - LOCK_NODE_POOL; - - allocatedNode = nodePool; - nodePool = nodePool->nextFree; - - UNLOCK_NODE_POOL; - - memset(allocatedNode, 0, sizeof(HashNode)); - } - - return allocatedNode; -} - -/** - * @brief frees a hash node into the pool - * - * @param hashNode node to be freed - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBFreeHashNode(HashNode *hashNode) -{ - if (hashNode != NULL) - { - LOCK_NODE_POOL; - - hashNode->nextFree = nodePool; - nodePool = hashNode; - - UNLOCK_NODE_POOL; - } -} - -/** - * @brief allocates a mac descriptor from the pool - * - * Allocates a mac descriptor and resets its value. - * This function is not used directly, instead @ref ixEthDBAllocMacDescriptor() - * is used, which keeps track of the pointer reference count. - * - * @see ixEthDBAllocMacDescriptor() - * - * @warning this function is not used directly by any other function - * apart from ixEthDBAllocMacDescriptor() - * - * @return the allocated mac descriptor or NULL if the pool is empty - * - * @internal - */ -IX_ETH_DB_PRIVATE -MacDescriptor* ixEthDBPoolAllocMacDescriptor(void) -{ - MacDescriptor *allocatedDescriptor = NULL; - - if (macPool != NULL) - { - LOCK_MAC_POOL; - - allocatedDescriptor = macPool; - macPool = macPool->nextFree; - - UNLOCK_MAC_POOL; - - memset(allocatedDescriptor, 0, sizeof(MacDescriptor)); - } - - return allocatedDescriptor; -} - -/** - * @brief allocates and initializes a mac descriptor smart pointer - * - * Uses @ref ixEthDBPoolAllocMacDescriptor() to allocate a mac descriptor - * from the pool and initializes its reference count. - * - * @see ixEthDBPoolAllocMacDescriptor() - * - * @return the allocated mac descriptor or NULL if the pool is empty - * - * @internal - */ -IX_ETH_DB_PUBLIC -MacDescriptor* ixEthDBAllocMacDescriptor(void) -{ - MacDescriptor *allocatedDescriptor = ixEthDBPoolAllocMacDescriptor(); - - if (allocatedDescriptor != NULL) - { - LOCK_MAC_POOL; - - allocatedDescriptor->refCount++; - - UNLOCK_MAC_POOL; - } - - return allocatedDescriptor; -} - -/** - * @brief frees a mac descriptor back into the pool - * - * @param macDescriptor mac descriptor to be freed - * - * @warning this function is not to be called by anyone but - * ixEthDBFreeMacDescriptor() - * - * @see ixEthDBFreeMacDescriptor() - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor) -{ - LOCK_MAC_POOL; - - macDescriptor->nextFree = macPool; - macPool = macDescriptor; - - UNLOCK_MAC_POOL; -} - -/** - * @brief frees or reduces the usage count of a mac descriptor smart pointer - * - * If the reference count reaches 0 (structure is no longer used anywhere) - * then the descriptor is freed back into the pool using ixEthDBPoolFreeMacDescriptor(). - * - * @see ixEthDBPoolFreeMacDescriptor() - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBFreeMacDescriptor(MacDescriptor *macDescriptor) -{ - if (macDescriptor != NULL) - { - LOCK_MAC_POOL; - - if (macDescriptor->refCount > 0) - { - macDescriptor->refCount--; - - if (macDescriptor->refCount == 0) - { - UNLOCK_MAC_POOL; - - ixEthDBPoolFreeMacDescriptor(macDescriptor); - } - else - { - UNLOCK_MAC_POOL; - } - } - else - { - UNLOCK_MAC_POOL; - } - } -} - -/** - * @brief clones a mac descriptor smart pointer - * - * @param macDescriptor mac descriptor to clone - * - * Increments the usage count of the smart pointer - * - * @returns the cloned smart pointer - * - * @internal - */ -IX_ETH_DB_PUBLIC -MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor) -{ - LOCK_MAC_POOL; - - if (macDescriptor->refCount == 0) - { - UNLOCK_MAC_POOL; - - return NULL; - } - - macDescriptor->refCount++; - - UNLOCK_MAC_POOL; - - return macDescriptor; -} - -/** - * @brief allocates a mac tree node from the pool - * - * Allocates and initializes a mac tree node from the pool. - * - * @return the allocated mac tree node or NULL if the pool is empty - * - * @internal - */ -IX_ETH_DB_PUBLIC -MacTreeNode* ixEthDBAllocMacTreeNode(void) -{ - MacTreeNode *allocatedNode = NULL; - - if (treePool != NULL) - { - LOCK_TREE_POOL; - - allocatedNode = treePool; - treePool = treePool->nextFree; - - UNLOCK_TREE_POOL; - - memset(allocatedNode, 0, sizeof(MacTreeNode)); - } - - return allocatedNode; -} - -/** - * @brief frees a mac tree node back into the pool - * - * @param macNode mac tree node to be freed - * - * @warning not to be used except from ixEthDBFreeMacTreeNode(). - * - * @see ixEthDBFreeMacTreeNode() - * - * @internal - */ -void ixEthDBPoolFreeMacTreeNode(MacTreeNode *macNode) -{ - if (macNode != NULL) - { - LOCK_TREE_POOL; - - macNode->nextFree = treePool; - treePool = macNode; - - UNLOCK_TREE_POOL; - } -} - -/** - * @brief frees or reduces the usage count of a mac tree node smart pointer - * - * @param macNode mac tree node to free - * - * Reduces the usage count of the given mac node. If the usage count - * reaches 0 the node is freed back into the pool using ixEthDBPoolFreeMacTreeNode() - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBFreeMacTreeNode(MacTreeNode *macNode) -{ - if (macNode->descriptor != NULL) - { - ixEthDBFreeMacDescriptor(macNode->descriptor); - } - - if (macNode->left != NULL) - { - ixEthDBFreeMacTreeNode(macNode->left); - } - - if (macNode->right != NULL) - { - ixEthDBFreeMacTreeNode(macNode->right); - } - - ixEthDBPoolFreeMacTreeNode(macNode); -} - -/** - * @brief clones a mac tree node - * - * @param macNode mac tree node to be cloned - * - * Increments the usage count of the node, its associated descriptor - * and recursively of all its child nodes. - * - * @warning this function is recursive and clones whole trees/subtrees, use only for - * root nodes - * - * @internal - */ -IX_ETH_DB_PUBLIC -MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *macNode) -{ - if (macNode != NULL) - { - MacTreeNode *clonedMacNode = ixEthDBAllocMacTreeNode(); - - if (clonedMacNode != NULL) - { - if (macNode->right != NULL) - { - clonedMacNode->right = ixEthDBCloneMacTreeNode(macNode->right); - } - - if (macNode->left != NULL) - { - clonedMacNode->left = ixEthDBCloneMacTreeNode(macNode->left); - } - - if (macNode->descriptor != NULL) - { - clonedMacNode->descriptor = ixEthDBCloneMacDescriptor(macNode->descriptor); - } - } - - return clonedMacNode; - } - else - { - return NULL; - } -} - -#ifndef NDEBUG -/* Debug statistical functions for memory usage */ - -extern HashTable dbHashtable; -int ixEthDBNumHashElements(void); - -int ixEthDBNumHashElements(void) -{ - UINT32 bucketIndex; - int numElements = 0; - HashTable *hashTable = &dbHashtable; - - for (bucketIndex = 0 ; bucketIndex < hashTable->numBuckets ; bucketIndex++) - { - if (hashTable->hashBuckets[bucketIndex] != NULL) - { - HashNode *node = hashTable->hashBuckets[bucketIndex]; - - while (node != NULL) - { - numElements++; - - node = node->next; - } - } - } - - return numElements; -} - -UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree) -{ - if (tree == NULL) - { - return 0; - } - else - { - return 1 /* this node */ + ixEthDBSearchTreeUsageGet(tree->left) + ixEthDBSearchTreeUsageGet(tree->right); - } -} - -int ixEthDBShowMemoryStatus(void) -{ - MacDescriptor *mac; - MacTreeNode *tree; - HashNode *node; - - int macCounter = 0; - int treeCounter = 0; - int nodeCounter = 0; - - int totalTreeUsage = 0; - int totalDescriptorUsage = 0; - int totalCloneDescriptorUsage = 0; - int totalNodeUsage = 0; - - UINT32 portIndex; - - LOCK_NODE_POOL; - LOCK_MAC_POOL; - LOCK_TREE_POOL; - - mac = macPool; - tree = treePool; - node = nodePool; - - while (mac != NULL) - { - macCounter++; - - mac = mac->nextFree; - - if (macCounter > MAC_POOL_SIZE) - { - break; - } - } - - while (tree != NULL) - { - treeCounter++; - - tree = tree->nextFree; - - if (treeCounter > TREE_POOL_SIZE) - { - break; - } - } - - while (node != NULL) - { - nodeCounter++; - - node = node->nextFree; - - if (nodeCounter > NODE_POOL_SIZE) - { - break; - } - } - - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - int treeUsage = ixEthDBSearchTreeUsageGet(ixEthDBPortInfo[portIndex].updateMethod.searchTree); - - totalTreeUsage += treeUsage; - totalCloneDescriptorUsage += treeUsage; /* each tree node contains a descriptor */ - } - - totalNodeUsage = ixEthDBNumHashElements(); - totalDescriptorUsage += totalNodeUsage; /* each hash table entry contains a descriptor */ - - UNLOCK_NODE_POOL; - UNLOCK_MAC_POOL; - UNLOCK_TREE_POOL; - - printf("Ethernet database memory usage stats:\n\n"); - - if (macCounter <= MAC_POOL_SIZE) - { - printf("\tMAC descriptor pool : %d free out of %d entries (%d%%)\n", macCounter, MAC_POOL_SIZE, macCounter * 100 / MAC_POOL_SIZE); - } - else - { - printf("\tMAC descriptor pool : invalid state (ring within the pool), normally %d entries\n", MAC_POOL_SIZE); - } - - if (treeCounter <= TREE_POOL_SIZE) - { - printf("\tTree node pool : %d free out of %d entries (%d%%)\n", treeCounter, TREE_POOL_SIZE, treeCounter * 100 / TREE_POOL_SIZE); - } - else - { - printf("\tTREE descriptor pool : invalid state (ring within the pool), normally %d entries\n", TREE_POOL_SIZE); - } - - if (nodeCounter <= NODE_POOL_SIZE) - { - printf("\tHash node pool : %d free out of %d entries (%d%%)\n", nodeCounter, NODE_POOL_SIZE, nodeCounter * 100 / NODE_POOL_SIZE); - } - else - { - printf("\tNODE descriptor pool : invalid state (ring within the pool), normally %d entries\n", NODE_POOL_SIZE); - } - - printf("\n"); - printf("\tMAC descriptor usage : %d entries, %d cloned\n", totalDescriptorUsage, totalCloneDescriptorUsage); - printf("\tTree node usage : %d entries\n", totalTreeUsage); - printf("\tHash node usage : %d entries\n", totalNodeUsage); - printf("\n"); - - /* search for duplicate nodes in the mac pool */ - { - MacDescriptor *reference = macPool; - - while (reference != NULL) - { - MacDescriptor *comparison = reference->nextFree; - - while (comparison != NULL) - { - if (reference == comparison) - { - printf("Warning: reached a duplicate (%p), invalid MAC pool state\n", reference); - - return 1; - } - - comparison = comparison->nextFree; - } - - reference = reference->nextFree; - } - } - - printf("No duplicates found in the MAC pool (sanity check ok)\n"); - - return 0; -} - -#endif /* NDEBUG */ - -/** - * @} EthMemoryManagement - */ diff --git a/arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c b/arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c deleted file mode 100644 index 112a46c..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBNPEAdaptor.c +++ /dev/null @@ -1,719 +0,0 @@ -/** - * @file IxEthDBDBNPEAdaptor.c - * - * @brief Routines that read and write learning/search trees in NPE-specific format - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxEthDB_p.h" -#include "IxEthDBLog_p.h" - -/* forward prototype declarations */ -IX_ETH_DB_PUBLIC void ixEthDBELTShow(IxEthDBPortId portID); -IX_ETH_DB_PUBLIC void ixEthDBShowNpeMsgHistory(void); - -/* data */ -UINT8* ixEthDBNPEUpdateArea[IX_ETH_DB_NUMBER_OF_PORTS]; -UINT32 dumpEltSize; - -/* private data */ -IX_ETH_DB_PRIVATE IxEthDBNoteWriteFn ixEthDBNPENodeWrite[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1]; - -#define IX_ETH_DB_MAX_DELTA_ZONES (6) /* at most 6 EP Delta zones, according to NPE FS */ -IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDeltaOffset[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES]; -IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDelta[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES]; - -/** - * @brief allocates non-cached or contiguous NPE tree update areas for all the ports - * - * This function is called only once at initialization time from - * @ref ixEthDBInit(). - * - * @warning do not call manually - * - * @see ixEthDBInit() - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBNPEUpdateAreasInit(void) -{ - UINT32 portIndex; - PortUpdateMethod *update; - - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - update = &ixEthDBPortInfo[portIndex].updateMethod; - - if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) - { - update->npeUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_ELT_BYTE_SIZE); - update->npeGwUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_GW_BYTE_SIZE); - update->vlanUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_VLAN_BYTE_SIZE); - - if (update->npeUpdateZone == NULL - || update->npeGwUpdateZone == NULL - || update->vlanUpdateZone == NULL) - { - ERROR_LOG("Fatal error: IX_ACC_DRV_DMA_MALLOC() returned NULL, no NPE update zones available\n"); - } - else - { - memset(update->npeUpdateZone, 0, FULL_ELT_BYTE_SIZE); - memset(update->npeGwUpdateZone, 0, FULL_GW_BYTE_SIZE); - memset(update->vlanUpdateZone, 0, FULL_VLAN_BYTE_SIZE); - } - } - else - { - /* unused */ - update->npeUpdateZone = NULL; - update->npeGwUpdateZone = NULL; - update->vlanUpdateZone = NULL; - } - } -} - -/** - * @brief deallocates the NPE update areas for all the ports - * - * This function is called at component de-initialization time - * by @ref ixEthDBUnload(). - * - * @warning do not call manually - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBNPEUpdateAreasUnload(void) -{ - UINT32 portIndex; - - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) - { - IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone); - IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeGwUpdateZone); - IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.vlanUpdateZone); - } - } -} - -/** - * @brief general-purpose NPE callback function - * - * @param npeID NPE ID - * @param msg NPE message - * - * This function will unblock the caller by unlocking - * the npeAckLock mutex defined for each NPE port - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg) -{ - IxEthDBPortId portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID); - PortInfo *portInfo; - - if (portID >= IX_ETH_DB_NUMBER_OF_PORTS) - { - /* invalid port */ - return; - } - - if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE) - { - /* not an NPE */ - return; - } - - portInfo = &ixEthDBPortInfo[portID]; - - ixOsalMutexUnlock(&portInfo->npeAckLock); -} - -/** - * @brief synchronizes the database with tree - * - * @param portID port ID of the NPE whose tree is to be scanned - * @param eltBaseAddress memory base address of the NPE serialized tree - * @param eltSize size in bytes of the NPE serialized tree - * - * Scans the NPE learning tree and resets the age of active database records. - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize) -{ - UINT32 eltEntryOffset; - UINT32 entryPortID; - - /* invalidate cache */ - IX_OSAL_CACHE_INVALIDATE(eltBaseAddress, eltSize); - - for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE) - { - /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node - * - * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit] - * therefore we can just use the pointer for database searches as only the first 6 bytes are checked - */ - void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset); - - /* debug */ - IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) checking node at offset %d...\n", eltEntryOffset / ELT_ENTRY_SIZE); - - if (IX_EDB_NPE_NODE_VALID(eltNodeAddress) != TRUE) - { - IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is empty\n"); - } - else if (eltEntryOffset == ELT_ROOT_OFFSET) - { - IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is root\n"); - } - - if (IX_EDB_NPE_NODE_VALID(eltNodeAddress)) - { - entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress)); - - /* check only active entries belonging to this port */ - if (ixEthDBPortInfo[portID].agingEnabled && IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) && (portID == entryPortID) - && ((ixEthDBPortDefinitions[portID].capabilities & IX_ETH_ENTRY_AGING) == 0)) - { - /* search record */ - HashNode *node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_FILTERING_RECORDS); - - /* safety check, maybe user deleted record right before sync? */ - if (node != NULL) - { - /* found record */ - MacDescriptor *descriptor = (MacDescriptor *) node->data; - - IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) synced entry [%s] already in the database, updating fields\n", mac2string(eltNodeAddress)); - - /* reset age - set to -1 so that maintenance will restore it to 0 (or more) when incrementing */ - if (!descriptor->recordData.filteringData.staticEntry) - { - if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) - { - descriptor->recordData.filteringData.age = AGE_RESET; - } - else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) - { - descriptor->recordData.filteringVlanData.age = AGE_RESET; - } - } - - /* end transaction */ - ixEthDBReleaseHashNode(node); - } - } - else - { - IX_ETH_DB_NPE_VERBOSE_TRACE("\t... found portID %d, we check only port %d\n", entryPortID, portID); - } - } - } -} - -/** - * @brief writes a search tree in NPE format - * - * @param type type of records to be written into the NPE update zone - * @param totalSize maximum size of the linearized tree - * @param baseAddress memory base address where to write the NPE tree into - * @param tree search tree to write in NPE format - * @param blocks number of written 64-byte blocks - * @param startIndex optimal binary search start index - * - * Serializes the given tree in NPE linear format - * - * @return none - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *epDelta, UINT32 *blocks) -{ - MacTreeNodeStack *stack; - UINT32 maxOffset = 0; - UINT32 emptyOffset; - - stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack)); - - if (stack == NULL) - { - ERROR_LOG("DB: (NPEAdaptor) failed to allocate the node stack for learning tree linearization, out of memory?\n"); - return; - } - - /* zero out empty root */ - memset(baseAddress, 0, ELT_ENTRY_SIZE); - - NODE_STACK_INIT(stack); - - if (tree != NULL) - { - /* push tree root at offset 1 */ - NODE_STACK_PUSH(stack, tree, 1); - - maxOffset = 1; - } - - while (NODE_STACK_NONEMPTY(stack)) - { - MacTreeNode *node; - UINT32 offset; - - NODE_STACK_POP(stack, node, offset); - - /* update maximum offset */ - if (offset > maxOffset) - { - maxOffset = offset; - } - - IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing MAC [%s] at offset %d\n", mac2string(node->descriptor->macAddress), offset); - - /* add node to NPE ELT at position indicated by offset */ - if (offset < MAX_ELT_SIZE) - { - ixEthDBNPENodeWrite[type]((void *) (((UINT32) baseAddress) + offset * ELT_ENTRY_SIZE), node); - } - - if (node->left != NULL) - { - NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset)); - } - else - { - /* ensure this entry is zeroed */ - memset((void *) ((UINT32) baseAddress + LEFT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE); - } - - if (node->right != NULL) - { - NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset)); - } - else - { - /* ensure this entry is zeroed */ - memset((void *) ((UINT32) baseAddress + RIGHT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE); - } - } - - emptyOffset = maxOffset + 1; - - /* zero out rest of the tree */ - IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Emptying tree from offset %d, address 0x%08X, %d bytes\n", - emptyOffset, ((UINT32) baseAddress) + emptyOffset * ELT_ENTRY_SIZE, totalSize - (emptyOffset * ELT_ENTRY_SIZE)); - - if (emptyOffset < MAX_ELT_SIZE - 1) - { - memset((void *) (((UINT32) baseAddress) + (emptyOffset * ELT_ENTRY_SIZE)), 0, totalSize - (emptyOffset * ELT_ENTRY_SIZE)); - } - - /* flush cache */ - IX_OSAL_CACHE_FLUSH(baseAddress, totalSize); - - /* debug */ - IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Ethernet learning/filtering tree XScale wrote at address 0x%08X (max %d bytes):\n\n", - (UINT32) baseAddress, FULL_ELT_BYTE_SIZE); - - IX_ETH_DB_NPE_DUMP_ELT(baseAddress, FULL_ELT_BYTE_SIZE); - - /* compute number of 64-byte blocks */ - if (blocks != NULL) - { - *blocks = maxOffset != 0 ? 1 + maxOffset / 8 : 0; - - IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Wrote %d 64-byte blocks\n", *blocks); - } - - /* compute epDelta - start index for binary search */ - if (epDelta != NULL) - { - UINT32 deltaIndex = 0; - - *epDelta = 0; - - for (; deltaIndex < IX_ETH_DB_MAX_DELTA_ZONES ; deltaIndex ++) - { - if (ixEthDBEPDeltaOffset[type][deltaIndex] >= maxOffset) - { - *epDelta = ixEthDBEPDelta[type][deltaIndex]; - break; - } - } - - IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Computed epDelta %d (based on maxOffset %d)\n", *epDelta, maxOffset); - } - - ixOsalCacheDmaFree(stack); -} - -/** - * @brief implements a dummy node serialization function - * - * @param address address of where the node is to be serialized (unused) - * @param node tree node to be serialized (unused) - * - * This function is registered for safety reasons and should - * never be called. It will display an error message if this - * function is called. - * - * @return none - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBNullSerialize(void *address, MacTreeNode *node) -{ - IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Warning, the NullSerialize function was called, wrong record type?\n"); -} - -/** - * @brief writes a filtering entry in NPE linear format - * - * @param address memory address to write node to - * @param node node to be written - * - * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree - * in NPE-readable format. - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBNPELearningNodeWrite(void *address, MacTreeNode *node) -{ - /* copy mac address */ - memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE); - - /* copy port ID */ - NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET) = IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(node->descriptor->portID); - - /* copy flags (valid and not active, as the NPE sets it to active) and clear reserved section (bits 2-7) */ - NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) = (UINT8) IX_EDB_FLAGS_INACTIVE_VALID; - - IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing ELT node 0x%08x:0x%08x\n", * (UINT32 *) address, * (((UINT32 *) (address)) + 1)); -} - -/** - * @brief writes a WiFi header conversion record in - * NPE linear format - * - * @param address memory address to write node to - * @param node node to be written - * - * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree - * in NPE-readable format. - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBNPEWiFiNodeWrite(void *address, MacTreeNode *node) -{ - /* copy mac address */ - memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE); - - /* copy index */ - NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET) = node->descriptor->recordData.wifiData.gwAddressIndex; - - /* copy flags (type and valid) */ - NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET) = node->descriptor->recordData.wifiData.type << 1 | IX_EDB_FLAGS_VALID; -} - -/** - * @brief writes a WiFi gateway header conversion record in - * NPE linear format - * - * @param address memory address to write node to - * @param node node to be written - * - * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree - * in NPE-readable format. - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node) -{ - /* copy mac address */ - memcpy(address, node->descriptor->recordData.wifiData.gwMacAddress, IX_IEEE803_MAC_ADDRESS_SIZE); - - /* set reserved field, two bytes */ - NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0; - NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET + 1) = 0; -} - -/** - * @brief writes a firewall record in - * NPE linear format - * - * @param address memory address to write node to - * @param node node to be written - * - * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree - * in NPE-readable format. - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBNPEFirewallNodeWrite(void *address, MacTreeNode *node) -{ - /* set reserved field */ - NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0; - - /* set flags */ - NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_FLAGS_OFFSET) = IX_EDB_FLAGS_VALID; - - /* copy mac address */ - memcpy((void *) ((UINT32) address + IX_EDB_NPE_NODE_FW_ADDR_OFFSET), node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE); -} - -/** - * @brief registers the NPE serialization methods - * - * This functions registers NPE serialization methods - * for writing the following types of records in NPE - * readable linear format: - * - filtering records - * - WiFi header conversion records - * - WiFi gateway header conversion records - * - firewall records - * - * Note that this function should be called by the - * component initialization function. - * - * @return number of registered record types - * - * @internal - */ -IX_ETH_DB_PUBLIC -UINT32 ixEthDBRecordSerializeMethodsRegister() -{ - int i; - - /* safety - register a blank method for everybody first */ - for ( i = 0 ; i < IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1 ; i++) - { - ixEthDBNPENodeWrite[i] = ixEthDBNullSerialize; - } - - /* register real methods */ - ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_RECORD] = ixEthDBNPELearningNodeWrite; - ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_VLAN_RECORD] = ixEthDBNPELearningNodeWrite; - ixEthDBNPENodeWrite[IX_ETH_DB_WIFI_RECORD] = ixEthDBNPEWiFiNodeWrite; - ixEthDBNPENodeWrite[IX_ETH_DB_FIREWALL_RECORD] = ixEthDBNPEFirewallNodeWrite; - ixEthDBNPENodeWrite[IX_ETH_DB_GATEWAY_RECORD] = ixEthDBNPEGatewayNodeWrite; - - /* EP Delta arrays */ - memset(ixEthDBEPDeltaOffset, 0, sizeof (ixEthDBEPDeltaOffset)); - memset(ixEthDBEPDelta, 0, sizeof (ixEthDBEPDelta)); - - /* filtering records */ - ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][0] = 1; - ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][0] = 0; - - ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][1] = 3; - ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][1] = 7; - - ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][2] = 511; - ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][2] = 14; - - /* wifi records */ - ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][0] = 1; - ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][0] = 0; - - ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][1] = 3; - ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][1] = 7; - - ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][2] = 511; - ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][2] = 14; - - /* firewall records */ - ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][0] = 0; - ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][0] = 0; - - ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][1] = 1; - ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][1] = 5; - - ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][2] = 3; - ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][2] = 13; - - ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][3] = 7; - ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][3] = 21; - - ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][4] = 15; - ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][4] = 29; - - ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][5] = 31; - ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][5] = 37; - - return 5; /* 5 methods registered */ -} - -#ifndef IX_NDEBUG - -IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2]; -IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen = 0; - -/** - * When compiled in DEBUG mode, this function can be used to display - * the history of messages sent to the NPEs (up to 100). - */ -IX_ETH_DB_PUBLIC -void ixEthDBShowNpeMsgHistory() -{ - UINT32 i = 0; - UINT32 base, len; - - if (npeMsgHistoryLen <= IX_ETH_DB_NPE_MSG_HISTORY_DEPTH) - { - base = 0; - len = npeMsgHistoryLen; - } - else - { - base = npeMsgHistoryLen % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; - len = IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; - } - - printf("NPE message history [last %d messages, from least to most recent]:\n", len); - - for (; i < len ; i++) - { - UINT32 pos = (base + i) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; - printf("msg[%d]: 0x%08x:0x%08x\n", i, npeMsgHistory[pos][0], npeMsgHistory[pos][1]); - } -} - -IX_ETH_DB_PUBLIC -void ixEthDBELTShow(IxEthDBPortId portID) -{ - IxNpeMhMessage message; - IX_STATUS result; - - /* send EDB_GetMACAddressDatabase message */ - FILL_GETMACADDRESSDATABASE(message, - 0 /* reserved */, - IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portID].updateMethod.npeUpdateZone)); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - if (result == IX_SUCCESS) - { - /* analyze NPE copy */ - UINT32 eltEntryOffset; - UINT32 entryPortID; - - UINT32 eltBaseAddress = (UINT32) ixEthDBPortInfo[portID].updateMethod.npeUpdateZone; - UINT32 eltSize = FULL_ELT_BYTE_SIZE; - - /* invalidate cache */ - IX_OSAL_CACHE_INVALIDATE((void *) eltBaseAddress, eltSize); - - printf("Listing records in main learning tree for port %d\n", portID); - - for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE) - { - /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node - * - * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit] - * therefore we can just use the pointer for database searches as only the first 6 bytes are checked - */ - void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset); - - if (IX_EDB_NPE_NODE_VALID(eltNodeAddress)) - { - HashNode *node; - - entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress)); - - /* search record */ - node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_RECORD_TYPES); - - printf("%s - port %d - %s ", mac2string((unsigned char *) eltNodeAddress), entryPortID, - IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) ? "active" : "inactive"); - - /* safety check, maybe user deleted record right before sync? */ - if (node != NULL) - { - /* found record */ - MacDescriptor *descriptor = (MacDescriptor *) node->data; - - printf("- %s ", - descriptor->type == IX_ETH_DB_FILTERING_RECORD ? "filtering" : - descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD ? "vlan" : - descriptor->type == IX_ETH_DB_WIFI_RECORD ? "wifi" : "other (check main DB)"); - - if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) printf("- age %d - %s ", - descriptor->recordData.filteringData.age, - descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic"); - - if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) printf("- age %d - %s - tci %d ", - descriptor->recordData.filteringVlanData.age, - descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic", - descriptor->recordData.filteringVlanData.ieee802_1qTag); - - /* end transaction */ - ixEthDBReleaseHashNode(node); - } - else - { - printf("- not synced"); - } - - printf("\n"); - } - } - } - else - { - ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT, - "EthDB: (ShowELT) Could not complete action (communication failure)\n", - portID, 0, 0, 0, 0, 0); - } -} - -#endif diff --git a/arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c b/arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c deleted file mode 100644 index cdf114b..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBPortUpdate.c +++ /dev/null @@ -1,740 +0,0 @@ -/** - * @file IxEthDBDBPortUpdate.c - * - * @brief Implementation of dependency and port update handling - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxEthDB_p.h" - -/* forward prototype declarations */ -IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor); -IX_ETH_DB_PRIVATE void ixEthDBCreateTrees(IxEthDBPortMap updatePorts); -IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree); -IX_ETH_DB_PRIVATE void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size); -IX_ETH_DB_PRIVATE void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size); -IX_ETH_DB_PRIVATE void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count); -IX_ETH_DB_PRIVATE UINT32 ixEthDBRebalanceLog2Floor(UINT32 x); - -extern HashTable dbHashtable; - -/** - * @brief register types requiring automatic updates - * - * @param typeArray array indexed on record types, each - * element indicating whether the record type requires an - * automatic update (TRUE) or not (FALSE) - * - * Automatic updates are done for registered record types - * upon adding, updating (that is, updating the record portID) - * and removing records. Whenever an automatic update is triggered - * the appropriate ports will be provided with new database - * information. - * - * It is assumed that the typeArray parameter is allocated large - * enough to hold all the user defined types. Also, the type - * array should be initialized to FALSE as this function only - * caters for types which do require automatic updates. - * - * Note that this function should be called by the component - * initialization function. - * - * @return number of record types registered for automatic - * updates - * - * @internal - */ -IX_ETH_DB_PUBLIC -UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray) -{ - typeArray[IX_ETH_DB_FILTERING_RECORD] = TRUE; - typeArray[IX_ETH_DB_FILTERING_VLAN_RECORD] = TRUE; - - return 2; -} - -/** - * @brief computes dependencies and triggers port learning tree updates - * - * @param triggerPorts port map consisting in the ports which triggered the update - * - * This function browses through all the ports and determines how to waterfall the update - * event from the trigger ports to all other ports depending on them. - * - * Once the list of ports to be updated is determined this function - * calls @ref ixEthDBCreateTrees. - * - * @internal - */ -IX_ETH_DB_PUBLIC -void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts) -{ - IxEthDBPortMap updatePorts; - UINT32 portIndex; - - ixEthDBUpdateLock(); - - SET_EMPTY_DEPENDENCY_MAP(updatePorts); - - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - PortInfo *port = &ixEthDBPortInfo[portIndex]; - BOOL mapsCollide; - - MAPS_COLLIDE(mapsCollide, triggerPorts, port->dependencyPortMap); - - if (mapsCollide /* do triggers influence this port? */ - && !IS_PORT_INCLUDED(portIndex, updatePorts) /* and it's not already in the update list */ - && port->updateMethod.updateEnabled) /* and we're allowed to update it */ - { - IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding port %d to update set\n", portIndex); - - JOIN_PORT_TO_MAP(updatePorts, portIndex); - } - else - { - IX_ETH_DB_UPDATE_TRACE("DB: (Update) Didn't add port %d to update set, reasons follow:\n", portIndex); - - if (!mapsCollide) - { - IX_ETH_DB_UPDATE_TRACE("\tMaps don't collide on port %d\n", portIndex); - } - - if (IS_PORT_INCLUDED(portIndex, updatePorts)) - { - IX_ETH_DB_UPDATE_TRACE("\tPort %d is already in the update set\n", portIndex); - } - - if (!port->updateMethod.updateEnabled) - { - IX_ETH_DB_UPDATE_TRACE("\tPort %d doesn't have updateEnabled set\n", portIndex); - } - } - } - - IX_ETH_DB_UPDATE_TRACE("DB: (Update) Updating port set\n"); - - ixEthDBCreateTrees(updatePorts); - - ixEthDBUpdateUnlock(); -} - -/** - * @brief creates learning trees and calls the port update handlers - * - * @param updatePorts set of ports in need of learning trees - * - * This function determines the optimal method of creating learning - * trees using a minimal number of database queries, keeping in mind - * that different ports can either use the same learning trees or they - * can partially share them. The actual tree building routine is - * @ref ixEthDBQuery. - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBCreateTrees(IxEthDBPortMap updatePorts) -{ - UINT32 portIndex; - BOOL result; - BOOL portsLeft = TRUE; - - while (portsLeft) - { - /* get port with minimal dependency map and NULL search tree */ - UINT32 minPortIndex = MAX_PORT_SIZE; - UINT32 minimalSize = MAX_PORT_SIZE; - - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - UINT32 size; - PortInfo *port = &ixEthDBPortInfo[portIndex]; - - /* generate trees only for ports that need them */ - if (!port->updateMethod.searchTreePendingWrite && IS_PORT_INCLUDED(portIndex, updatePorts)) - { - GET_MAP_SIZE(port->dependencyPortMap, size); - - IX_ETH_DB_UPDATE_TRACE("DB: (Update) Dependency map for port %d: size %d\n", - portIndex, size); - - if (size < minimalSize) - { - minPortIndex = portIndex; - minimalSize = size; - } - } - else - { - IX_ETH_DB_UPDATE_TRACE("DB: (Update) Skipped port %d from tree diff (%s)\n", portIndex, - port->updateMethod.searchTreePendingWrite ? "pending write access" : "ignored by query"); - } - } - - /* if a port was found than minimalSize is not MAX_PORT_SIZE */ - if (minimalSize != MAX_PORT_SIZE) - { - /* minPortIndex is the port we seek */ - PortInfo *port = &ixEthDBPortInfo[minPortIndex]; - - IxEthDBPortMap query; - MacTreeNode *baseTree; - - /* now try to find a port with minimal map difference */ - PortInfo *minimalDiffPort = NULL; - UINT32 minimalDiff = MAX_PORT_SIZE; - - IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal size port is %d\n", minPortIndex); - - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - PortInfo *diffPort = &ixEthDBPortInfo[portIndex]; - BOOL mapIsSubset; - - IS_MAP_SUBSET(mapIsSubset, diffPort->dependencyPortMap, port->dependencyPortMap); - - - if (portIndex != minPortIndex - && diffPort->updateMethod.searchTree != NULL - && mapIsSubset) - { - /* compute size and pick only minimal size difference */ - UINT32 diffPortSize; - UINT32 sizeDifference; - - GET_MAP_SIZE(diffPort->dependencyPortMap, diffPortSize); - - IX_ETH_DB_UPDATE_TRACE("DB: (Update) Checking port %d for differences...\n", portIndex); - - sizeDifference = minimalSize - diffPortSize; - - if (sizeDifference < minimalDiff) - { - minimalDiffPort = diffPort; - minimalDiff = sizeDifference; - - IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal difference 0x%x was found on port %d\n", - minimalDiff, portIndex); - } - } - } - - /* check if filtering is enabled on this port */ - if ((port->featureStatus & IX_ETH_DB_FILTERING) != 0) - { - /* if minimalDiff is not MAX_PORT_SIZE minimalDiffPort points to the most similar port */ - if (minimalDiff != MAX_PORT_SIZE) - { - baseTree = ixEthDBCloneMacTreeNode(minimalDiffPort->updateMethod.searchTree); - DIFF_MAPS(query, port->dependencyPortMap , minimalDiffPort->dependencyPortMap); - - IX_ETH_DB_UPDATE_TRACE("DB: (Update) Found minimal diff, extending tree %d on query\n", - minimalDiffPort->portID); - } - else /* .. otherwise no similar port was found, build tree from scratch */ - { - baseTree = NULL; - - COPY_DEPENDENCY_MAP(query, port->dependencyPortMap); - - IX_ETH_DB_UPDATE_TRACE("DB: (Update) No similar diff, creating tree from query\n"); - } - - IS_EMPTY_DEPENDENCY_MAP(result, query); - - if (!result) /* otherwise we don't need anything more on top of the cloned tree */ - { - IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding query tree to port %d\n", minPortIndex); - - /* build learning tree */ - port->updateMethod.searchTree = ixEthDBQuery(baseTree, query, IX_ETH_DB_ALL_FILTERING_RECORDS, MAX_ELT_SIZE); - } - else - { - IX_ETH_DB_UPDATE_TRACE("DB: (Update) Query is empty, assuming identical nearest tree\n"); - - port->updateMethod.searchTree = baseTree; - } - } - else - { - /* filtering is not enabled, will download an empty tree */ - if (port->updateMethod.searchTree != NULL) - { - ixEthDBFreeMacTreeNode(port->updateMethod.searchTree); - } - - port->updateMethod.searchTree = NULL; - } - - /* mark tree as valid */ - port->updateMethod.searchTreePendingWrite = TRUE; - } - else - { - portsLeft = FALSE; - - IX_ETH_DB_UPDATE_TRACE("DB: (Update) No trees to create this round\n"); - } - } - - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - PortInfo *updatePort = &ixEthDBPortInfo[portIndex]; - - if (updatePort->updateMethod.searchTreePendingWrite) - { - IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Starting procedure to upload new search tree (%snull) into NPE %d\n", - updatePort->updateMethod.searchTree != NULL ? "not " : "", - portIndex); - - updatePort->updateMethod.updateHandler(portIndex, IX_ETH_DB_FILTERING_RECORD); - } - } -} - -/** - * @brief standard NPE update handler - * - * @param portID id of the port to be updated - * @param type record type to be pushed during this update - * - * The NPE update handler manages updating the NPE databases - * given a certain record type. - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type) -{ - UINT32 epDelta, blockCount; - IxNpeMhMessage message; - UINT32 treeSize = 0; - PortInfo *port = &ixEthDBPortInfo[portID]; - - /* size selection and type check */ - if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD) - { - treeSize = FULL_ELT_BYTE_SIZE; - } - else if (type == IX_ETH_DB_FIREWALL_RECORD) - { - treeSize = FULL_FW_BYTE_SIZE; - } - else - { - return IX_ETH_DB_INVALID_ARG; - } - - /* serialize tree into memory */ - ixEthDBNPETreeWrite(type, treeSize, port->updateMethod.npeUpdateZone, port->updateMethod.searchTree, &epDelta, &blockCount); - - /* free internal copy */ - if (port->updateMethod.searchTree != NULL) - { - ixEthDBFreeMacTreeNode(port->updateMethod.searchTree); - } - - /* forget last used search tree */ - port->updateMethod.searchTree = NULL; - port->updateMethod.searchTreePendingWrite = FALSE; - - /* dependending on the update type we do different things */ - if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD) - { - IX_STATUS result; - - FILL_SETMACADDRESSDATABASE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), - epDelta, blockCount, - IX_OSAL_MMU_VIRT_TO_PHYS(port->updateMethod.npeUpdateZone)); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - if (result == IX_SUCCESS) - { - IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Finished downloading NPE tree on port %d\n", portID); - } - else - { - ixEthDBPortInfo[portID].agingEnabled = FALSE; - ixEthDBPortInfo[portID].updateMethod.updateEnabled = FALSE; - ixEthDBPortInfo[portID].updateMethod.userControlled = TRUE; - - ERROR_LOG("EthDB: (PortUpdate) disabling aging and updates on port %d (assumed dead)\n", portID); - - ixEthDBDatabaseClear(portID, IX_ETH_DB_ALL_RECORD_TYPES); - - return IX_ETH_DB_FAIL; - } - - return IX_ETH_DB_SUCCESS; - } - else if (type == IX_ETH_DB_FIREWALL_RECORD) - { - return ixEthDBFirewallUpdate(portID, port->updateMethod.npeUpdateZone, epDelta); - } - - return IX_ETH_DB_INVALID_ARG; -} - -/** - * @brief queries the database for a set of records to be inserted into a given tree - * - * @param searchTree pointer to a tree where insertions will be performed; can be NULL - * @param query set of ports that a database record must match to be inserted into the tree - * - * The query method browses through the database, extracts all the descriptors matching - * the given query parameter and inserts them into the given learning tree. - * Note that this is an append procedure, the given tree needs not to be empty. - * A "descriptor matching the query" is a descriptor whose port id is in the query map. - * If the given tree is empty (NULL) a new tree is created and returned. - * - * @return the tree root - * - * @internal - */ -IX_ETH_DB_PUBLIC -MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maxEntries) -{ - HashIterator iterator; - UINT32 entryCount = 0; - - /* browse database */ - BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); - - while (IS_ITERATOR_VALID(&iterator)) - { - MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; - - IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) querying [%s]:%d on port map ... ", - mac2string(descriptor->macAddress), - descriptor->portID); - - if ((descriptor->type & recordFilter) != 0 - && IS_PORT_INCLUDED(descriptor->portID, query)) - { - MacDescriptor *descriptorClone = ixEthDBCloneMacDescriptor(descriptor); - - IX_ETH_DB_UPDATE_TRACE("match\n"); - - if (descriptorClone != NULL) - { - /* add descriptor to tree */ - searchTree = ixEthDBTreeInsert(searchTree, descriptorClone); - - entryCount++; - } - } - else - { - IX_ETH_DB_UPDATE_TRACE("no match\n"); - } - - if (entryCount < maxEntries) - { - /* advance to the next record */ - BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); - } - else - { - /* the NPE won't accept more entries so we can stop now */ - ixEthDBReleaseHashIterator(&iterator); - - IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) number of elements reached maximum supported by port\n"); - - break; - } - } - - IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) query inserted %d records in the search tree\n", entryCount); - - return ixEthDBTreeRebalance(searchTree); -} - -/** - * @brief inserts a mac descriptor into an tree - * - * @param searchTree tree where the insertion is to be performed (may be NULL) - * @param descriptor descriptor to insert into tree - * - * @return the tree root - * - * @internal - */ -IX_ETH_DB_PRIVATE -MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor) -{ - MacTreeNode *currentNode = searchTree; - MacTreeNode *insertLocation = NULL; - MacTreeNode *newNode; - INT32 insertPosition = RIGHT; - - if (descriptor == NULL) - { - return searchTree; - } - - /* create a new node */ - newNode = ixEthDBAllocMacTreeNode(); - - if (newNode == NULL) - { - /* out of memory */ - ERROR_LOG("Warning: ixEthDBAllocMacTreeNode returned NULL in file %s:%d (out of memory?)\n", __FILE__, __LINE__); - - ixEthDBFreeMacDescriptor(descriptor); - - return NULL; - } - - /* populate node */ - newNode->descriptor = descriptor; - - /* an empty initial tree is a special case */ - if (searchTree == NULL) - { - return newNode; - } - - /* get insertion location */ - while (insertLocation == NULL) - { - MacTreeNode *nextNode; - - /* compare given key with current node key */ - insertPosition = ixEthDBAddressCompare(descriptor->macAddress, currentNode->descriptor->macAddress); - - /* navigate down */ - if (insertPosition == RIGHT) - { - nextNode = currentNode->right; - } - else if (insertPosition == LEFT) - { - nextNode = currentNode->left; - } - else - { - /* error, duplicate key */ - ERROR_LOG("Warning: trapped insertion of a duplicate MAC address in an NPE search tree\n"); - - /* this will free the MAC descriptor as well */ - ixEthDBFreeMacTreeNode(newNode); - - return searchTree; - } - - /* when we can no longer dive through the tree we found the insertion place */ - if (nextNode != NULL) - { - currentNode = nextNode; - } - else - { - insertLocation = currentNode; - } - } - - /* insert node */ - if (insertPosition == RIGHT) - { - insertLocation->right = newNode; - } - else - { - insertLocation->left = newNode; - } - - return searchTree; -} - -/** - * @brief balance a tree - * - * @param searchTree tree to balance - * - * Converts a tree into a balanced tree and returns the root of - * the balanced tree. The resulting tree is route balanced - * not perfectly balanced. This makes no difference to the - * average tree search time which is the same in both cases, O(log2(n)). - * - * @return root of the balanced tree or NULL if there's no memory left - * - * @internal - */ -IX_ETH_DB_PRIVATE -MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree) -{ - MacTreeNode *pseudoRoot = ixEthDBAllocMacTreeNode(); - UINT32 size; - - if (pseudoRoot == NULL) - { - /* out of memory */ - return NULL; - } - - pseudoRoot->right = searchTree; - - ixEthDBRebalanceTreeToVine(pseudoRoot, &size); - ixEthDBRebalanceVineToTree(pseudoRoot, size); - - searchTree = pseudoRoot->right; - - /* remove pseudoRoot right branch, otherwise it will free the entire tree */ - pseudoRoot->right = NULL; - - ixEthDBFreeMacTreeNode(pseudoRoot); - - return searchTree; -} - -/** - * @brief converts a tree into a vine - * - * @param root root of tree to convert - * @param size depth of vine (equal to the number of nodes in the tree) - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size) -{ - MacTreeNode *vineTail = root; - MacTreeNode *remainder = vineTail->right; - MacTreeNode *tempPtr; - - *size = 0; - - while (remainder != NULL) - { - if (remainder->left == NULL) - { - /* move tail down one */ - vineTail = remainder; - remainder = remainder->right; - (*size)++; - } - else - { - /* rotate around remainder */ - tempPtr = remainder->left; - remainder->left = tempPtr->right; - tempPtr->right = remainder; - remainder = tempPtr; - vineTail->right = tempPtr; - } - } -} - -/** - * @brief converts a vine into a balanced tree - * - * @param root vine to convert - * @param size depth of vine - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size) -{ - UINT32 leafCount = size + 1 - (1 << ixEthDBRebalanceLog2Floor(size + 1)); - - ixEthDBRebalanceCompression(root, leafCount); - - size = size - leafCount; - - while (size > 1) - { - ixEthDBRebalanceCompression(root, size / 2); - - size /= 2; - } -} - -/** - * @brief compresses a vine/tree stage into a more balanced vine/tree - * - * @param root root of the tree to compress - * @param count number of "spine" nodes - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count) -{ - MacTreeNode *scanner = root; - MacTreeNode *child; - UINT32 local_index; - - for (local_index = 0 ; local_index < count ; local_index++) - { - child = scanner->right; - scanner->right = child->right; - scanner = scanner->right; - child->right = scanner->left; - scanner->left = child; - } -} - -/** - * @brief computes |_log2(x)_| (a.k.a. floor(log2(x))) - * - * @param x number to compute |_log2(x)_| for - * - * @return |_log2(x)_| - * - * @internal - */ -IX_ETH_DB_PRIVATE -UINT32 ixEthDBRebalanceLog2Floor(UINT32 x) -{ - UINT32 log = 0; - UINT32 val = 1; - - while (val < x) - { - log++; - val <<= 1; - } - - return val == x ? log : log - 1; -} - diff --git a/arch/arm/cpu/ixp/npe/IxEthDBReports.c b/arch/arm/cpu/ixp/npe/IxEthDBReports.c deleted file mode 100644 index 9c7ae1c..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBReports.c +++ /dev/null @@ -1,652 +0,0 @@ -/** - * @file IxEthDBAPI.c - * - * @brief Implementation of the public API - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxEthDB_p.h" - -extern HashTable dbHashtable; -IX_ETH_DB_PRIVATE void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter); -IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map); - -/** - * @brief displays a port dependency map - * - * @param portID ID of the port - * @param map port map to display - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map) -{ - UINT32 portIndex; - BOOL mapSelf = TRUE, mapNone = TRUE, firstPort = TRUE; - - /* dependency port maps */ - printf("Dependency port map: "); - - /* browse the port map */ - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - if (IS_PORT_INCLUDED(portIndex, map)) - { - mapNone = FALSE; - - if (portIndex != portID) - { - mapSelf = FALSE; - } - - printf("%s%d", firstPort ? "{" : ", ", portIndex); - - firstPort = FALSE; - } - } - - if (mapNone) - { - mapSelf = FALSE; - } - - printf("%s (%s)\n", firstPort ? "" : "}", mapSelf ? "self" : mapNone ? "none" : "group"); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief displays all the filtering records belonging to a port - * - * @param portID ID of the port to display - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords() - * instead. Calling this function is equivalent to calling - * ixEthDBFilteringDatabaseShowRecords(portID, IX_ETH_DB_FILTERING_RECORD) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID) -{ - IxEthDBStatus local_result; - HashIterator iterator; - PortInfo *portInfo; - UINT32 recordCount = 0; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - portInfo = &ixEthDBPortInfo[portID]; - - /* display table header */ - printf("Ethernet database records for port ID [%d]\n", portID); - - ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap); - - if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) - { - printf("NPE updates are %s\n\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled"); - } - else - { - printf("updates disabled (not an NPE)\n\n"); - } - - printf(" MAC address | Age | Type \n"); - printf("___________________________________\n"); - - /* browse database */ - BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); - - while (IS_ITERATOR_VALID(&iterator)) - { - MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; - - if (descriptor->portID == portID && descriptor->type == IX_ETH_DB_FILTERING_RECORD) - { - recordCount++; - - /* display entry */ - printf(" %02X:%02X:%02X:%02X:%02X:%02X | %5d | %s\n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5], - descriptor->recordData.filteringData.age, - descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic"); - } - - /* move to the next record */ - BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result); - - /* debug */ - if (local_result == IX_ETH_DB_BUSY) - { - return IX_ETH_DB_FAIL; - } - } - - /* display number of records */ - printf("\nFound %d records\n", recordCount); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief displays all the filtering records belonging to all the ports - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords() - * instead. Calling this function is equivalent to calling - * ixEthDBFilteringDatabaseShowRecords(IX_ETH_DB_ALL_PORTS, IX_ETH_DB_FILTERING_RECORD) - */ -IX_ETH_DB_PUBLIC -void ixEthDBFilteringDatabaseShowAll() -{ - IxEthDBPortId portIndex; - - printf("\nEthernet learning/filtering database: listing %d ports\n\n", (UINT32) IX_ETH_DB_NUMBER_OF_PORTS); - - for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) - { - ixEthDBFilteringDatabaseShow(portIndex); - - if (portIndex < IX_ETH_DB_NUMBER_OF_PORTS - 1) - { - printf("\n"); - } - } -} - -/** - * @brief displays one record in a format depending on the record filter - * - * @param descriptor pointer to the record - * @param recordFilter format filter - * - * This function will display the fields in a record depending on the - * selected record filter. - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBRecordShow(MacDescriptor *descriptor, IxEthDBRecordType recordFilter) -{ - if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD - || recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD)) - { - /* display VLAN record header - leave this commented code in place, its purpose is to align the print format with the header - printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n"); - printf("___________________________________________________________________\n"); */ - - if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) - { - printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | %d | %d | %d\n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5], - descriptor->recordData.filteringVlanData.age, - descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic", - IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag), - (descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12, - IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag)); - } - else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) - { - printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | - | - | -\n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5], - descriptor->recordData.filteringData.age, - descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic"); - } - } - else if (recordFilter == IX_ETH_DB_FILTERING_RECORD) - { - /* display filtering record header - leave this commented code in place, its purpose is to align the print format with the header - printf(" MAC address | Age | Type \n"); - printf("_______________________________________\n"); */ - - if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) - { - printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s \n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5], - descriptor->recordData.filteringData.age, - descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic"); - } - } - else if (recordFilter == IX_ETH_DB_WIFI_RECORD) - { - /* display WiFi record header - leave this commented code in place, its purpose is to align the print format with the header - printf(" MAC address | GW MAC address \n"); - printf("_______________________________________\n"); */ - - if (descriptor->type == IX_ETH_DB_WIFI_RECORD) - { - if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP) - { - /* gateway address present */ - printf("%02X:%02X:%02X:%02X:%02X:%02X | %02X:%02X:%02X:%02X:%02X:%02X \n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5], - descriptor->recordData.wifiData.gwMacAddress[0], - descriptor->recordData.wifiData.gwMacAddress[1], - descriptor->recordData.wifiData.gwMacAddress[2], - descriptor->recordData.wifiData.gwMacAddress[3], - descriptor->recordData.wifiData.gwMacAddress[4], - descriptor->recordData.wifiData.gwMacAddress[5]); - } - else - { - /* no gateway */ - printf("%02X:%02X:%02X:%02X:%02X:%02X | ----no gateway----- \n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5]); - } - } - } - else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD) - { - /* display Firewall record header - leave this commented code in place, its purpose is to align the print format with the header - printf(" MAC address \n"); - printf("__________________\n"); */ - - if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD) - { - printf("%02X:%02X:%02X:%02X:%02X:%02X \n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5]); - } - } - else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES) - { - /* display composite record header - leave this commented code in place, its purpose is to align the print format with the header - printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n"); - printf("_______________________________________________________________________________\n"); */ - - if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) - { - printf("%02X:%02X:%02X:%02X:%02X:%02X | VLAN | %2d | %s | %4d | %1d | %1d | -----------------\n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5], - descriptor->recordData.filteringVlanData.age, - descriptor->recordData.filteringVlanData.staticEntry ? "static " : "dynamic", - IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag), - (descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12, - IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag)); - } - else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) - { - printf("%02X:%02X:%02X:%02X:%02X:%02X | Filter | %2d | %s | ---- | - | --- | -----------------\n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5], - descriptor->recordData.filteringData.age, - descriptor->recordData.filteringData.staticEntry ? "static " : "dynamic"); - } - else if (descriptor->type == IX_ETH_DB_WIFI_RECORD) - { - if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP) - { - /* gateway address present */ - printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>AP | ---- | - | --- | %02X:%02X:%02X:%02X:%02X:%02X\n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5], - descriptor->recordData.wifiData.gwMacAddress[0], - descriptor->recordData.wifiData.gwMacAddress[1], - descriptor->recordData.wifiData.gwMacAddress[2], - descriptor->recordData.wifiData.gwMacAddress[3], - descriptor->recordData.wifiData.gwMacAddress[4], - descriptor->recordData.wifiData.gwMacAddress[5]); - } - else - { - /* no gateway */ - printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>ST | ---- | - | --- | -- no gateway -- \n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5]); - } - } - else if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD) - { - printf("%02X:%02X:%02X:%02X:%02X:%02X | FW | -- | ------- | ---- | - | --- | -----------------\n", - descriptor->macAddress[0], - descriptor->macAddress[1], - descriptor->macAddress[2], - descriptor->macAddress[3], - descriptor->macAddress[4], - descriptor->macAddress[5]); - } - } - else - { - printf("invalid record filter\n"); - } -} - -/** - * @brief displays the status, records and configuration information of a port - * - * @param portID ID of the port - * @param recordFilter record filter to display - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter) -{ - PortInfo *portInfo = &ixEthDBPortInfo[portID]; - UINT32 recordCount = 0; - HashIterator iterator; - IxEthDBStatus local_result; - - /* display port status */ - printf("== Port ID %d ==\n", portID); - - /* display capabilities */ - printf("- Capabilities: "); - - if ((portInfo->featureCapability & IX_ETH_DB_LEARNING) != 0) - { - printf("Learning (%s) ", ((portInfo->featureStatus & IX_ETH_DB_LEARNING) != 0) ? "on" : "off"); - } - - if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) - { - printf("VLAN/QoS (%s) ", ((portInfo->featureStatus & IX_ETH_DB_VLAN_QOS) != 0) ? "on" : "off"); - } - - if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0) - { - printf("Firewall (%s) ", ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0) ? "on" : "off"); - } - - if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) - { - printf("WiFi (%s) ", ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) ? "on" : "off"); - } - - if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) - { - printf("STP (%s) ", ((portInfo->featureStatus & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) ? "on" : "off"); - } - - printf("\n"); - - /* dependency map */ - ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap); - - /* NPE dynamic updates */ - if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) - { - printf(" - NPE dynamic update is %s\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled"); - } - else - { - printf(" - dynamic update disabled (not an NPE)\n"); - } - - if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) - { - if ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) - { - /* WiFi header conversion */ - if ((portInfo->frameControlDurationID - + portInfo->bbsid[0] - + portInfo->bbsid[1] - + portInfo->bbsid[2] - + portInfo->bbsid[3] - + portInfo->bbsid[4] - + portInfo->bbsid[5]) == 0) - { - printf(" - WiFi header conversion not configured\n"); - } - else - { - printf(" - WiFi header conversion: BBSID [%02X:%02X:%02X:%02X:%02X:%02X], Frame Control 0x%X, Duration/ID 0x%X\n", - portInfo->bbsid[0], - portInfo->bbsid[1], - portInfo->bbsid[2], - portInfo->bbsid[3], - portInfo->bbsid[4], - portInfo->bbsid[5], - portInfo->frameControlDurationID >> 16, - portInfo->frameControlDurationID & 0xFFFF); - } - } - else - { - printf(" - WiFi header conversion not enabled\n"); - } - } - - /* Firewall */ - if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0) - { - if ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0) - { - printf(" - Firewall is in %s-list mode\n", portInfo->firewallMode == IX_ETH_DB_FIREWALL_BLACK_LIST ? "black" : "white"); - printf(" - Invalid source MAC address filtering is %s\n", portInfo->srcAddressFilterEnabled ? "enabled" : "disabled"); - } - else - { - printf(" - Firewall not enabled\n"); - } - } - - /* browse database if asked to display records */ - if (recordFilter != IX_ETH_DB_NO_RECORD_TYPE) - { - printf("\n"); - ixEthDBHeaderShow(recordFilter); - - BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); - - while (IS_ITERATOR_VALID(&iterator)) - { - MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; - - if (descriptor->portID == portID && (descriptor->type & recordFilter) != 0) - { - recordCount++; - - /* display entry */ - ixEthDBRecordShow(descriptor, recordFilter); - } - - /* move to the next record */ - BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result); - - /* debug */ - if (local_result == IX_ETH_DB_BUSY) - { - printf("EthDB (API): Error, database browser failed (no access), giving up\n"); - } - } - - printf("\nFound %d records\n\n", recordCount); - } -} - -/** - * @brief displays a record header - * - * @param recordFilter record type filter - * - * This function displays a record header, depending on - * the given record type filter. It is useful when used - * in conjunction with ixEthDBRecordShow which will display - * record fields formatted for the header, provided the same - * record filter is used. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or IX_ETH_DB_INVALID_ARG if the recordFilter - * parameter is invalid or not supported - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter) -{ - if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD - || recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD)) - { - /* display VLAN record header */ - printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n"); - printf("___________________________________________________________________\n"); - } - else if (recordFilter == IX_ETH_DB_FILTERING_RECORD) - { - /* display filtering record header */ - printf(" MAC address | Age | Type \n"); - printf("_______________________________________\n"); - } - else if (recordFilter == IX_ETH_DB_WIFI_RECORD) - { - /* display WiFi record header */ - printf(" MAC address | GW MAC address \n"); - printf("_______________________________________\n"); - } - else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD) - { - /* display Firewall record header */ - printf(" MAC address \n"); - printf("__________________\n"); - } - else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES) - { - /* display composite record header */ - printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n"); - printf("_______________________________________________________________________________\n"); - } - else - { - return IX_ETH_DB_INVALID_ARG; - } - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief displays database information (records and port information) - * - * @param portID ID of the port to display (or IX_ETH_DB_ALL_PORTS for all the ports) - * @param recordFilter record filter (use IX_ETH_DB_NO_RECORD_TYPE to display only - * port information) - * - * Note that this function is documented in the main component header - * file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully or - * an appropriate error code otherwise - * - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter) -{ - IxEthDBPortId currentPort; - BOOL showAllPorts = (portID == IX_ETH_DB_ALL_PORTS); - - IX_ETH_DB_CHECK_PORT_ALL(portID); - - printf("\nEthernet learning/filtering database: listing %d port(s)\n\n", showAllPorts ? (UINT32) IX_ETH_DB_NUMBER_OF_PORTS : 1); - - currentPort = showAllPorts ? 0 : portID; - - while (currentPort != IX_ETH_DB_NUMBER_OF_PORTS) - { - /* display port info */ - ixEthDBPortInfoShow(currentPort, recordFilter); - - /* next port */ - currentPort = showAllPorts ? currentPort + 1 : IX_ETH_DB_NUMBER_OF_PORTS; - } - - return IX_ETH_DB_SUCCESS; -} - diff --git a/arch/arm/cpu/ixp/npe/IxEthDBSearch.c b/arch/arm/cpu/ixp/npe/IxEthDBSearch.c deleted file mode 100644 index 4a10878..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBSearch.c +++ /dev/null @@ -1,327 +0,0 @@ -/** - * @file IxEthDBSearch.c - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxEthDB_p.h" - -extern HashTable dbHashtable; - -/** - * @brief matches two database records based on their MAC addresses - * - * @param untypedReference record to match against - * @param untypedEntry record to match - * - * @return TRUE if the match is successful or FALSE otherwise - * - * @internal - */ -IX_ETH_DB_PUBLIC -BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry) -{ - MacDescriptor *entry = (MacDescriptor *) untypedEntry; - MacDescriptor *reference = (MacDescriptor *) untypedReference; - - /* check accepted record types */ - if ((entry->type & reference->type) == 0) return FALSE; - - return (ixEthDBAddressCompare((UINT8 *) entry->macAddress, (UINT8 *) reference->macAddress) == 0); -} - -/** - * @brief matches two database records based on their MAC addresses - * and VLAN IDs - * - * @param untypedReference record to match against - * @param untypedEntry record to match - * - * @return TRUE if the match is successful or FALSE otherwise - * - * @internal - */ -IX_ETH_DB_PUBLIC -BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry) -{ - MacDescriptor *entry = (MacDescriptor *) untypedEntry; - MacDescriptor *reference = (MacDescriptor *) untypedReference; - - /* check accepted record types */ - if ((entry->type & reference->type) == 0) return FALSE; - - return (IX_ETH_DB_GET_VLAN_ID(entry->recordData.filteringVlanData.ieee802_1qTag) == - IX_ETH_DB_GET_VLAN_ID(reference->recordData.filteringVlanData.ieee802_1qTag)) && - (ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0); -} - -/** - * @brief matches two database records based on their MAC addresses - * and port IDs - * - * @param untypedReference record to match against - * @param untypedEntry record to match - * - * @return TRUE if the match is successful or FALSE otherwise - * - * @internal - */ -IX_ETH_DB_PUBLIC -BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry) -{ - MacDescriptor *entry = (MacDescriptor *) untypedEntry; - MacDescriptor *reference = (MacDescriptor *) untypedReference; - - /* check accepted record types */ - if ((entry->type & reference->type) == 0) return FALSE; - - return (entry->portID == reference->portID) && - (ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0); -} - -/** - * @brief dummy matching function, registered for safety - * - * @param reference record to match against (unused) - * @param entry record to match (unused) - * - * This function is registered in the matching functions - * array on invalid types. Calling it will display an - * error message, indicating an error in the component logic. - * - * @return FALSE - * - * @internal - */ -IX_ETH_DB_PUBLIC -BOOL ixEthDBNullMatch(void *reference, void *entry) -{ - /* display an error message */ - - ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, "DB: (Search) The NullMatch function was called, wrong key type?\n", 0, 0, 0, 0, 0, 0); - - - return FALSE; -} - -/** - * @brief registers hash matching methods - * - * @param matchFunctions table of match functions to be populated - * - * This function registers the available record matching functions - * by indexing them on record types into the given function array. - * - * Note that it is compulsory to call this in ixEthDBInit(), - * otherwise hashtable searching and removal will not work - * - * @return number of registered functions - * - * @internal - */ -IX_ETH_DB_PUBLIC -UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions) -{ - UINT32 i; - - /* safety first */ - for ( i = 0 ; i < IX_ETH_DB_MAX_KEY_INDEX + 1 ; i++) - { - matchFunctions[i] = ixEthDBNullMatch; - } - - /* register MAC search method */ - matchFunctions[IX_ETH_DB_MAC_KEY] = ixEthDBAddressRecordMatch; - - /* register MAC/PortID search method */ - matchFunctions[IX_ETH_DB_MAC_PORT_KEY] = ixEthDBPortRecordMatch; - - /* register MAC/VLAN ID search method */ - matchFunctions[IX_ETH_DB_MAC_VLAN_KEY] = ixEthDBVlanRecordMatch; - - return 3; /* three methods */ -} - -/** - * @brief search a record in the Ethernet datbase - * - * @param macAddress MAC address to perform the search on - * @param typeFilter type of records to consider for matching - * - * @warning if searching is successful an implicit write lock - * to the search result is granted, therefore unlock the - * entry using @ref ixEthDBReleaseHashNode() as soon as possible. - * - * @see ixEthDBReleaseHashNode() - * - * @return the search result, or NULL if a record with the given - * MAC address was not found - * - * @internal - */ -IX_ETH_DB_PUBLIC -HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter) -{ - HashNode *searchResult = NULL; - MacDescriptor reference; - - TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; - - if (macAddress == NULL) - { - return NULL; - } - - /* fill search fields */ - memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr)); - - /* set acceptable record types */ - reference.type = typeFilter; - - BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference, &searchResult)); - - return searchResult; -} - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter) -{ - MacDescriptor reference; - IxEthDBStatus result; - - TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; - - if (macAddress == NULL) - { - return IX_ETH_DB_INVALID_ARG; - } - - /* fill search fields */ - memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr)); - - /* set acceptable record types */ - reference.type = typeFilter; - - result = ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference); - - return result; -} - -/** - * @brief search a record in the Ethernet datbase - * - * @param macAddress MAC address to perform the search on - * @param portID port ID to perform the search on - * @param typeFilter type of records to consider for matching - * - * @warning if searching is successful an implicit write lock - * to the search result is granted, therefore unlock the - * entry using @ref ixEthDBReleaseHashNode() as soon as possible. - * - * @see ixEthDBReleaseHashNode() - * - * @return the search result, or NULL if a record with the given - * MAC address/port ID combination was not found - * - * @internal - */ -IX_ETH_DB_PUBLIC -HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter) -{ - HashNode *searchResult = NULL; - MacDescriptor reference; - - if (macAddress == NULL) - { - return NULL; - } - - /* fill search fields */ - memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr)); - reference.portID = portID; - - /* set acceptable record types */ - reference.type = typeFilter; - - BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference, &searchResult)); - - return searchResult; -} - -/** - * @brief search a record in the Ethernet datbase - * - * @param macAddress MAC address to perform the search on - * @param vlanID VLAN ID to perform the search on - * @param typeFilter type of records to consider for matching - * - * @warning if searching is successful an implicit write lock - * to the search result is granted, therefore unlock the - * entry using @ref ixEthDBReleaseHashNode() as soon as possible. - * - * @see ixEthDBReleaseHashNode() - * - * @return the search result, or NULL if a record with the given - * MAC address/VLAN ID combination was not found - * - * @internal - */ -IX_ETH_DB_PUBLIC -HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter) -{ - HashNode *searchResult = NULL; - MacDescriptor reference; - - if (macAddress == NULL) - { - return NULL; - } - - /* fill search fields */ - memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr)); - reference.recordData.filteringVlanData.ieee802_1qTag = - IX_ETH_DB_SET_VLAN_ID(reference.recordData.filteringVlanData.ieee802_1qTag, vlanID); - - /* set acceptable record types */ - reference.type = typeFilter; - - BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_VLAN_KEY, &reference, &searchResult)); - - return searchResult; -} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c b/arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c deleted file mode 100644 index 6d9fd6e..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBSpanningTree.c +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @file IxEthDBSpanningTree.c - * - * @brief Implementation of the STP API - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - - -#include "IxEthDB_p.h" - -/** - * @brief sets the STP blocking state of a port - * - * @param portID ID of the port - * @param blocked TRUE to block the port or FALSE to unblock it - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked) -{ - IxNpeMhMessage message; - IX_STATUS result; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL); - - ixEthDBPortInfo[portID].stpBlocked = blocked; - - FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief retrieves the STP blocking state of a port - * - * @param portID ID of the port - * @param blocked address to write the blocked status into - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL); - - IX_ETH_DB_CHECK_REFERENCE(blocked); - - *blocked = ixEthDBPortInfo[portID].stpBlocked; - - return IX_ETH_DB_SUCCESS; -} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBUtil.c b/arch/arm/cpu/ixp/npe/IxEthDBUtil.c deleted file mode 100644 index e708bf1..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBUtil.c +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @file ethUtil.c - * - * @brief Utility functions - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - - -#include "IxFeatureCtrl.h" -#include "IxEthDB_p.h" - -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portID) -{ - /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */ - if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != - (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) - || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) - { - if ((portID == 0) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - return IX_ETH_DB_FAIL; - } - - if ((portID == 1) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - return IX_ETH_DB_FAIL; - } - - if ((portID == 2) && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - return IX_ETH_DB_FAIL; - } - } - - return IX_ETH_DB_SUCCESS; -} - -IX_ETH_DB_PUBLIC -BOOL ixEthDBCheckSingleBitValue(UINT32 value) -{ -#if (CPU != SIMSPARCSOLARIS) && !defined (__wince) - UINT32 shift; - - /* use the count-leading-zeros XScale instruction */ - __asm__ ("clz %0, %1\n" : "=r" (shift) : "r" (value)); - - return ((value << shift) == 0x80000000UL); - -#else - - while (value != 0) - { - if (value == 1) return TRUE; - else if ((value & 1) == 1) return FALSE; - - value >>= 1; - } - - return FALSE; - -#endif -} - -const char *mac2string(const unsigned char *mac) -{ - static char str[19]; - - if (mac == NULL) - { - return NULL; - } - - sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - return str; -} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBVlan.c b/arch/arm/cpu/ixp/npe/IxEthDBVlan.c deleted file mode 100644 index e2efb9b..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBVlan.c +++ /dev/null @@ -1,1179 +0,0 @@ -/** - * @file IxEthDBVlan.c - * - * @brief Implementation of the VLAN API - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxEthDB.h" -#include "IxEthDB_p.h" - -/* forward prototypes */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex); -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet); - -/* contants used by various functions as "action" parameter */ -#define ADD_VLAN (0x1) -#define REMOVE_VLAN (0x2) - -/** - * @brief adds or removes a VLAN from a VLAN set - * - * @param vlanID VLAN ID to add or remove - * @param table VLAN set to add into or remove from - * @param action ADD_VLAN or REMOVE_VLAN - * - * @internal - */ -IX_ETH_DB_PRIVATE -void ixEthDBLocalVlanMembershipChange(UINT32 vlanID, IxEthDBVlanSet table, UINT32 action) -{ - UINT32 setOffset; - - /* add/remove VID to membership table */ - setOffset = VLAN_SET_OFFSET(vlanID); /* we need 9 bits to index the 512 byte membership array */ - - if (action == ADD_VLAN) - { - table[setOffset] |= 1 << VLAN_SET_MASK(vlanID); - } - else if (action == REMOVE_VLAN) - { - table[setOffset] &= ~(1 << VLAN_SET_MASK(vlanID)); - } -} - -/** - * @brief updates a set of 8 VLANs in an NPE - * - * @param portID ID of the port - * @param setOffset offset of the 8 VLANs - * - * This function updates the VLAN membership table - * and Transmit Tagging Info table for 8 consecutive - * VLAN IDs indexed by setOffset. - * - * For example, a setOffset of 0 indexes VLAN IDs 0 - * through 7, 1 indexes VLAN IDs 8 through 9 etc. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBVlanTableEntryUpdate(IxEthDBPortId portID, UINT32 setOffset) -{ - PortInfo *portInfo = &ixEthDBPortInfo[portID]; - IxNpeMhMessage message; - IX_STATUS result; - - FILL_SETPORTVLANTABLEENTRY_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), - 2 * setOffset, - portInfo->vlanMembership[setOffset], - portInfo->transmitTaggingInfo[setOffset]); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief updates a VLAN range in an NPE - * - * @param portID ID of the port - * - * This function is similar to @ref ixEthDBVlanTableEntryUpdate - * except that it can update more than one VLAN set (up to - * the entire VLAN membership and TTI tables if the offset is 0 - * and length is sizeof (IxEthDBVlanSet) (512 bytes). - * - * Updating the NPE via this method is slower as it requires - * a memory copy from SDRAM, hence it is recommended that the - * ixEthDBVlanTableEntryUpdate function is used where possible. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBVlanTableRangeUpdate(IxEthDBPortId portID) -{ - PortInfo *portInfo = &ixEthDBPortInfo[portID]; - UINT8 *vlanUpdateZone = (UINT8 *) portInfo->updateMethod.vlanUpdateZone; - IxNpeMhMessage message; - UINT32 setIndex; - IX_STATUS result; - - /* copy membership info and transmit tagging into into exchange area */ - for (setIndex = 0 ; setIndex < sizeof (portInfo->vlanMembership) ; setIndex++) - { - /* membership and TTI data are interleaved */ - vlanUpdateZone[setIndex * 2] = portInfo->vlanMembership[setIndex]; - vlanUpdateZone[setIndex * 2 + 1] = portInfo->transmitTaggingInfo[setIndex]; - } - - IX_OSAL_CACHE_FLUSH(vlanUpdateZone, FULL_VLAN_BYTE_SIZE); - - /* build NPE message */ - FILL_SETPORTVLANTABLERANGE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 0, 0, - IX_OSAL_MMU_VIRT_TO_PHYS(vlanUpdateZone)); - - /* send message */ - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief adds or removes a VLAN from a port's VLAN membership table - * or Transmit Tagging Information table - * - * @param portID ID of the port - * @param vlanID VLAN ID to add or remove - * @param table to add or remove from - * @param action ADD_VLAN or REMOVE_VLAN - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBPortVlanMembershipChange(IxEthDBPortId portID, IxEthDBVlanId vlanID, IxEthDBVlanSet table, UINT32 action) -{ - /* change VLAN in local membership table */ - ixEthDBLocalVlanMembershipChange(vlanID, table, action); - - /* send updated entry to NPE */ - return ixEthDBVlanTableEntryUpdate(portID, VLAN_SET_OFFSET(vlanID)); -} - -/** - * @brief sets the default port VLAN tag (the lower 3 bytes are the PVID) - * - * @param portID ID of the port - * @param vlanTag port VLAN tag (802.1Q tag) - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag) -{ - IxNpeMhMessage message; - IX_STATUS result; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_VLAN_TAG(vlanTag); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - /* add VLAN ID to local membership table */ - ixEthDBPortVlanMembershipChange(portID, - vlanTag & IX_ETH_DB_802_1Q_VLAN_MASK, - ixEthDBPortInfo[portID].vlanMembership, - ADD_VLAN); - - /* set tag in portInfo */ - ixEthDBPortInfo[portID].vlanTag = vlanTag; - - /* build VLAN_SetDefaultRxVID message */ - FILL_SETDEFAULTRXVID_MSG(message, - IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), - IX_IEEE802_1Q_VLAN_TPID, - vlanTag); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief retrieves the default port VLAN tag (the lower 3 bytes are the PVID) - * - * @param portID ID of the port - * @param vlanTag address to write the port VLAN tag (802.1Q tag) into - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(vlanTag); - - *vlanTag = ixEthDBPortInfo[portID].vlanTag; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief sets the VLAN tag (the lower 3 bytes are the PVID) of a - * database filtering record - * - * @param portID ID of the port - * @param vlanTag VLAN tag (802.1Q tag) - * - * Important: filtering records are automatically converted to - * IX_ETH_DB_FILTERING_VLAN record when added a VLAN tag. - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag) -{ - HashNode *searchResult; - MacDescriptor *descriptor; - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - IX_ETH_DB_CHECK_VLAN_TAG(vlanTag); - - searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); - - if (searchResult == NULL) - { - return IX_ETH_DB_NO_SUCH_ADDR; - } - - descriptor = (MacDescriptor *) searchResult->data; - - /* set record type to VLAN if not already set */ - descriptor->type = IX_ETH_DB_FILTERING_VLAN_RECORD; - - /* add vlan tag */ - descriptor->recordData.filteringVlanData.ieee802_1qTag = vlanTag; - - /* transaction completed */ - ixEthDBReleaseHashNode(searchResult); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief retrieves the VLAN tag (the lower 3 bytes are the PVID) from a - * database VLAN filtering record - * - * @param portID ID of the port - * @param vlanTag address to write the VLAN tag (802.1Q tag) into - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag) -{ - HashNode *searchResult; - MacDescriptor *descriptor; - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - IX_ETH_DB_CHECK_REFERENCE(vlanTag); - - searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_FILTERING_VLAN_RECORD); - - if (searchResult == NULL) - { - return IX_ETH_DB_NO_SUCH_ADDR; - } - - descriptor = (MacDescriptor *) searchResult->data; - - /* get vlan tag */ - *vlanTag = descriptor->recordData.filteringVlanData.ieee802_1qTag; - - /* transaction completed */ - ixEthDBReleaseHashNode(searchResult); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief adds a VLAN to a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanID VLAN ID to add - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_VLAN_ID(vlanID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN); -} - -/** - * @brief removes a VLAN from a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanID VLAN ID to remove - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_VLAN_ID(vlanID); - - /* for safety isolate only the VLAN ID in the tag (the lower 12 bits) */ - vlanID = vlanID & IX_ETH_DB_802_1Q_VLAN_MASK; - - /* check we're not asked to remove the default port VID */ - if (vlanID == IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag)) - { - return IX_ETH_DB_NO_PERMISSION; - } - - return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN); -} - -/** - * @brief adds or removes a VLAN range from a port's - * VLAN membership table or TTI table - * - * @param portID ID of the port - * @param vlanIDMin start of the VLAN range - * @param vlanIDMax end of the VLAN range - * @param table VLAN set to add or remove from - * @param action ADD_VLAN or REMOVE_VLAN - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBPortVlanMembershipRangeChange(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, IxEthDBVlanSet table, UINT32 action) -{ - UINT32 setOffsetMin, setOffsetMax; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_VLAN_ID(vlanIDMin); - - IX_ETH_DB_CHECK_VLAN_ID(vlanIDMax); - - /* for safety isolate only the VLAN ID in the tags (the lower 12 bits) */ - vlanIDMin = vlanIDMin & IX_ETH_DB_802_1Q_VLAN_MASK; - vlanIDMax = vlanIDMax & IX_ETH_DB_802_1Q_VLAN_MASK; - - /* is this a range? */ - if (vlanIDMax < vlanIDMin) - { - return IX_ETH_DB_INVALID_VLAN; - } - - /* check that we're not specifically asked to remove the default port VID */ - if (action == REMOVE_VLAN && vlanIDMax == vlanIDMin && IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag) == vlanIDMin) - { - return IX_ETH_DB_NO_PERMISSION; - } - - /* compute set offsets */ - setOffsetMin = VLAN_SET_OFFSET(vlanIDMin); - setOffsetMax = VLAN_SET_OFFSET(vlanIDMax); - - /* change VLAN range */ - for (; vlanIDMin <= vlanIDMax ; vlanIDMin++) - { - /* change vlan in local membership table */ - ixEthDBLocalVlanMembershipChange(vlanIDMin, table, action); - } - - /* if the range is within one set (max 8 VLANs in one table byte) we can just update that entry in the NPE */ - if (setOffsetMin == setOffsetMax) - { - /* send updated entry to NPE */ - return ixEthDBVlanTableEntryUpdate(portID, setOffsetMin); - } - else - { - /* update a zone of the membership/transmit tag info table */ - return ixEthDBVlanTableRangeUpdate(portID); - } -} - -/** - * @brief adds a VLAN range to a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanIDMin start of the VLAN range - * @param vlanIDMax end of the VLAN range - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN); -} - -/** - * @brief removes a VLAN range from a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanIDMin start of the VLAN range - * @param vlanIDMax end of the VLAN range - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN); -} - -/** - * @brief sets a port's VLAN membership table or TTI table and - * updates the NPE VLAN configuration - * - * @param portID ID of the port - * @param portVlanTable port VLAN table to set - * @param vlanSet new set contents - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(vlanSet); - - memcpy(portVlanTable, vlanSet, sizeof (IxEthDBVlanSet)); - - return ixEthDBVlanTableRangeUpdate(portID); -} - -/** - * @brief retireves a port's VLAN membership table or TTI table - * - * @param portID ID of the port - * @param portVlanTable port VLAN table to retrieve - * @param vlanSet address to - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(vlanSet); - - memcpy(vlanSet, portVlanTable, sizeof (IxEthDBVlanSet)); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief sets a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanSet new VLAN membership table - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) -{ - IxEthDBVlanId vlanID; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(vlanSet); - - /* set the bit corresponding to the PVID just in case */ - vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag); - vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID); - - return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet); -} - -/** - * @brief retrieves a port's VLAN membership table - * - * @param portID ID of the port - * @param vlanSet location to store the port's VLAN membership table - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet); -} - -/** - * @brief enables or disables Egress tagging for one VLAN ID - * - * @param portID ID of the port - * @param vlanID VLAN ID to enable or disable Egress tagging on - * @param enabled TRUE to enable and FALSE to disable tagging - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_VLAN_ID(vlanID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN); -} - -/** - * @brief retrieves the Egress tagging status for one VLAN ID - * - * @param portID ID of the port - * @param vlanID VLAN ID to retrieve the tagging status for - * @param enabled location to store the tagging status - * (TRUE - tagging enabled, FALSE - tagging disabled) - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(enabled); - - IX_ETH_DB_CHECK_VLAN_ID(vlanID); - - *enabled = ((ixEthDBPortInfo[portID].transmitTaggingInfo[VLAN_SET_OFFSET(vlanID)] & (1 << VLAN_SET_MASK(vlanID))) != 0); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief enables or disables Egress VLAN tagging for a VLAN range - * - * @param portID ID of the port - * @param vlanIDMin start of VLAN range - * @param vlanIDMax end of VLAN range - * @param enabled TRUE to enable or FALSE to disable VLAN tagging - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN); -} - -/** - * @brief sets the Egress VLAN tagging table (the Transmit Tagging - * Information table) - * - * @param portID ID of the port - * @param vlanSet new TTI table - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) -{ - IxEthDBVlanId vlanID; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(vlanSet); - - /* set the PVID bit just in case */ - vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag); - vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID); - - return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet); -} - -/** - * @brief retrieves the Egress VLAN tagging table (the Transmit - * Tagging Information table) - * - * @param portID ID of the port - * @param vlanSet location to store the port's TTI table - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet); -} - -/** - * @brief sends the NPE the updated frame filter and default - * Ingress tagging - * - * @param portID ID of the port - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBIngressVlanModeUpdate(IxEthDBPortId portID) -{ - PortInfo *portInfo = &ixEthDBPortInfo[portID]; - IxNpeMhMessage message; - IX_STATUS result; - - FILL_SETRXTAGMODE_MSG(message, portID, portInfo->npeFrameFilter, portInfo->npeTaggingAction); - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief sets the default Ingress tagging behavior - * - * @param portID ID of the port - * @param taggingAction default tagging behavior - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction) -{ - PortInfo *portInfo; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - portInfo = &ixEthDBPortInfo[portID]; - - if (taggingAction == IX_ETH_DB_PASS_THROUGH) - { - portInfo->npeTaggingAction = 0x00; - } - else if (taggingAction == IX_ETH_DB_ADD_TAG) - { - portInfo->npeTaggingAction = 0x02; - } - else if (taggingAction == IX_ETH_DB_REMOVE_TAG) - { - portInfo->npeTaggingAction = 0x01; - } - else - { - return IX_ETH_DB_INVALID_ARG; - } - - portInfo->taggingAction = taggingAction; - - return ixEthDBIngressVlanModeUpdate(portID); -} - -/** - * @brief retrieves the default Ingress tagging behavior of a port - * - * @param portID ID of the port - * @param taggingAction location to save the default tagging behavior - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(taggingAction); - - *taggingAction = ixEthDBPortInfo[portID].taggingAction; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief sets the Ingress acceptable frame type filter - * - * @param portID ID of the port - * @param frameFilter acceptable frame type filter - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter) -{ - PortInfo *portInfo; - IxEthDBStatus result = IX_ETH_DB_SUCCESS; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - /* check parameter range - the ORed value of the valid values is 0x7 - a value having extra bits is invalid */ - if ((frameFilter | 0x7) != 0x7 || frameFilter == 0) - { - return IX_ETH_DB_INVALID_ARG; - } - - portInfo = &ixEthDBPortInfo[portID]; - - portInfo->frameFilter = frameFilter; - portInfo->npeFrameFilter = 0; /* allow all by default */ - - /* if accepting priority tagged but not all VLAN tagged - set the membership table to contain only VLAN ID 0 - hence remove vlans 1-4094 and add VLAN ID 0 */ - if (((frameFilter & IX_ETH_DB_PRIORITY_TAGGED_FRAMES) != 0) - && ((frameFilter & IX_ETH_DB_VLAN_TAGGED_FRAMES) == 0)) - { - result = ixEthDBPortVlanMembershipRangeChange(portID, - 1, IX_ETH_DB_802_1Q_MAX_VLAN_ID, portInfo->vlanMembership, REMOVE_VLAN); - - if (result == IX_ETH_DB_SUCCESS) - { - ixEthDBLocalVlanMembershipChange(0, portInfo->vlanMembership, ADD_VLAN); - result = ixEthDBVlanTableRangeUpdate(portID); - } - } - - /* untagged only? */ - if (frameFilter == IX_ETH_DB_UNTAGGED_FRAMES) - { - portInfo->npeFrameFilter = 0x01; - } - - /* tagged only? */ - if ((frameFilter & IX_ETH_DB_UNTAGGED_FRAMES) == 0) - { - portInfo->npeFrameFilter = 0x02; - } - - if (result == IX_ETH_DB_SUCCESS) - { - result = ixEthDBIngressVlanModeUpdate(portID); - } - - return result; -} - -/** - * @brief retrieves the acceptable frame type filter for a port - * - * @param portID ID of the port - * @param frameFilter location to store the frame filter - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(frameFilter); - - *frameFilter = ixEthDBPortInfo[portID].frameFilter; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief sends an NPE the updated configuration related - * to one QoS priority (associated traffic class and AQM mapping) - * - * @param portID ID of the port - * @param classIndex QoS priority (traffic class index) - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex) -{ - IxNpeMhMessage message; - IX_STATUS result; - - UINT32 trafficClass = ixEthDBPortInfo[portID].priorityTable[classIndex]; - UINT32 aqmQueue = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[trafficClass]; - - FILL_SETRXQOSENTRY(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), classIndex, trafficClass, aqmQueue); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief sets the priority mapping table - * - * @param portID ID of the port - * @param priorityTable new priority mapping table - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) -{ - UINT32 classIndex; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(priorityTable); - - for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++) - { - /* check range */ - if (priorityTable[classIndex] >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) - { - return IX_ETH_DB_INVALID_PRIORITY; - } - } - - /* set new traffic classes */ - for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++) - { - ixEthDBPortInfo[portID].priorityTable[classIndex] = priorityTable[classIndex]; - - if (ixEthDBUpdateTrafficClass(portID, classIndex) != IX_ETH_DB_SUCCESS) - { - return IX_ETH_DB_FAIL; - } - } - - return IX_ETH_DB_SUCCESS; - } - -/** - * @brief retrieves a port's priority mapping table - * - * @param portID ID of the port - * @param priorityTable location to store the priority table - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(priorityTable); - - memcpy(priorityTable, ixEthDBPortInfo[portID].priorityTable, sizeof (IxEthDBPriorityTable)); - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief sets one QoS priority => traffic class mapping - * - * @param portID ID of the port - * @param userPriority QoS (user) priority - * @param trafficClass associated traffic class - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - /* check ranges for userPriority and trafficClass */ - if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT || trafficClass >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) - { - return IX_ETH_DB_INVALID_PRIORITY; - } - - ixEthDBPortInfo[portID].priorityTable[userPriority] = trafficClass; - - return ixEthDBUpdateTrafficClass(portID, userPriority); -} - -/** - * @brief retrieves one QoS priority => traffic class mapping - * - * @param portID ID of the port - * @param userPriority QoS (user) priority - * @param trafficClass location to store the associated traffic class - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - IX_ETH_DB_CHECK_REFERENCE(trafficClass); - - /* check userPriority range */ - if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT) - { - return IX_ETH_DB_INVALID_PRIORITY; - } - - *trafficClass = ixEthDBPortInfo[portID].priorityTable[userPriority]; - - return IX_ETH_DB_SUCCESS; -} - -/** - * @brief enables or disables the source port extraction - * from the VLAN TPID field - * - * @param portID ID of the port - * @param enable TRUE to enable or FALSE to disable - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable) -{ - IxNpeMhMessage message; - IX_STATUS result; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); - - FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} diff --git a/arch/arm/cpu/ixp/npe/IxEthDBWiFi.c b/arch/arm/cpu/ixp/npe/IxEthDBWiFi.c deleted file mode 100644 index 0a6043f..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthDBWiFi.c +++ /dev/null @@ -1,480 +0,0 @@ -/** - * @file IxEthDBAPI.c - * - * @brief Implementation of the public API - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxEthDB_p.h" - -/* forward prototypes */ -IX_ETH_DB_PUBLIC -MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations); - -/** - * @brief sets the BBSID value for the WiFi header conversion feature - * - * @param portID ID of the port - * @param bbsid pointer to the 6-byte BBSID value - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid) -{ - IxNpeMhMessage message; - IX_STATUS result; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); - - IX_ETH_DB_CHECK_REFERENCE(bbsid); - - memcpy(ixEthDBPortInfo[portID].bbsid, bbsid, sizeof (IxEthDBMacAddr)); - - FILL_SETBBSID_MSG(message, portID, bbsid); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief updates the Frame Control and Duration/ID WiFi header - * conversion parameters in an NPE - * - * @param portID ID of the port - * - * This function will send a message to the NPE updating the - * frame conversion parameters for 802.3 => 802.11 header conversion. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or IX_ETH_DB_FAIL otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBWiFiFrameControlDurationIDUpdate(IxEthDBPortId portID) -{ - IxNpeMhMessage message; - IX_STATUS result; - - FILL_SETFRAMECONTROLDURATIONID(message, portID, ixEthDBPortInfo[portID].frameControlDurationID); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - return result; -} - -/** - * @brief sets the Duration/ID WiFi frame header conversion parameter - * - * @param portID ID of the port - * @param durationID 16-bit value containing the new Duration/ID parameter - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); - - ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF0000) | durationID; - - return ixEthDBWiFiFrameControlDurationIDUpdate(portID); -} - -/** - * @brief sets the Frame Control WiFi frame header conversion parameter - * - * @param portID ID of the port - * @param durationID 16-bit value containing the new Frame Control parameter - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl) -{ - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); - - ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF) | (frameControl << 16); - - return ixEthDBWiFiFrameControlDurationIDUpdate(portID); -} - -/** - * @brief removes a WiFi header conversion record - * - * @param portID ID of the port - * @param macAddr MAC address of the record to remove - * - * Note that this function is documented in the main - * component header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) -{ - MacDescriptor recordTemplate; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); - - memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr)); - - recordTemplate.type = IX_ETH_DB_WIFI_RECORD; - recordTemplate.portID = portID; - - return ixEthDBRemove(&recordTemplate, NULL); -} - -/** - * @brief adds a WiFi header conversion record - * - * @param portID ID of the port - * @param macAddr MAC address of the record to add - * @param gatewayMacAddr address of the gateway (or - * NULL if this is a station record) - * - * This function adds a record of type AP_TO_AP (gateway is not NULL) - * or AP_TO_STA (gateway is NULL) in the main database as a - * WiFi header conversion record. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - * - * @internal - */ -IX_ETH_DB_PRIVATE -IxEthDBStatus ixEthDBWiFiEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr) -{ - MacDescriptor recordTemplate; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_REFERENCE(macAddr); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); - - memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr)); - - recordTemplate.type = IX_ETH_DB_WIFI_RECORD; - recordTemplate.portID = portID; - - if (gatewayMacAddr != NULL) - { - memcpy(recordTemplate.recordData.wifiData.gwMacAddress, gatewayMacAddr, sizeof (IxEthDBMacAddr)); - - recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_AP; - } - else - { - memset(recordTemplate.recordData.wifiData.gwMacAddress, 0, sizeof (IxEthDBMacAddr)); - - recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_STA; - } - - return ixEthDBAdd(&recordTemplate, NULL); -} - -/** - * @brief adds a WiFi header conversion record - * - * @param portID ID of the port - * @param macAddr MAC address of the record to add - * @param gatewayMacAddr address of the gateway - * - * This function adds a record of type AP_TO_AP - * in the main database as a WiFi header conversion record. - * - * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd(). - * - * Note that this function is documented in the main - * component header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr) -{ - IX_ETH_DB_CHECK_REFERENCE(gatewayMacAddr); - - return ixEthDBWiFiEntryAdd(portID, macAddr, gatewayMacAddr); -} - -/** - * @brief adds a WiFi header conversion record - * - * @param portID ID of the port - * @param macAddr MAC address of the record to add - * - * This function adds a record of type AP_TO_STA - * in the main database as a WiFi header conversion record. - * - * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd(). - * - * Note that this function is documented in the main - * component header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed - * successfully or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) -{ - return ixEthDBWiFiEntryAdd(portID, macAddr, NULL); -} - -/** - * @brief selects a set of gateways from a tree of - * WiFi header conversion records - * - * @param stations binary tree containing pointers to WiFi header - * conversion records - * - * This function browses through the input binary tree, identifies - * records of type AP_TO_AP, clones these records and appends them - * to a vine (a single right-branch binary tree) which is returned - * as result. A maximum of MAX_GW_SIZE entries containing gateways - * will be cloned from the original tree. - * - * @return vine (linear binary tree) containing record - * clones of AP_TO_AP type, which have a gateway field - * - * @internal - */ -IX_ETH_DB_PUBLIC -MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations) -{ - MacTreeNodeStack *stack; - MacTreeNode *gateways, *insertionPlace; - UINT32 gwIndex = 1; /* skip the empty root */ - - if (stations == NULL) - { - return NULL; - } - - stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack)); - - if (stack == NULL) - { - ERROR_LOG("DB: (WiFi) failed to allocate the node stack for gateway tree linearization, out of memory?\n"); - return NULL; - } - - /* initialize root node */ - gateways = insertionPlace = NULL; - - /* start browsing the station tree */ - NODE_STACK_INIT(stack); - - /* initialize stack by pushing the tree root at offset 0 */ - NODE_STACK_PUSH(stack, stations, 0); - - while (NODE_STACK_NONEMPTY(stack)) - { - MacTreeNode *node; - UINT32 offset; - - NODE_STACK_POP(stack, node, offset); - - /* we can store maximum 31 (32 total, 1 empty root) entries in the gateway tree */ - if (offset > (MAX_GW_SIZE - 1)) break; - - /* check if this record has a gateway address */ - if (node->descriptor != NULL && node->descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP) - { - /* found a record, create an insertion place */ - if (insertionPlace != NULL) - { - insertionPlace->right = ixEthDBAllocMacTreeNode(); - insertionPlace = insertionPlace->right; - } - else - { - gateways = ixEthDBAllocMacTreeNode(); - insertionPlace = gateways; - } - - if (insertionPlace == NULL) - { - /* no nodes left, bail out with what we have */ - ixOsalCacheDmaFree(stack); - return gateways; - } - - /* clone the original record for the gateway tree */ - insertionPlace->descriptor = ixEthDBCloneMacDescriptor(node->descriptor); - - /* insert and update the offset in the original record */ - node->descriptor->recordData.wifiData.gwAddressIndex = gwIndex++; - } - - /* browse the tree */ - if (node->left != NULL) - { - NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset)); - } - - if (node->right != NULL) - { - NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset)); - } - } - - ixOsalCacheDmaFree(stack); - return gateways; -} - -/** - * @brief downloads the WiFi header conversion table to an NPE - * - * @param portID ID of the port - * - * This function prepares the WiFi header conversion tables and - * downloads them to the specified NPE port. - * - * The header conversion tables consist in the main table of - * addresses and the secondary table of gateways. AP_TO_AP records - * from the first table contain index fields into the second table - * for gateway selection. - * - * Note that this function is documented in the main component - * header file, IxEthDB.h. - * - * @return IX_ETH_DB_SUCCESS if the operation completed successfully - * or an appropriate error message otherwise - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID) -{ - IxEthDBPortMap query; - MacTreeNode *stations = NULL, *gateways = NULL, *gateway = NULL; - IxNpeMhMessage message; - PortInfo *portInfo; - IX_STATUS result; - - IX_ETH_DB_CHECK_PORT(portID); - - IX_ETH_DB_CHECK_SINGLE_NPE(portID); - - IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); - - portInfo = &ixEthDBPortInfo[portID]; - - SET_DEPENDENCY_MAP(query, portID); - - ixEthDBUpdateLock(); - - stations = ixEthDBQuery(NULL, query, IX_ETH_DB_WIFI_RECORD, MAX_ELT_SIZE); - gateways = ixEthDBGatewaySelect(stations); - - /* clean up gw area */ - memset((void *) portInfo->updateMethod.npeGwUpdateZone, FULL_GW_BYTE_SIZE, 0); - - /* write all gateways */ - gateway = gateways; - - while (gateway != NULL) - { - ixEthDBNPEGatewayNodeWrite((void *) (((UINT32) portInfo->updateMethod.npeGwUpdateZone) - + gateway->descriptor->recordData.wifiData.gwAddressIndex * ELT_ENTRY_SIZE), - gateway); - - gateway = gateway->right; - } - - /* free the gateway tree */ - if (gateways != NULL) - { - ixEthDBFreeMacTreeNode(gateways); - } - - FILL_SETAPMACTABLE_MSG(message, - IX_OSAL_MMU_VIRT_TO_PHYS(portInfo->updateMethod.npeGwUpdateZone)); - - IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); - - if (result == IX_SUCCESS) - { - /* update the main tree (the stations tree) */ - portInfo->updateMethod.searchTree = stations; - - result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_WIFI_RECORD); - } - - ixEthDBUpdateUnlock(); - - return result; -} diff --git a/arch/arm/cpu/ixp/npe/IxEthMii.c b/arch/arm/cpu/ixp/npe/IxEthMii.c deleted file mode 100644 index 4d92f17..0000000 --- a/arch/arm/cpu/ixp/npe/IxEthMii.c +++ /dev/null @@ -1,497 +0,0 @@ -/** - * @file IxEthMii.c - * - * @author Intel Corporation - * @date - * - * @brief MII control functions - * - * Design Notes: - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxOsal.h" - -#include "IxEthAcc.h" -#include "IxEthMii_p.h" - -#ifdef __wince -#include "IxOsPrintf.h" -#endif - -/* Array to store the phy IDs of the discovered phys */ -PRIVATE UINT32 ixEthMiiPhyId[IXP425_ETH_ACC_MII_MAX_ADDR]; - -/********************************************************* - * - * Scan for PHYs on the MII bus. This function returns - * an array of booleans, one for each PHY address. - * If a PHY is found at a particular address, the - * corresponding entry in the array is set to TRUE. - * - */ - -PUBLIC IX_STATUS -ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount) -{ - UINT32 i; - UINT16 regval, regvalId1, regvalId2; - - /*Search for PHYs on the MII*/ - /*Search for existant phys on the MDIO bus*/ - - if ((phyPresent == NULL) || - (maxPhyCount > IXP425_ETH_ACC_MII_MAX_ADDR)) - { - return IX_FAIL; - } - - /* fill the array */ - for(i=0; - i 0 && i= IX_ETH_MII_RESET_DELAY_MS) - { - ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, - IX_ETH_MII_CR_NORM_EN); - return IX_FAIL; - } - - return IX_SUCCESS; - } /* end of if(ixEthMiiPhyId) */ - else if (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_KS8995_PHY_ID) - { - /* reset bit is reserved, just reset the control register */ - ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, - IX_ETH_MII_CR_NORM_EN); - return IX_SUCCESS; - } - else - { - /* unknown PHY, set the control register reset bit, - * wait 2 s. and clear the control register. - */ - ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, - IX_ETH_MII_CR_RESET); - - ixOsalSleep (IX_ETH_MII_RESET_DELAY_MS); - - ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, - IX_ETH_MII_CR_NORM_EN); - return IX_SUCCESS; - } /* end of if-else(ixEthMiiPhyId) */ - } /* end of if(phyAddr) */ - return IX_FAIL; -} - -/***************************************************************** - * - * Link state query functions - */ - -PUBLIC IX_STATUS -ixEthMiiLinkStatus(UINT32 phyAddr, - BOOL *linkUp, - BOOL *speed100, - BOOL *fullDuplex, - BOOL *autoneg) -{ - UINT16 ctrlRegval, statRegval, regval, regval4, regval5; - - /* check the parameters */ - if ((linkUp == NULL) || - (speed100 == NULL) || - (fullDuplex == NULL) || - (autoneg == NULL)) - { - return IX_FAIL; - } - - *linkUp = FALSE; - *speed100 = FALSE; - *fullDuplex = FALSE; - *autoneg = FALSE; - - if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) && - (ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID)) - { - if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID) || - (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID) || - (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID) - ) - { - /* --------------------------------------------------*/ - /* Retrieve information from PHY specific register */ - /* --------------------------------------------------*/ - if (ixEthAccMiiReadRtn(phyAddr, - IX_ETH_MII_STAT2_REG, - ®val) != IX_ETH_ACC_SUCCESS) - { - return IX_FAIL; - } - *linkUp = ((regval & IX_ETH_MII_SR2_LINK) != 0); - *speed100 = ((regval & IX_ETH_MII_SR2_100) != 0); - *fullDuplex = ((regval & IX_ETH_MII_SR2_FD) != 0); - *autoneg = ((regval & IX_ETH_MII_SR2_AUTO) != 0); - return IX_SUCCESS; - } /* end of if(ixEthMiiPhyId) */ - else - { - /* ----------------------------------------------------*/ - /* Retrieve information from status and ctrl registers */ - /* ----------------------------------------------------*/ - if (ixEthAccMiiReadRtn(phyAddr, - IX_ETH_MII_CTRL_REG, - &ctrlRegval) != IX_ETH_ACC_SUCCESS) - { - return IX_FAIL; - } - ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &statRegval); - - *linkUp = ((statRegval & IX_ETH_MII_SR_LINK_STATUS) != 0); - if (*linkUp) - { - *autoneg = ((ctrlRegval & IX_ETH_MII_CR_AUTO_EN) != 0) && - ((statRegval & IX_ETH_MII_SR_AUTO_SEL) != 0) && - ((statRegval & IX_ETH_MII_SR_AUTO_NEG) != 0); - - if (*autoneg) - { - /* mask the current stat values with the capabilities */ - ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_ADS_REG, ®val4); - ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_PRTN_REG, ®val5); - /* merge the flags from the 3 registers */ - regval = (statRegval & ((regval4 & regval5) << 6)); - /* initialise from status register values */ - if ((regval & IX_ETH_MII_SR_TX_FULL_DPX) != 0) - { - /* 100 Base X full dplx */ - *speed100 = TRUE; - *fullDuplex = TRUE; - return IX_SUCCESS; - } - if ((regval & IX_ETH_MII_SR_TX_HALF_DPX) != 0) - { - /* 100 Base X half dplx */ - *speed100 = TRUE; - return IX_SUCCESS; - } - if ((regval & IX_ETH_MII_SR_10T_FULL_DPX) != 0) - { - /* 10 mb full dplx */ - *fullDuplex = TRUE; - return IX_SUCCESS; - } - if ((regval & IX_ETH_MII_SR_10T_HALF_DPX) != 0) - { - /* 10 mb half dplx */ - return IX_SUCCESS; - } - } /* end of if(autoneg) */ - else - { - /* autonegotiate not complete, return setup parameters */ - *speed100 = ((ctrlRegval & IX_ETH_MII_CR_100) != 0); - *fullDuplex = ((ctrlRegval & IX_ETH_MII_CR_FDX) != 0); - } - } /* end of if(linkUp) */ - } /* end of if-else(ixEthMiiPhyId) */ - } /* end of if(phyAddr) */ - else - { - return IX_FAIL; - } /* end of if-else(phyAddr) */ - return IX_SUCCESS; -} - -/***************************************************************** - * - * Link state display functions - */ - -PUBLIC IX_STATUS -ixEthMiiPhyShow (UINT32 phyAddr) -{ - BOOL linkUp, speed100, fullDuplex, autoneg; - UINT16 cregval; - UINT16 sregval; - - - ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &sregval); - ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_CTRL_REG, &cregval); - - /* get link information */ - if (ixEthMiiLinkStatus(phyAddr, - &linkUp, - &speed100, - &fullDuplex, - &autoneg) != IX_ETH_ACC_SUCCESS) - { - printf("PHY Status unknown\n"); - return IX_FAIL; - } - - printf("PHY ID [phyAddr]: %8.8x\n",ixEthMiiPhyId[phyAddr]); - printf( " Status reg: %4.4x\n",sregval); - printf( " control reg: %4.4x\n",cregval); - /* display link information */ - printf("PHY Status:\n"); - printf(" Link is %s\n", - (linkUp ? "Up" : "Down")); - if((sregval & IX_ETH_MII_SR_REMOTE_FAULT) != 0) - { - printf(" Remote fault detected\n"); - } - printf(" Auto Negotiation %s\n", - (autoneg ? "Completed" : "Not Completed")); - - printf("PHY Configuration:\n"); - printf(" Speed %sMb/s\n", - (speed100 ? "100" : "10")); - printf(" %s Duplex\n", - (fullDuplex ? "Full" : "Half")); - printf(" Auto Negotiation %s\n", - (autoneg ? "Enabled" : "Disabled")); - return IX_SUCCESS; -} - diff --git a/arch/arm/cpu/ixp/npe/IxFeatureCtrl.c b/arch/arm/cpu/ixp/npe/IxFeatureCtrl.c deleted file mode 100644 index 2e196a1..0000000 --- a/arch/arm/cpu/ixp/npe/IxFeatureCtrl.c +++ /dev/null @@ -1,422 +0,0 @@ -/** - * @file IxFeatureCtrl.c - * - * @author Intel Corporation - * @date 29-Jan-2003 - * - * @brief Feature Control Public API Implementation - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -#include "IxOsal.h" -#include "IxVersionId.h" -#include "IxFeatureCtrl.h" - -/* Macro to read from the Feature Control Register */ -#define IX_FEATURE_CTRL_READ(result) \ -do { \ -ixFeatureCtrlExpMap(); \ -(result) = IX_OSAL_READ_LONG(ixFeatureCtrlRegister); \ -} while (0) - -/* Macro to write to the Feature Control Register */ -#define IX_FEATURE_CTRL_WRITE(value) \ -do { \ -ixFeatureCtrlExpMap(); \ -IX_OSAL_WRITE_LONG(ixFeatureCtrlRegister, (value)); \ -} while (0) - -/* - * This is the offset of the feature register relative to the base of the - * Expansion Bus Controller MMR. - */ -#define IX_FEATURE_CTRL_REG_OFFSET (0x00000028) - - -/* Boolean to mark the fact that the EXP_CONFIG address space was mapped */ -PRIVATE BOOL ixFeatureCtrlExpCfgRegionMapped = FALSE; - -/* Pointer holding the virtual address of the Feature Control Register */ -PRIVATE VUINT32 *ixFeatureCtrlRegister = NULL; - -/* Place holder to store the software configuration */ -PRIVATE BOOL swConfiguration[IX_FEATURECTRL_SWCONFIG_MAX]; - -/* Flag to control swConfiguration[] is initialized once */ -PRIVATE BOOL swConfigurationFlag = FALSE ; - -/* Array containing component mask values */ -#ifdef __ixp42X -UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = { - (0x1<> IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET) - & IX_FEATURE_CTRL_DEVICE_TYPE_MASK); -} /* End function ixFeatureCtrlDeviceRead */ - - -/** - * Function definition: ixFeatureCtrlSwConfigurationCheck - */ -IX_STATUS -ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType) -{ - if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX) - { - ixOsalLog(IX_OSAL_LOG_LVL_WARNING, - IX_OSAL_LOG_DEV_STDOUT, - "FeatureCtrl: Invalid software configuraiton input.\n", - 0, 0, 0, 0, 0, 0); - - return IX_FEATURE_CTRL_SWCONFIG_DISABLED; - } - - /* The function will only initialize once. */ - ixFeatureCtrlSwConfigurationInit(); - - /* Check and return software configuration */ - return ((swConfiguration[(UINT32)swConfigType] == TRUE) ? IX_FEATURE_CTRL_SWCONFIG_ENABLED: IX_FEATURE_CTRL_SWCONFIG_DISABLED); -} - -/** - * Function definition: ixFeatureCtrlSwConfigurationWrite - */ -void -ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled) -{ - if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX) - { - ixOsalLog(IX_OSAL_LOG_LVL_WARNING, - IX_OSAL_LOG_DEV_STDOUT, - "FeatureCtrl: Invalid software configuraiton input.\n", - 0, 0, 0, 0, 0, 0); - - return; - } - - /* The function will only initialize once. */ - ixFeatureCtrlSwConfigurationInit(); - - /* Write software configuration */ - swConfiguration[(UINT32)swConfigType]=enabled ; -} - -/** - * Function definition: ixFeatureCtrlIxp400SwVersionShow - */ -void -ixFeatureCtrlIxp400SwVersionShow (void) -{ - printf ("\nIXP400 Software Release %s %s\n\n", IX_VERSION_ID, IX_VERSION_INTERNAL_ID); - -} - -/** - * Function definition: ixFeatureCtrlSoftwareBuildGet - */ -IxFeatureCtrlBuildDevice -ixFeatureCtrlSoftwareBuildGet (void) -{ - #ifdef __ixp42X - return IX_FEATURE_CTRL_SW_BUILD_IXP42X; - #else - return IX_FEATURE_CTRL_SW_BUILD_IXP46X; - #endif -} diff --git a/arch/arm/cpu/ixp/npe/IxNpeDl.c b/arch/arm/cpu/ixp/npe/IxNpeDl.c deleted file mode 100644 index 3738337..0000000 --- a/arch/arm/cpu/ixp/npe/IxNpeDl.c +++ /dev/null @@ -1,940 +0,0 @@ -/** - * @file IxNpeDl.c - * - * @author Intel Corporation - * @date 08 January 2002 - * - * @brief This file contains the implementation of the public API for the - * IXP425 NPE Downloader component - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * Put the system defined include files required - */ - -/* - * Put the user defined include files required - */ -#include "IxNpeDl.h" -#include "IxNpeDlImageMgr_p.h" -#include "IxNpeDlNpeMgr_p.h" -#include "IxNpeDlMacros_p.h" -#include "IxFeatureCtrl.h" -#include "IxOsal.h" -/* - * #defines used in this file - */ - #define IMAGEID_MAJOR_NUMBER_DEFAULT 0 - #define IMAGEID_MINOR_NUMBER_DEFAULT 0 - -/* - * Typedefs whose scope is limited to this file. - */ -typedef struct -{ - BOOL validImage; - IxNpeDlImageId imageId; -} IxNpeDlNpeState; - -/* module statistics counters */ -typedef struct -{ - UINT32 attemptedDownloads; - UINT32 successfulDownloads; - UINT32 criticalFailDownloads; -} IxNpeDlStats; - -/* - * Variable declarations global to this file only. Externs are followed - * by static variables. - */ -static IxNpeDlNpeState ixNpeDlNpeState[IX_NPEDL_NPEID_MAX] = -{ - {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}}, - {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}}, - {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}} -}; - -static IxNpeDlStats ixNpeDlStats; - -/* - * Software guard to prevent NPE from being started multiple times. - */ -static BOOL ixNpeDlNpeStarted[IX_NPEDL_NPEID_MAX] ={FALSE, FALSE, FALSE} ; - - -/* - * static function prototypes. - */ -PRIVATE IX_STATUS -ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary, UINT32 imageId); - -/* - * Function definition: ixNpeDlImageDownload - */ -PUBLIC IX_STATUS -ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr, - BOOL verify) -{ - UINT32 imageSize; - UINT32 *imageCodePtr = NULL; - IX_STATUS status; - IxNpeDlNpeId npeId = imageIdPtr->npeId; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlImageDownload\n"); - - ixNpeDlStats.attemptedDownloads++; - - /* Check input parameters */ - if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0)) - { - status = IX_NPEDL_PARAM_ERR; - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageDownload - invalid parameter\n"); - } - else - { - /* Ensure initialisation has been completed */ - ixNpeDlNpeMgrInit(); - - /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ - if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != - (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) - || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) - { - if (npeId == IX_NPEDL_NPEID_NPEA) - { - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) == - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does" - " not exist\n"); - return IX_SUCCESS; - } - } /* end of if(npeId) */ - else if (npeId == IX_NPEDL_NPEID_NPEB) - { - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified" - " does not exist\n"); - return IX_SUCCESS; - } - } /* end of elseif(npeId) */ - else if (npeId == IX_NPEDL_NPEID_NPEC) - { - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified" - " does not exist\n"); - return IX_SUCCESS; - } - } /* end of elseif(npeId) */ - } /* end of if(IX_FEATURE_CTRL_SILICON_TYPE_B0) */ /*End of Silicon Type Check*/ - - /* stop and reset the NPE */ - if (IX_SUCCESS != ixNpeDlNpeStopAndReset (npeId)) - { - IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n"); - return IX_FAIL; - } - - /* Locate image */ - status = ixNpeDlImageMgrImageLocate (imageIdPtr, &imageCodePtr, - &imageSize); - if (IX_SUCCESS == status) - { - /* - * If download was successful, store image Id in list of - * currently loaded images. If a critical error occured - * during download, record that the NPE has an invalid image - */ - status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr, - verify); - if (IX_SUCCESS == status) - { - ixNpeDlNpeState[npeId].imageId = *imageIdPtr; - ixNpeDlNpeState[npeId].validImage = TRUE; - ixNpeDlStats.successfulDownloads++; - - status = ixNpeDlNpeExecutionStart (npeId); - } - else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) || - (status == IX_NPEDL_CRITICAL_MICROCODE_ERR)) - { - ixNpeDlNpeState[npeId].imageId = *imageIdPtr; - ixNpeDlNpeState[npeId].validImage = FALSE; - ixNpeDlStats.criticalFailDownloads++; - } - } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */ - } /* end of if-else(npeId) */ /* condition: parameter checks ok */ - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlImageDownload : status = %d\n", status); - return status; -} - -/* - * Function definition: ixNpeDlAvailableImagesCountGet - */ -PUBLIC IX_STATUS -ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr) -{ - IX_STATUS status; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlAvailableImagesCountGet\n"); - - /* Check input parameters */ - if (numImagesPtr == NULL) - { - status = IX_NPEDL_PARAM_ERR; - IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesCountGet - " - "invalid parameter\n"); - } - else - { - /* - * Use ImageMgr module to get no. of images listed in Image Library Header. - * If NULL is passed as imageListPtr parameter to following function, - * it will only fill number of images into numImagesPtr - */ - status = ixNpeDlImageMgrImageListExtract (NULL, numImagesPtr); - } /* end of if-else(numImagesPtr) */ - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlAvailableImagesCountGet : " - "status = %d\n", status); - return status; -} - -/* - * Function definition: ixNpeDlAvailableImagesListGet - */ -PUBLIC IX_STATUS -ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr, - UINT32 *listSizePtr) -{ - IX_STATUS status; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlAvailableImagesListGet\n"); - - /* Check input parameters */ - if ((imageIdListPtr == NULL) || (listSizePtr == NULL)) - { - status = IX_NPEDL_PARAM_ERR; - IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesListGet - " - "invalid parameter\n"); - } - else - { - /* Call ImageMgr to get list of images listed in Image Library Header */ - status = ixNpeDlImageMgrImageListExtract (imageIdListPtr, - listSizePtr); - } /* end of if-else(imageIdListPtr) */ - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlAvailableImagesListGet : status = %d\n", - status); - return status; -} - -/* - * Function definition: ixNpeDlLoadedImageGet - */ -PUBLIC IX_STATUS -ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId, - IxNpeDlImageId *imageIdPtr) -{ - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlLoadedImageGet\n"); - - /* Check input parameters */ - if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0) || (imageIdPtr == NULL)) - { - status = IX_NPEDL_PARAM_ERR; - IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageGet - invalid parameter\n"); - } - else - { - - /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ - if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != - (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) - || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) - { - if (npeId == IX_NPEDL_NPEID_NPEA && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does" - " not exist\n"); - return IX_SUCCESS; - } /* end of if(npeId) */ - - if (npeId == IX_NPEDL_NPEID_NPEB && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does" - " not exist\n"); - return IX_SUCCESS; - } /* end of if(npeId) */ - - if (npeId == IX_NPEDL_NPEID_NPEC && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does" - " not exist\n"); - return IX_SUCCESS; - } /* end of if(npeId) */ - } /* end of if not IXP42x-A0 silicon */ - - if (ixNpeDlNpeState[npeId].validImage) - { - /* use npeId to get imageId from list of currently loaded - images */ - *imageIdPtr = ixNpeDlNpeState[npeId].imageId; - } - else - { - status = IX_FAIL; - } /* end of if-else(ixNpeDlNpeState) */ - } /* end of if-else(npeId) */ - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlLoadedImageGet : status = %d\n", - status); - return status; -} - -/* - * Function definition: ixNpeDlLatestImageGet - */ -PUBLIC IX_STATUS -ixNpeDlLatestImageGet ( - IxNpeDlNpeId npeId, - IxNpeDlFunctionalityId functionalityId, - IxNpeDlImageId *imageIdPtr) -{ - IX_STATUS status; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlLatestImageGet\n"); - - /* Check input parameters */ - if ((npeId >= IX_NPEDL_NPEID_MAX) || - (npeId < 0) || - (imageIdPtr == NULL)) - { - status = IX_NPEDL_PARAM_ERR; - IX_NPEDL_ERROR_REPORT ("ixNpeDlLatestImageGet - " - "invalid parameter\n"); - } /* end of if(npeId) */ - else - { - - /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ - if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != - (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) - || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) - { - if (npeId == IX_NPEDL_NPEID_NPEA && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does" - " not exist\n"); - return IX_SUCCESS; - } /* end of if(npeId) */ - - if (npeId == IX_NPEDL_NPEID_NPEB && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does" - " not exist\n"); - return IX_SUCCESS; - } /* end of if(npeId) */ - - if (npeId == IX_NPEDL_NPEID_NPEC && - (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) == - IX_FEATURE_CTRL_COMPONENT_DISABLED)) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does" - " not exist\n"); - return IX_SUCCESS; - } /* end of if(npeId) */ - } /* end of if not IXP42x-A0 silicon */ - - imageIdPtr->npeId = npeId; - imageIdPtr->functionalityId = functionalityId; - imageIdPtr->major = IMAGEID_MAJOR_NUMBER_DEFAULT; - imageIdPtr->minor = IMAGEID_MINOR_NUMBER_DEFAULT; - /* Call ImageMgr to get list of images listed in Image Library Header */ - status = ixNpeDlImageMgrLatestImageExtract(imageIdPtr); - } /* end of if-else(npeId) */ - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlLatestImageGet : status = %d\n", - status); - - return status; -} - -/* - * Function definition: ixNpeDlNpeStopAndReset - */ -PUBLIC IX_STATUS -ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId) -{ - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeStopAndReset\n"); - - /* Ensure initialisation has been completed */ - ixNpeDlNpeMgrInit(); - - /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ - if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != - (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) - || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) - { - /* - * Check whether NPE is present - */ - if (IX_NPEDL_NPEID_NPEA == npeId) - { - /* Check whether NPE A is present */ - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - /* NPE A does not present */ - IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEA does not present.\n"); - return IX_SUCCESS; - } - } /* end of if(IX_NPEDL_NPEID_NPEA) */ - else if (IX_NPEDL_NPEID_NPEB == npeId) - { - /* Check whether NPE B is present */ - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - /* NPE B does not present */ - IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEB does not present.\n"); - return IX_SUCCESS; - } - } /* end of elseif(IX_NPEDL_NPEID_NPEB) */ - else if (IX_NPEDL_NPEID_NPEC == npeId) - { - /* Check whether NPE C is present */ - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - /* NPE C does not present */ - IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEC does not present.\n"); - return IX_SUCCESS; - } - } /* end of elseif(IX_NPEDL_NPEID_NPEC) */ - else - { - /* Invalid NPE ID */ - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeStopAndReset - invalid Npe ID\n"); - status = IX_NPEDL_PARAM_ERR; - } /* end of if-else(IX_NPEDL_NPEID_NPEC) */ - } /* end of if not IXP42x-A0 Silicon */ - - if (status == IX_SUCCESS) - { - /* call NpeMgr function to stop the NPE */ - status = ixNpeDlNpeMgrNpeStop (npeId); - if (status == IX_SUCCESS) - { - /* call NpeMgr function to reset the NPE */ - status = ixNpeDlNpeMgrNpeReset (npeId); - } - } /* end of if(status) */ - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeStopAndReset : status = %d\n", status); - - if (IX_SUCCESS == status) - { - /* Indicate NPE has been stopped */ - ixNpeDlNpeStarted[npeId] = FALSE ; - } - - return status; -} - -/* - * Function definition: ixNpeDlNpeExecutionStart - */ -PUBLIC IX_STATUS -ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId) -{ - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeExecutionStart\n"); - - /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ - if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != - (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) - || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) - { - /* - * Check whether NPE is present - */ - if (IX_NPEDL_NPEID_NPEA == npeId) - { - /* Check whether NPE A is present */ - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - /* NPE A does not present */ - IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEA does not present.\n"); - return IX_SUCCESS; - } - } /* end of if(IX_NPEDL_NPEID_NPEA) */ - else if (IX_NPEDL_NPEID_NPEB == npeId) - { - /* Check whether NPE B is present */ - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - /* NPE B does not present */ - IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEB does not present.\n"); - return IX_SUCCESS; - } - } /* end of elseif(IX_NPEDL_NPEID_NPEB) */ - else if (IX_NPEDL_NPEID_NPEC == npeId) - { - /* Check whether NPE C is present */ - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - /* NPE C does not present */ - IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEC does not present.\n"); - return IX_SUCCESS; - } - } /* end of elseif(IX_NPEDL_NPEID_NPEC) */ - else - { - /* Invalid NPE ID */ - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStart - invalid Npe ID\n"); - return IX_NPEDL_PARAM_ERR; - } /* end of if-else(IX_NPEDL_NPEID_NPEC) */ - } /* end of if not IXP42x-A0 Silicon */ - - if (TRUE == ixNpeDlNpeStarted[npeId]) - { - /* NPE has been started. */ - return IX_SUCCESS ; - } - - /* Ensure initialisation has been completed */ - ixNpeDlNpeMgrInit(); - - /* call NpeMgr function to start the NPE */ - status = ixNpeDlNpeMgrNpeStart (npeId); - - if (IX_SUCCESS == status) - { - /* Indicate NPE has started */ - ixNpeDlNpeStarted[npeId] = TRUE ; - } - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeExecutionStart : status = %d\n", - status); - - return status; -} - -/* - * Function definition: ixNpeDlNpeExecutionStop - */ -PUBLIC IX_STATUS -ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId) -{ - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeExecutionStop\n"); - - /* Ensure initialisation has been completed */ - ixNpeDlNpeMgrInit(); - - /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ - if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != - (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) - || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) - { - /* - * Check whether NPE is present - */ - if (IX_NPEDL_NPEID_NPEA == npeId) - { - /* Check whether NPE A is present */ - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - /* NPE A does not present */ - IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEA does not present.\n"); - return IX_SUCCESS; - } - } /* end of if(IX_NPEDL_NPEID_NPEA) */ - else if (IX_NPEDL_NPEID_NPEB == npeId) - { - /* Check whether NPE B is present */ - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - /* NPE B does not present */ - IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEB does not present.\n"); - return IX_SUCCESS; - } - } /* end of elseif(IX_NPEDL_NPEID_NPEB) */ - else if (IX_NPEDL_NPEID_NPEC == npeId) - { - /* Check whether NPE C is present */ - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - /* NPE C does not present */ - IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEC does not present.\n"); - return IX_SUCCESS; - } - } /* end of elseif(IX_NPEDL_NPEID_NPEC) */ - else - { - /* Invalid NPE ID */ - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStop - invalid Npe ID\n"); - status = IX_NPEDL_PARAM_ERR; - } /* end of if-else(IX_NPEDL_NPEID_NPEC) */ - } /* end of if not IXP42X-AO Silicon */ - - if (status == IX_SUCCESS) - { - /* call NpeMgr function to stop the NPE */ - status = ixNpeDlNpeMgrNpeStop (npeId); - } - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeExecutionStop : status = %d\n", - status); - - if (IX_SUCCESS == status) - { - /* Indicate NPE has been stopped */ - ixNpeDlNpeStarted[npeId] = FALSE ; - } - - return status; -} - -/* - * Function definition: ixNpeDlUnload - */ -PUBLIC IX_STATUS -ixNpeDlUnload (void) -{ - IX_STATUS status; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlUnload\n"); - - status = ixNpeDlNpeMgrUninit(); - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlUnload : status = %d\n", - status); - return status; -} - -/* - * Function definition: ixNpeDlStatsShow - */ -PUBLIC void -ixNpeDlStatsShow (void) -{ - ixOsalLog (IX_OSAL_LOG_LVL_USER, - IX_OSAL_LOG_DEV_STDOUT, - "\nixNpeDlStatsShow:\n" - "\tDownloads Attempted by user: %u\n" - "\tSuccessful Downloads: %u\n" - "\tFailed Downloads (due to Critical Error): %u\n\n", - ixNpeDlStats.attemptedDownloads, - ixNpeDlStats.successfulDownloads, - ixNpeDlStats.criticalFailDownloads, - 0,0,0); - - ixNpeDlImageMgrStatsShow (); - ixNpeDlNpeMgrStatsShow (); -} - -/* - * Function definition: ixNpeDlStatsReset - */ -PUBLIC void -ixNpeDlStatsReset (void) -{ - ixNpeDlStats.attemptedDownloads = 0; - ixNpeDlStats.successfulDownloads = 0; - ixNpeDlStats.criticalFailDownloads = 0; - - ixNpeDlImageMgrStatsReset (); - ixNpeDlNpeMgrStatsReset (); -} - -/* - * Function definition: ixNpeDlNpeInitAndStartInternal - */ -PRIVATE IX_STATUS -ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary, - UINT32 imageId) -{ - UINT32 imageSize; - UINT32 *imageCodePtr = NULL; - IX_STATUS status; - IxNpeDlNpeId npeId = IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId); - IxFeatureCtrlDeviceId deviceId = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId); - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeInitAndStartInternal\n"); - - ixNpeDlStats.attemptedDownloads++; - - /* Check input parameter device correctness */ - if ((deviceId >= IX_FEATURE_CTRL_DEVICE_TYPE_MAX) || - (deviceId < IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X)) - { - status = IX_NPEDL_PARAM_ERR; - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - " - "invalid parameter\n"); - } /* End valid device id checking */ - - /* Check input parameters */ - else if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0)) - { - status = IX_NPEDL_PARAM_ERR; - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - " - "invalid parameter\n"); - } - - else - { - /* Ensure initialisation has been completed */ - ixNpeDlNpeMgrInit(); - - /* Checking if image being loaded is meant for device that is running. - * Image is forward compatible. i.e Image built for IXP42X should run - * on IXP46X but not vice versa.*/ - if (deviceId > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK)) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - " - "Device type mismatch. NPE Image not " - "meant for device in use \n"); - return IX_NPEDL_DEVICE_ERR; - }/* if statement - matching image device and current device */ - - /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ - if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != - (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) - || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) - { - if (npeId == IX_NPEDL_NPEID_NPEA) - { - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) == - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does" - " not exist\n"); - return IX_SUCCESS; - } - } /* end of if(npeId) */ - else if (npeId == IX_NPEDL_NPEID_NPEB) - { - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified" - " does not exist\n"); - return IX_SUCCESS; - } - } /* end of elseif(npeId) */ - else if (npeId == IX_NPEDL_NPEID_NPEC) - { - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)== - IX_FEATURE_CTRL_COMPONENT_DISABLED) - { - IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified" - " does not exist\n"); - return IX_SUCCESS; - } - } /* end of elseif(npeId) */ - } /* end of if not IXP42X-A0 Silicon */ - - /* stop and reset the NPE */ - status = ixNpeDlNpeStopAndReset (npeId); - if (IX_SUCCESS != status) - { - IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n"); - return status; - } - - /* Locate image */ - status = ixNpeDlImageMgrImageFind (imageLibrary, imageId, - &imageCodePtr, &imageSize); - if (IX_SUCCESS == status) - { - /* - * If download was successful, store image Id in list of - * currently loaded images. If a critical error occured - * during download, record that the NPE has an invalid image - */ - status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr, TRUE); - if (IX_SUCCESS == status) - { - ixNpeDlNpeState[npeId].validImage = TRUE; - ixNpeDlStats.successfulDownloads++; - - status = ixNpeDlNpeExecutionStart (npeId); - } - else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) || - (status == IX_NPEDL_CRITICAL_MICROCODE_ERR)) - { - ixNpeDlNpeState[npeId].validImage = FALSE; - ixNpeDlStats.criticalFailDownloads++; - } - - /* NOTE - The following section of code is here to support - * a deprecated function ixNpeDlLoadedImageGet(). When that - * function is removed from the API, this code should be revised. - */ - ixNpeDlNpeState[npeId].imageId.npeId = npeId; - ixNpeDlNpeState[npeId].imageId.functionalityId = - IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId); - ixNpeDlNpeState[npeId].imageId.major = - IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId); - ixNpeDlNpeState[npeId].imageId.minor = - IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId); - } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */ - } /* end of if-else(npeId-deviceId) */ /* condition: parameter checks ok */ - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeInitAndStartInternal : " - "status = %d\n", status); - return status; -} - -/* - * Function definition: ixNpeDlCustomImageNpeInitAndStart - */ -PUBLIC IX_STATUS -ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary, - UINT32 imageId) -{ - IX_STATUS status; - - if (imageLibrary == NULL) - { - status = IX_NPEDL_PARAM_ERR; - IX_NPEDL_ERROR_REPORT ("ixNpeDlCustomImageNpeInitAndStart " - "- invalid parameter\n"); - } - else - { - status = ixNpeDlNpeInitAndStartInternal (imageLibrary, imageId); - } /* end of if-else(imageLibrary) */ - - return status; -} - -/* - * Function definition: ixNpeDlNpeInitAndStart - */ -PUBLIC IX_STATUS -ixNpeDlNpeInitAndStart (UINT32 imageId) -{ - return ixNpeDlNpeInitAndStartInternal (NULL, imageId); -} - -/* - * Function definition: ixNpeDlLoadedImageFunctionalityGet - */ -PUBLIC IX_STATUS -ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId, - UINT8 *functionalityId) -{ - /* Check input parameters */ - if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0)) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet " - "- invalid parameter\n"); - return IX_NPEDL_PARAM_ERR; - } - if (functionalityId == NULL) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet " - "- invalid parameter\n"); - return IX_NPEDL_PARAM_ERR; - } - - if (ixNpeDlNpeState[npeId].validImage) - { - *functionalityId = ixNpeDlNpeState[npeId].imageId.functionalityId; - return IX_SUCCESS; - } - else - { - return IX_FAIL; - } -} diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c b/arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c deleted file mode 100644 index 9bcdc9c..0000000 --- a/arch/arm/cpu/ixp/npe/IxNpeDlImageMgr.c +++ /dev/null @@ -1,687 +0,0 @@ -/** - * @file IxNpeDlImageMgr.c - * - * @author Intel Corporation - * @date 09 January 2002 - * - * @brief This file contains the implementation of the private API for the - * IXP425 NPE Downloader ImageMgr module - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - - -/* - * Put the system defined include files required. - */ -#include "IxOsal.h" - -/* - * Put the user defined include files required. - */ -#include "IxNpeDlImageMgr_p.h" -#include "IxNpeDlMacros_p.h" - -/* - * define the flag which toggles the firmare inclusion - */ -#define IX_NPE_MICROCODE_FIRMWARE_INCLUDED 1 -#include "IxNpeMicrocode.h" - -/* - * Indicates the start of an NPE Image, in new NPE Image Library format. - * 2 consecutive occurances indicates the end of the NPE Image Library - */ -#define NPE_IMAGE_MARKER 0xfeedf00d - -/* - * Typedefs whose scope is limited to this file. - */ - -/* - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * TO BE DEPRECATED IN A FUTURE RELEASE - */ -typedef struct -{ - UINT32 size; - UINT32 offset; - UINT32 id; -} IxNpeDlImageMgrImageEntry; - -/* - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * TO BE DEPRECATED IN A FUTURE RELEASE - */ -typedef union -{ - IxNpeDlImageMgrImageEntry image; - UINT32 eohMarker; -} IxNpeDlImageMgrHeaderEntry; - -/* - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * TO BE DEPRECATED IN A FUTURE RELEASE - */ -typedef struct -{ - UINT32 signature; - /* 1st entry in the header (there may be more than one) */ - IxNpeDlImageMgrHeaderEntry entry[1]; -} IxNpeDlImageMgrImageLibraryHeader; - - -/* - * NPE Image Header definition, used in new NPE Image Library format - */ -typedef struct -{ - UINT32 marker; - UINT32 id; - UINT32 size; -} IxNpeDlImageMgrImageHeader; - -/* module statistics counters */ -typedef struct -{ - UINT32 invalidSignature; - UINT32 imageIdListOverflow; - UINT32 imageIdNotFound; -} IxNpeDlImageMgrStats; - - -/* - * Variable declarations global to this file only. Externs are followed by - * static variables. - */ -static IxNpeDlImageMgrStats ixNpeDlImageMgrStats; - -static UINT32* getIxNpeMicroCodeImageLibrary(void) -{ - char *s; - - if ((s = getenv("npe_ucode")) != NULL) - return (UINT32*) simple_strtoul(s, NULL, 16); - else - return NULL; -} - -/* - * static function prototypes. - */ -PRIVATE BOOL -ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary); - -PRIVATE void -ixNpeDlImageMgrImageIdFormat (UINT32 rawImageId, IxNpeDlImageId *imageId); - -PRIVATE BOOL -ixNpeDlImageMgrImageIdCompare (IxNpeDlImageId *imageIdA, - IxNpeDlImageId *imageIdB); - -PRIVATE BOOL -ixNpeDlImageMgrNpeFunctionIdCompare (IxNpeDlImageId *imageIdA, - IxNpeDlImageId *imageIdB); - -#if 0 -PRIVATE IX_STATUS -ixNpeDlImageMgrImageFind_legacy (UINT32 *imageLibrary, - UINT32 imageId, - UINT32 **imagePtr, - UINT32 *imageSize); - -/* - * Function definition: ixNpeDlImageMgrMicrocodeImageLibraryOverride - * - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE - */ -IX_STATUS -ixNpeDlImageMgrMicrocodeImageLibraryOverride ( - UINT32 *clientImageLibrary) -{ - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlImageMgrMicrocodeImageLibraryOverride\n"); - - if (ixNpeDlImageMgrSignatureCheck (clientImageLibrary)) - { - IxNpeMicroCodeImageLibrary = clientImageLibrary; - } - else - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrMicrocodeImageLibraryOverride: " - "Client-supplied image has invalid signature\n"); - status = IX_FAIL; - } - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlImageMgrMicrocodeImageLibraryOverride: status = %d\n", - status); - return status; -} -#endif - -/* - * Function definition: ixNpeDlImageMgrImageListExtract - * - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE - */ -IX_STATUS -ixNpeDlImageMgrImageListExtract ( - IxNpeDlImageId *imageListPtr, - UINT32 *numImages) -{ - UINT32 rawImageId; - IxNpeDlImageId formattedImageId; - IX_STATUS status = IX_SUCCESS; - UINT32 imageCount = 0; - IxNpeDlImageMgrImageLibraryHeader *header; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlImageMgrImageListExtract\n"); - - header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary(); - - if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary())) - { - /* for each image entry in the image header ... */ - while (header->entry[imageCount].eohMarker != - IX_NPEDL_IMAGEMGR_END_OF_HEADER) - { - /* - * if the image list container from calling function has capacity, - * add the image id to the list - */ - if ((imageListPtr != NULL) && (imageCount < *numImages)) - { - rawImageId = header->entry[imageCount].image.id; - ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId); - imageListPtr[imageCount] = formattedImageId; - } - /* imageCount reflects no. of image entries in image library header */ - imageCount++; - } - - /* - * if image list container from calling function was too small to - * contain all image ids in the header, set return status to FAIL - */ - if ((imageListPtr != NULL) && (imageCount > *numImages)) - { - status = IX_FAIL; - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: " - "number of Ids found exceeds list capacity\n"); - ixNpeDlImageMgrStats.imageIdListOverflow++; - } - /* return number of image ids found in image library header */ - *numImages = imageCount; - } - else - { - status = IX_FAIL; - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: " - "invalid signature in image\n"); - } - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlImageMgrImageListExtract: status = %d\n", - status); - return status; -} - - -/* - * Function definition: ixNpeDlImageMgrImageLocate - * - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE - */ -IX_STATUS -ixNpeDlImageMgrImageLocate ( - IxNpeDlImageId *imageId, - UINT32 **imagePtr, - UINT32 *imageSize) -{ - UINT32 imageOffset; - UINT32 rawImageId; - IxNpeDlImageId formattedImageId; - /* used to index image entries in image library header */ - UINT32 imageCount = 0; - IX_STATUS status = IX_FAIL; - IxNpeDlImageMgrImageLibraryHeader *header; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlImageMgrImageLocate\n"); - - header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary(); - - if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary())) - { - /* for each image entry in the image library header ... */ - while (header->entry[imageCount].eohMarker != - IX_NPEDL_IMAGEMGR_END_OF_HEADER) - { - rawImageId = header->entry[imageCount].image.id; - ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId); - /* if a match for imageId is found in the image library header... */ - if (ixNpeDlImageMgrImageIdCompare (imageId, &formattedImageId)) - { - /* - * get pointer to the image in the image library using offset from - * 1st word in image library - */ - UINT32 *tmp=getIxNpeMicroCodeImageLibrary(); - imageOffset = header->entry[imageCount].image.offset; - *imagePtr = &tmp[imageOffset]; - /* get the image size */ - *imageSize = header->entry[imageCount].image.size; - status = IX_SUCCESS; - break; - } - imageCount++; - } - if (status != IX_SUCCESS) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: " - "imageId not found in image library header\n"); - ixNpeDlImageMgrStats.imageIdNotFound++; - } - } - else - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: " - "invalid signature in image library\n"); - } - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlImageMgrImageLocate: status = %d\n", status); - return status; -} - -/* - * Function definition: ixNpeDlImageMgrLatestImageExtract - * - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE - */ -IX_STATUS -ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId) -{ - UINT32 imageCount = 0; - UINT32 rawImageId; - IxNpeDlImageId formattedImageId; - IX_STATUS status = IX_FAIL; - IxNpeDlImageMgrImageLibraryHeader *header; - - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlImageMgrLatestImageExtract\n"); - - header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary(); - - if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary())) - { - /* for each image entry in the image library header ... */ - while (header->entry[imageCount].eohMarker != - IX_NPEDL_IMAGEMGR_END_OF_HEADER) - { - rawImageId = header->entry[imageCount].image.id; - ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId); - /* - * if a match for the npe Id and functionality Id of the imageId is - * found in the image library header... - */ - if(ixNpeDlImageMgrNpeFunctionIdCompare(imageId, &formattedImageId)) - { - if(imageId->major <= formattedImageId.major) - { - if(imageId->minor < formattedImageId.minor) - { - imageId->minor = formattedImageId.minor; - } - imageId->major = formattedImageId.major; - } - status = IX_SUCCESS; - } - imageCount++; - } - if (status != IX_SUCCESS) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageExtract: " - "imageId not found in image library header\n"); - ixNpeDlImageMgrStats.imageIdNotFound++; - } - } - else - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageGet: " - "invalid signature in image library\n"); - } - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlImageMgrLatestImageGet: status = %d\n", status); - return status; -} - -/* - * Function definition: ixNpeDlImageMgrSignatureCheck - * - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE - */ -PRIVATE BOOL -ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary) -{ - IxNpeDlImageMgrImageLibraryHeader *header = - (IxNpeDlImageMgrImageLibraryHeader *) microCodeImageLibrary; - BOOL result = TRUE; - - if (!header || header->signature != IX_NPEDL_IMAGEMGR_SIGNATURE) - { - result = FALSE; - ixNpeDlImageMgrStats.invalidSignature++; - } - - return result; -} - - -/* - * Function definition: ixNpeDlImageMgrImageIdFormat - * - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE - */ -PRIVATE void -ixNpeDlImageMgrImageIdFormat ( - UINT32 rawImageId, - IxNpeDlImageId *imageId) -{ - imageId->npeId = (rawImageId >> - IX_NPEDL_IMAGEID_NPEID_OFFSET) & - IX_NPEDL_NPEIMAGE_FIELD_MASK; - imageId->functionalityId = (rawImageId >> - IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET) & - IX_NPEDL_NPEIMAGE_FIELD_MASK; - imageId->major = (rawImageId >> - IX_NPEDL_IMAGEID_MAJOR_OFFSET) & - IX_NPEDL_NPEIMAGE_FIELD_MASK; - imageId->minor = (rawImageId >> - IX_NPEDL_IMAGEID_MINOR_OFFSET) & - IX_NPEDL_NPEIMAGE_FIELD_MASK; - -} - - -/* - * Function definition: ixNpeDlImageMgrImageIdCompare - * - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE - */ -PRIVATE BOOL -ixNpeDlImageMgrImageIdCompare ( - IxNpeDlImageId *imageIdA, - IxNpeDlImageId *imageIdB) -{ - if ((imageIdA->npeId == imageIdB->npeId) && - (imageIdA->functionalityId == imageIdB->functionalityId) && - (imageIdA->major == imageIdB->major) && - (imageIdA->minor == imageIdB->minor)) - { - return TRUE; - } - else - { - return FALSE; - } -} - -/* - * Function definition: ixNpeDlImageMgrNpeFunctionIdCompare - * - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE - */ -PRIVATE BOOL -ixNpeDlImageMgrNpeFunctionIdCompare ( - IxNpeDlImageId *imageIdA, - IxNpeDlImageId *imageIdB) -{ - if ((imageIdA->npeId == imageIdB->npeId) && - (imageIdA->functionalityId == imageIdB->functionalityId)) - { - return TRUE; - } - else - { - return FALSE; - } -} - - -/* - * Function definition: ixNpeDlImageMgrStatsShow - */ -void -ixNpeDlImageMgrStatsShow (void) -{ - ixOsalLog (IX_OSAL_LOG_LVL_USER, - IX_OSAL_LOG_DEV_STDOUT, - "\nixNpeDlImageMgrStatsShow:\n" - "\tInvalid Image Signatures: %u\n" - "\tImage Id List capacity too small: %u\n" - "\tImage Id not found: %u\n\n", - ixNpeDlImageMgrStats.invalidSignature, - ixNpeDlImageMgrStats.imageIdListOverflow, - ixNpeDlImageMgrStats.imageIdNotFound, - 0,0,0); -} - - -/* - * Function definition: ixNpeDlImageMgrStatsReset - */ -void -ixNpeDlImageMgrStatsReset (void) -{ - ixNpeDlImageMgrStats.invalidSignature = 0; - ixNpeDlImageMgrStats.imageIdListOverflow = 0; - ixNpeDlImageMgrStats.imageIdNotFound = 0; -} - - -#if 0 -/* - * Function definition: ixNpeDlImageMgrImageFind_legacy - * - * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT - * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE - */ -PRIVATE IX_STATUS -ixNpeDlImageMgrImageFind_legacy ( - UINT32 *imageLibrary, - UINT32 imageId, - UINT32 **imagePtr, - UINT32 *imageSize) -{ - UINT32 imageOffset; - /* used to index image entries in image library header */ - UINT32 imageCount = 0; - IX_STATUS status = IX_FAIL; - IxNpeDlImageMgrImageLibraryHeader *header; - BOOL imageFound = FALSE; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlImageMgrImageFind\n"); - - - /* If user didn't specify a library to use, use the default - * one from IxNpeMicrocode.h - */ - if (imageLibrary == NULL) - { - imageLibrary = IxNpeMicroCodeImageLibrary; - } - - if (ixNpeDlImageMgrSignatureCheck (imageLibrary)) - { - header = (IxNpeDlImageMgrImageLibraryHeader *) imageLibrary; - - /* for each image entry in the image library header ... */ - while ((header->entry[imageCount].eohMarker != - IX_NPEDL_IMAGEMGR_END_OF_HEADER) && !(imageFound)) - { - /* if a match for imageId is found in the image library header... */ - if (imageId == header->entry[imageCount].image.id) - { - /* - * get pointer to the image in the image library using offset from - * 1st word in image library - */ - imageOffset = header->entry[imageCount].image.offset; - *imagePtr = &imageLibrary[imageOffset]; - /* get the image size */ - *imageSize = header->entry[imageCount].image.size; - status = IX_SUCCESS; - imageFound = TRUE; - } - imageCount++; - } - if (status != IX_SUCCESS) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: " - "imageId not found in image library header\n"); - ixNpeDlImageMgrStats.imageIdNotFound++; - } - } - else - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: " - "invalid signature in image library\n"); - } - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlImageMgrImageFind: status = %d\n", status); - return status; -} -#endif - -/* - * Function definition: ixNpeDlImageMgrImageFind - */ -IX_STATUS -ixNpeDlImageMgrImageFind ( - UINT32 *imageLibrary, - UINT32 imageId, - UINT32 **imagePtr, - UINT32 *imageSize) -{ - IxNpeDlImageMgrImageHeader *image; - UINT32 offset = 0; - - /* If user didn't specify a library to use, use the default - * one from IxNpeMicrocode.h - */ - if (imageLibrary == NULL) - { -#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE - if (ixNpeMicrocode_binaryArray == NULL) - { - printk (KERN_ERR "ixp400.o: ERROR, no Microcode found in memory\n"); - return IX_FAIL; - } - else - { - imageLibrary = ixNpeMicrocode_binaryArray; - } -#else - imageLibrary = getIxNpeMicroCodeImageLibrary(); - if (imageLibrary == NULL) - { - printf ("npe: ERROR, no Microcode found in memory\n"); - return IX_FAIL; - } -#endif /* IX_NPEDL_READ_MICROCODE_FROM_FILE */ - } - -#if 0 - /* For backward's compatibility with previous image format */ - if (ixNpeDlImageMgrSignatureCheck(imageLibrary)) - { - return ixNpeDlImageMgrImageFind_legacy(imageLibrary, - imageId, - imagePtr, - imageSize); - } -#endif - - while (*(imageLibrary+offset) == NPE_IMAGE_MARKER) - { - image = (IxNpeDlImageMgrImageHeader *)(imageLibrary+offset); - offset += sizeof(IxNpeDlImageMgrImageHeader)/sizeof(UINT32); - - if (image->id == imageId) - { - *imagePtr = imageLibrary + offset; - *imageSize = image->size; - return IX_SUCCESS; - } - /* 2 consecutive NPE_IMAGE_MARKER's indicates end of library */ - else if (image->id == NPE_IMAGE_MARKER) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: " - "imageId not found in image library header\n"); - ixNpeDlImageMgrStats.imageIdNotFound++; - /* reached end of library, image not found */ - return IX_FAIL; - } - offset += image->size; - } - - /* If we get here, our image library may be corrupted */ - IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: " - "image library format may be invalid or corrupted\n"); - return IX_FAIL; -} - diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c b/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c deleted file mode 100644 index a9ea8bc..0000000 --- a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgr.c +++ /dev/null @@ -1,931 +0,0 @@ -/** - * @file IxNpeDlNpeMgr.c - * - * @author Intel Corporation - * @date 09 January 2002 - * - * @brief This file contains the implementation of the private API for the - * IXP425 NPE Downloader NpeMgr module - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - - -/* - * Put the user defined include files required. - */ -#include "IxOsal.h" -#include "IxNpeDl.h" -#include "IxNpeDlNpeMgr_p.h" -#include "IxNpeDlNpeMgrUtils_p.h" -#include "IxNpeDlNpeMgrEcRegisters_p.h" -#include "IxNpeDlMacros_p.h" -#include "IxFeatureCtrl.h" - -/* - * #defines and macros used in this file. - */ -#define IX_NPEDL_BYTES_PER_WORD 4 - -/* used to read download map from version in microcode image */ -#define IX_NPEDL_BLOCK_TYPE_INSTRUCTION 0x00000000 -#define IX_NPEDL_BLOCK_TYPE_DATA 0x00000001 -#define IX_NPEDL_BLOCK_TYPE_STATE 0x00000002 -#define IX_NPEDL_END_OF_DOWNLOAD_MAP 0x0000000F - -/* - * masks used to extract address info from State information context - * register addresses as read from microcode image - */ -#define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG 0x0000000F -#define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM 0x000000F0 - -/* LSB offset of Context Number field in State-Info Context Address */ -#define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM 4 - -/* size (in words) of single State Information entry (ctxt reg address|data) */ -#define IX_NPEDL_STATE_INFO_ENTRY_SIZE 2 - - - #define IX_NPEDL_RESET_NPE_PARITY 0x0800 - #define IX_NPEDL_PARITY_BIT_MASK 0x3F00FFFF - #define IX_NPEDL_CONFIG_CTRL_REG_MASK 0x3F3FFFFF - - -/* - * Typedefs whose scope is limited to this file. - */ - -typedef struct -{ - UINT32 type; - UINT32 offset; -} IxNpeDlNpeMgrDownloadMapBlockEntry; - -typedef union -{ - IxNpeDlNpeMgrDownloadMapBlockEntry block; - UINT32 eodmMarker; -} IxNpeDlNpeMgrDownloadMapEntry; - -typedef struct -{ - /* 1st entry in the download map (there may be more than one) */ - IxNpeDlNpeMgrDownloadMapEntry entry[1]; -} IxNpeDlNpeMgrDownloadMap; - - -/* used to access an instruction or data block in a microcode image */ -typedef struct -{ - UINT32 npeMemAddress; - UINT32 size; - UINT32 data[1]; -} IxNpeDlNpeMgrCodeBlock; - -/* used to access each Context Reg entry state-information block */ -typedef struct -{ - UINT32 addressInfo; - UINT32 value; -} IxNpeDlNpeMgrStateInfoCtxtRegEntry; - -/* used to access a state-information block in a microcode image */ -typedef struct -{ - UINT32 size; - IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1]; -} IxNpeDlNpeMgrStateInfoBlock; - -/* used to store some useful NPE information for easy access */ -typedef struct -{ - UINT32 baseAddress; - UINT32 insMemSize; - UINT32 dataMemSize; -} IxNpeDlNpeInfo; - -/* used to distinguish instruction and data memory operations */ -typedef enum -{ - IX_NPEDL_MEM_TYPE_INSTRUCTION = 0, - IX_NPEDL_MEM_TYPE_DATA -} IxNpeDlNpeMemType; - -/* used to hold a reset value for a particular ECS register */ -typedef struct -{ - UINT32 regAddr; - UINT32 regResetVal; -} IxNpeDlEcsRegResetValue; - -/* prototype of function to write either Instruction or Data memory */ -typedef IX_STATUS (*IxNpeDlNpeMgrMemWrite) (UINT32 npeBaseAddress, - UINT32 npeMemAddress, - UINT32 npeMemData, - BOOL verify); - -/* module statistics counters */ -typedef struct -{ - UINT32 instructionBlocksLoaded; - UINT32 dataBlocksLoaded; - UINT32 stateInfoBlocksLoaded; - UINT32 criticalNpeErrors; - UINT32 criticalMicrocodeErrors; - UINT32 npeStarts; - UINT32 npeStops; - UINT32 npeResets; -} IxNpeDlNpeMgrStats; - - -/* - * Variable declarations global to this file only. Externs are followed by - * static variables. - */ -static IxNpeDlNpeInfo ixNpeDlNpeInfo[] = -{ - { - 0, - IX_NPEDL_INS_MEMSIZE_WORDS_NPEA, - IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA - }, - { - 0, - IX_NPEDL_INS_MEMSIZE_WORDS_NPEB, - IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB - }, - { - 0, - IX_NPEDL_INS_MEMSIZE_WORDS_NPEC, - IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC - } -}; - -/* contains Reset values for Context Store Registers */ -static UINT32 ixNpeDlCtxtRegResetValues[] = -{ - IX_NPEDL_CTXT_REG_RESET_STEVT, - IX_NPEDL_CTXT_REG_RESET_STARTPC, - IX_NPEDL_CTXT_REG_RESET_REGMAP, - IX_NPEDL_CTXT_REG_RESET_CINDEX, -}; - -/* contains Reset values for Context Store Registers */ -static IxNpeDlEcsRegResetValue ixNpeDlEcsRegResetValues[] = -{ - {IX_NPEDL_ECS_BG_CTXT_REG_0, IX_NPEDL_ECS_BG_CTXT_REG_0_RESET}, - {IX_NPEDL_ECS_BG_CTXT_REG_1, IX_NPEDL_ECS_BG_CTXT_REG_1_RESET}, - {IX_NPEDL_ECS_BG_CTXT_REG_2, IX_NPEDL_ECS_BG_CTXT_REG_2_RESET}, - {IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET}, - {IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET}, - {IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET}, - {IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET}, - {IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET}, - {IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET}, - {IX_NPEDL_ECS_DBG_CTXT_REG_0, IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET}, - {IX_NPEDL_ECS_DBG_CTXT_REG_1, IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET}, - {IX_NPEDL_ECS_DBG_CTXT_REG_2, IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET}, - {IX_NPEDL_ECS_INSTRUCT_REG, IX_NPEDL_ECS_INSTRUCT_REG_RESET} -}; - -static IxNpeDlNpeMgrStats ixNpeDlNpeMgrStats; - -/* Set when NPE register memory has been mapped */ -static BOOL ixNpeDlMemInitialised = FALSE; - - -/* - * static function prototypes. - */ -PRIVATE IX_STATUS -ixNpeDlNpeMgrMemLoad (IxNpeDlNpeId npeId, UINT32 npeBaseAddress, - IxNpeDlNpeMgrCodeBlock *codeBlockPtr, - BOOL verify, IxNpeDlNpeMemType npeMemType); -PRIVATE IX_STATUS -ixNpeDlNpeMgrStateInfoLoad (UINT32 npeBaseAddress, - IxNpeDlNpeMgrStateInfoBlock *codeBlockPtr, - BOOL verify); -PRIVATE BOOL -ixNpeDlNpeMgrBitsSetCheck (UINT32 npeBaseAddress, UINT32 regOffset, - UINT32 expectedBitsSet); - -PRIVATE UINT32 -ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId); - -/* - * Function definition: ixNpeDlNpeMgrBaseAddressGet - */ -PRIVATE UINT32 -ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId) -{ - IX_OSAL_ASSERT (ixNpeDlMemInitialised); - return ixNpeDlNpeInfo[npeId].baseAddress; -} - - -/* - * Function definition: ixNpeDlNpeMgrInit - */ -void -ixNpeDlNpeMgrInit (void) -{ - /* Only map the memory once */ - if (!ixNpeDlMemInitialised) - { - UINT32 virtAddr; - - /* map the register memory for NPE-A */ - virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEA, - IX_OSAL_IXP400_NPEA_MAP_SIZE); - IX_OSAL_ASSERT(virtAddr); - ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = virtAddr; - - /* map the register memory for NPE-B */ - virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEB, - IX_OSAL_IXP400_NPEB_MAP_SIZE); - IX_OSAL_ASSERT(virtAddr); - ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = virtAddr; - - /* map the register memory for NPE-C */ - virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEC, - IX_OSAL_IXP400_NPEC_MAP_SIZE); - IX_OSAL_ASSERT(virtAddr); - ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = virtAddr; - - ixNpeDlMemInitialised = TRUE; - } -} - - -/* - * Function definition: ixNpeDlNpeMgrUninit - */ -IX_STATUS -ixNpeDlNpeMgrUninit (void) -{ - if (!ixNpeDlMemInitialised) - { - return IX_FAIL; - } - - IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress); - IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress); - IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress); - - ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = 0; - ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = 0; - ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = 0; - - ixNpeDlMemInitialised = FALSE; - - return IX_SUCCESS; -} - -/* - * Function definition: ixNpeDlNpeMgrImageLoad - */ -IX_STATUS -ixNpeDlNpeMgrImageLoad ( - IxNpeDlNpeId npeId, - UINT32 *imageCodePtr, - BOOL verify) -{ - UINT32 npeBaseAddress; - IxNpeDlNpeMgrDownloadMap *downloadMap; - UINT32 *blockPtr; - UINT32 mapIndex = 0; - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrImageLoad\n"); - - /* get base memory address of NPE from npeId */ - npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId); - - /* check execution status of NPE to verify NPE Stop was successful */ - if (!ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, - IX_NPEDL_EXCTL_STATUS_STOP)) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageDownload - " - "NPE was not stopped before download\n"); - status = IX_FAIL; - } - else - { - /* - * Read Download Map, checking each block type and calling - * appropriate function to perform download - */ - downloadMap = (IxNpeDlNpeMgrDownloadMap *) imageCodePtr; - while ((downloadMap->entry[mapIndex].eodmMarker != - IX_NPEDL_END_OF_DOWNLOAD_MAP) - && (status == IX_SUCCESS)) - { - /* calculate pointer to block to be downloaded */ - blockPtr = imageCodePtr + - downloadMap->entry[mapIndex].block.offset; - - switch (downloadMap->entry[mapIndex].block.type) - { - case IX_NPEDL_BLOCK_TYPE_INSTRUCTION: - status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress, - (IxNpeDlNpeMgrCodeBlock *)blockPtr, - verify, - IX_NPEDL_MEM_TYPE_INSTRUCTION); - break; - case IX_NPEDL_BLOCK_TYPE_DATA: - status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress, - (IxNpeDlNpeMgrCodeBlock *)blockPtr, - verify, IX_NPEDL_MEM_TYPE_DATA); - break; - case IX_NPEDL_BLOCK_TYPE_STATE: - status = ixNpeDlNpeMgrStateInfoLoad (npeBaseAddress, - (IxNpeDlNpeMgrStateInfoBlock *) blockPtr, - verify); - break; - default: - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageLoad: " - "unknown block type in download map\n"); - status = IX_NPEDL_CRITICAL_MICROCODE_ERR; - ixNpeDlNpeMgrStats.criticalMicrocodeErrors++; - break; - } - mapIndex++; - }/* loop: for each entry in download map, while status == SUCCESS */ - }/* condition: NPE stopped before attempting download */ - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrImageLoad : status = %d\n", - status); - return status; -} - - -/* - * Function definition: ixNpeDlNpeMgrMemLoad - */ -PRIVATE IX_STATUS -ixNpeDlNpeMgrMemLoad ( - IxNpeDlNpeId npeId, - UINT32 npeBaseAddress, - IxNpeDlNpeMgrCodeBlock *blockPtr, - BOOL verify, - IxNpeDlNpeMemType npeMemType) -{ - UINT32 npeMemAddress; - UINT32 blockSize; - UINT32 memSize = 0; - IxNpeDlNpeMgrMemWrite memWriteFunc = NULL; - UINT32 localIndex = 0; - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrMemLoad\n"); - - /* - * select NPE EXCTL reg read/write commands depending on memory - * type (instruction/data) to be accessed - */ - if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION) - { - memSize = ixNpeDlNpeInfo[npeId].insMemSize; - memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrInsMemWrite; - } - else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA) - { - memSize = ixNpeDlNpeInfo[npeId].dataMemSize; - memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrDataMemWrite; - } - - /* - * NPE memory is loaded contiguously from each block, so only address - * of 1st word in block is needed - */ - npeMemAddress = blockPtr->npeMemAddress; - /* number of words of instruction/data microcode in block to download */ - blockSize = blockPtr->size; - if ((npeMemAddress + blockSize) > memSize) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: " - "Block size too big for NPE memory\n"); - status = IX_NPEDL_CRITICAL_MICROCODE_ERR; - ixNpeDlNpeMgrStats.criticalMicrocodeErrors++; - } - else - { - for (localIndex = 0; localIndex < blockSize; localIndex++) - { - status = memWriteFunc (npeBaseAddress, npeMemAddress, - blockPtr->data[localIndex], verify); - - if (status != IX_SUCCESS) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: " - "write to NPE memory failed\n"); - status = IX_NPEDL_CRITICAL_NPE_ERR; - ixNpeDlNpeMgrStats.criticalNpeErrors++; - break; /* abort download */ - } - /* increment target (word)address in NPE memory */ - npeMemAddress++; - } - }/* condition: block size will fit in NPE memory */ - - if (status == IX_SUCCESS) - { - if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION) - { - ixNpeDlNpeMgrStats.instructionBlocksLoaded++; - } - else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA) - { - ixNpeDlNpeMgrStats.dataBlocksLoaded++; - } - } - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrMemLoad : status = %d\n", status); - return status; -} - - -/* - * Function definition: ixNpeDlNpeMgrStateInfoLoad - */ -PRIVATE IX_STATUS -ixNpeDlNpeMgrStateInfoLoad ( - UINT32 npeBaseAddress, - IxNpeDlNpeMgrStateInfoBlock *blockPtr, - BOOL verify) -{ - UINT32 blockSize; - UINT32 ctxtRegAddrInfo; - UINT32 ctxtRegVal; - IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */ - UINT32 ctxtNum; /* identifies Context number (0-16) */ - UINT32 i; - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrStateInfoLoad\n"); - - /* block size contains number of words of state-info in block */ - blockSize = blockPtr->size; - - ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress); - - /* for each state-info context register entry in block */ - for (i = 0; i < (blockSize/IX_NPEDL_STATE_INFO_ENTRY_SIZE); i++) - { - /* each state-info entry is 2 words (address, value) in length */ - ctxtRegAddrInfo = (blockPtr->ctxtRegEntry[i]).addressInfo; - ctxtRegVal = (blockPtr->ctxtRegEntry[i]).value; - - ctxtReg = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_REG); - ctxtNum = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM) >> - IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM; - - /* error-check Context Register No. and Context Number values */ - /* NOTE that there is no STEVT register for Context 0 */ - if ((ctxtReg < 0) || - (ctxtReg >= IX_NPEDL_CTXT_REG_MAX) || - (ctxtNum > IX_NPEDL_CTXT_NUM_MAX) || - ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT))) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: " - "invalid Context Register Address\n"); - status = IX_NPEDL_CRITICAL_MICROCODE_ERR; - ixNpeDlNpeMgrStats.criticalMicrocodeErrors++; - break; /* abort download */ - } - - status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum, ctxtReg, - ctxtRegVal, verify); - if (status != IX_SUCCESS) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: " - "write of state-info to NPE failed\n"); - status = IX_NPEDL_CRITICAL_NPE_ERR; - ixNpeDlNpeMgrStats.criticalNpeErrors++; - break; /* abort download */ - } - }/* loop: for each context reg entry in State Info block */ - - ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress); - - if (status == IX_SUCCESS) - { - ixNpeDlNpeMgrStats.stateInfoBlocksLoaded++; - } - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrStateInfoLoad : status = %d\n", - status); - return status; -} - - -/* - * Function definition: ixNpeDlNpeMgrNpeReset - */ -IX_STATUS -ixNpeDlNpeMgrNpeReset ( - IxNpeDlNpeId npeId) -{ - UINT32 npeBaseAddress; - IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */ - UINT32 ctxtNum; /* identifies Context number (0-16) */ - UINT32 regAddr; - UINT32 regVal; - UINT32 localIndex; - UINT32 indexMax; - IX_STATUS status = IX_SUCCESS; - IxFeatureCtrlReg unitFuseReg; - UINT32 ixNpeConfigCtrlRegVal; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrNpeReset\n"); - - /* get base memory address of NPE from npeId */ - npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId); - - /* pre-store the NPE Config Control Register Value */ - IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, &ixNpeConfigCtrlRegVal); - - ixNpeConfigCtrlRegVal |= 0x3F000000; - - /* disable the parity interrupt */ - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK)); - - ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress); - - /* - * clear the FIFOs - */ - while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, - IX_NPEDL_REG_OFFSET_WFIFO, - IX_NPEDL_MASK_WFIFO_VALID)) - { - /* read from the Watch-point FIFO until empty */ - IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WFIFO, - ®Val); - } - - while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, - IX_NPEDL_REG_OFFSET_STAT, - IX_NPEDL_MASK_STAT_OFNE)) - { - /* read from the outFIFO until empty */ - IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_FIFO, - ®Val); - } - - while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, - IX_NPEDL_REG_OFFSET_STAT, - IX_NPEDL_MASK_STAT_IFNE)) - { - /* - * step execution of the NPE intruction to read inFIFO using - * the Debug Executing Context stack - */ - status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, - IX_NPEDL_INSTR_RD_FIFO, 0, 0); - - if (IX_SUCCESS != status) - { - return status; - } - - } - - /* - * Reset the mailbox reg - */ - /* ...from XScale side */ - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_MBST, - IX_NPEDL_REG_RESET_MBST); - /* ...from NPE side */ - status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, - IX_NPEDL_INSTR_RESET_MBOX, 0, 0); - - if (IX_SUCCESS != status) - { - return status; - } - - /* - * Reset the physical registers in the NPE register file: - * Note: no need to save/restore REGMAP for Context 0 here - * since all Context Store regs are reset in subsequent code - */ - for (regAddr = 0; - (regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG) && (status != IX_FAIL); - regAddr++) - { - /* for each physical register in the NPE reg file, write 0 : */ - status = ixNpeDlNpeMgrPhysicalRegWrite (npeBaseAddress, regAddr, - 0, TRUE); - if (status != IX_SUCCESS) - { - return status; /* abort reset */ - } - } - - - /* - * Reset the context store: - */ - for (ctxtNum = IX_NPEDL_CTXT_NUM_MIN; - ctxtNum <= IX_NPEDL_CTXT_NUM_MAX; ctxtNum++) - { - /* set each context's Context Store registers to reset values: */ - for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++) - { - /* NOTE that there is no STEVT register for Context 0 */ - if (!((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT))) - { - regVal = ixNpeDlCtxtRegResetValues[ctxtReg]; - status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum, - ctxtReg, regVal, TRUE); - if (status != IX_SUCCESS) - { - return status; /* abort reset */ - } - } - } - } - - ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress); - - /* write Reset values to Execution Context Stack registers */ - indexMax = sizeof (ixNpeDlEcsRegResetValues) / - sizeof (IxNpeDlEcsRegResetValue); - for (localIndex = 0; localIndex < indexMax; localIndex++) - { - regAddr = ixNpeDlEcsRegResetValues[localIndex].regAddr; - regVal = ixNpeDlEcsRegResetValues[localIndex].regResetVal; - ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, regAddr, regVal); - } - - /* clear the profile counter */ - ixNpeDlNpeMgrCommandIssue (npeBaseAddress, - IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT); - - /* clear registers EXCT, AP0, AP1, AP2 and AP3 */ - for (regAddr = IX_NPEDL_REG_OFFSET_EXCT; - regAddr <= IX_NPEDL_REG_OFFSET_AP3; - regAddr += IX_NPEDL_BYTES_PER_WORD) - { - IX_NPEDL_REG_WRITE (npeBaseAddress, regAddr, 0); - } - - /* Reset the Watch-count register */ - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, 0); - - /* - * WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation - */ - - /* - * Call the feature control API to fused out and reset the NPE and its - * coprocessor - to reset internal states and remove parity error - */ - unitFuseReg = ixFeatureCtrlRead (); - unitFuseReg |= (IX_NPEDL_RESET_NPE_PARITY << npeId); - ixFeatureCtrlWrite (unitFuseReg); - - /* call the feature control API to un-fused and un-reset the NPE & COP */ - unitFuseReg &= (~(IX_NPEDL_RESET_NPE_PARITY << npeId)); - ixFeatureCtrlWrite (unitFuseReg); - - /* - * Call NpeMgr function to stop the NPE again after the Feature Control - * has unfused and Un-Reset the NPE and its associated Coprocessors - */ - status = ixNpeDlNpeMgrNpeStop (npeId); - - /* restore NPE configuration bus Control Register - Parity Settings */ - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, - (ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK)); - - ixNpeDlNpeMgrStats.npeResets++; - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrNpeReset : status = %d\n", status); - return status; -} - - -/* - * Function definition: ixNpeDlNpeMgrNpeStart - */ -IX_STATUS -ixNpeDlNpeMgrNpeStart ( - IxNpeDlNpeId npeId) -{ - UINT32 npeBaseAddress; - UINT32 ecsRegVal; - BOOL npeRunning; - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrNpeStart\n"); - - /* get base memory address of NPE from npeId */ - npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId); - - /* - * ensure only Background Context Stack Level is Active by turning off - * the Active bit in each of the other Executing Context Stack levels - */ - ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress, - IX_NPEDL_ECS_PRI_1_CTXT_REG_0); - ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE; - ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_1_CTXT_REG_0, - ecsRegVal); - - ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress, - IX_NPEDL_ECS_PRI_2_CTXT_REG_0); - ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE; - ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_2_CTXT_REG_0, - ecsRegVal); - - ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress, - IX_NPEDL_ECS_DBG_CTXT_REG_0); - ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE; - ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0, - ecsRegVal); - - /* clear the pipeline */ - ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE); - - /* start NPE execution by issuing command through EXCTL register on NPE */ - ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_START); - - /* - * check execution status of NPE to verify NPE Start operation was - * successful - */ - npeRunning = ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, - IX_NPEDL_REG_OFFSET_EXCTL, - IX_NPEDL_EXCTL_STATUS_RUN); - if (npeRunning) - { - ixNpeDlNpeMgrStats.npeStarts++; - } - else - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStart: " - "failed to start NPE execution\n"); - status = IX_FAIL; - } - - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrNpeStart : status = %d\n", status); - return status; -} - - -/* - * Function definition: ixNpeDlNpeMgrNpeStop - */ -IX_STATUS -ixNpeDlNpeMgrNpeStop ( - IxNpeDlNpeId npeId) -{ - UINT32 npeBaseAddress; - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrNpeStop\n"); - - /* get base memory address of NPE from npeId */ - npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId); - - /* stop NPE execution by issuing command through EXCTL register on NPE */ - ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STOP); - - /* verify that NPE Stop was successful */ - if (! ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, - IX_NPEDL_EXCTL_STATUS_STOP)) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStop: " - "failed to stop NPE execution\n"); - status = IX_FAIL; - } - - ixNpeDlNpeMgrStats.npeStops++; - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrNpeStop : status = %d\n", status); - return status; -} - - -/* - * Function definition: ixNpeDlNpeMgrBitsSetCheck - */ -PRIVATE BOOL -ixNpeDlNpeMgrBitsSetCheck ( - UINT32 npeBaseAddress, - UINT32 regOffset, - UINT32 expectedBitsSet) -{ - UINT32 regVal; - IX_NPEDL_REG_READ (npeBaseAddress, regOffset, ®Val); - - return expectedBitsSet == (expectedBitsSet & regVal); -} - - -/* - * Function definition: ixNpeDlNpeMgrStatsShow - */ -void -ixNpeDlNpeMgrStatsShow (void) -{ - ixOsalLog (IX_OSAL_LOG_LVL_USER, - IX_OSAL_LOG_DEV_STDOUT, - "\nixNpeDlNpeMgrStatsShow:\n" - "\tInstruction Blocks loaded: %u\n" - "\tData Blocks loaded: %u\n" - "\tState Information Blocks loaded: %u\n" - "\tCritical NPE errors: %u\n" - "\tCritical Microcode errors: %u\n", - ixNpeDlNpeMgrStats.instructionBlocksLoaded, - ixNpeDlNpeMgrStats.dataBlocksLoaded, - ixNpeDlNpeMgrStats.stateInfoBlocksLoaded, - ixNpeDlNpeMgrStats.criticalNpeErrors, - ixNpeDlNpeMgrStats.criticalMicrocodeErrors, - 0); - - ixOsalLog (IX_OSAL_LOG_LVL_USER, - IX_OSAL_LOG_DEV_STDOUT, - "\tSuccessful NPE Starts: %u\n" - "\tSuccessful NPE Stops: %u\n" - "\tSuccessful NPE Resets: %u\n\n", - ixNpeDlNpeMgrStats.npeStarts, - ixNpeDlNpeMgrStats.npeStops, - ixNpeDlNpeMgrStats.npeResets, - 0,0,0); - - ixNpeDlNpeMgrUtilsStatsShow (); -} - - -/* - * Function definition: ixNpeDlNpeMgrStatsReset - */ -void -ixNpeDlNpeMgrStatsReset (void) -{ - ixNpeDlNpeMgrStats.instructionBlocksLoaded = 0; - ixNpeDlNpeMgrStats.dataBlocksLoaded = 0; - ixNpeDlNpeMgrStats.stateInfoBlocksLoaded = 0; - ixNpeDlNpeMgrStats.criticalNpeErrors = 0; - ixNpeDlNpeMgrStats.criticalMicrocodeErrors = 0; - ixNpeDlNpeMgrStats.npeStarts = 0; - ixNpeDlNpeMgrStats.npeStops = 0; - ixNpeDlNpeMgrStats.npeResets = 0; - - ixNpeDlNpeMgrUtilsStatsReset (); -} diff --git a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c b/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c deleted file mode 100644 index 18cac50..0000000 --- a/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c +++ /dev/null @@ -1,806 +0,0 @@ -/** - * @file IxNpeDlNpeMgrUtils.c - * - * @author Intel Corporation - * @date 18 February 2002 - * - * @brief This file contains the implementation of the private API for the - * IXP425 NPE Downloader NpeMgr Utils module - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - - -/* - * Put the system defined include files required. - */ -#define IX_NPE_DL_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of - * retries before - * timeout - */ - -/* - * Put the user defined include files required. - */ -#include "IxOsal.h" -#include "IxNpeDl.h" -#include "IxNpeDlNpeMgrUtils_p.h" -#include "IxNpeDlNpeMgrEcRegisters_p.h" -#include "IxNpeDlMacros_p.h" - -/* - * #defines and macros used in this file. - */ - -/* used to bit-mask a number of bytes */ -#define IX_NPEDL_MASK_LOWER_BYTE_OF_WORD 0x000000FF -#define IX_NPEDL_MASK_LOWER_SHORT_OF_WORD 0x0000FFFF -#define IX_NPEDL_MASK_FULL_WORD 0xFFFFFFFF - -#define IX_NPEDL_BYTES_PER_WORD 4 -#define IX_NPEDL_BYTES_PER_SHORT 2 - -#define IX_NPEDL_REG_SIZE_BYTE 8 -#define IX_NPEDL_REG_SIZE_SHORT 16 -#define IX_NPEDL_REG_SIZE_WORD 32 - -/* - * Introduce extra read cycles after issuing read command to NPE - * so that we read the register after the NPE has updated it - * This is to overcome race condition between XScale and NPE - */ -#define IX_NPEDL_DELAY_READ_CYCLES 2 -/* - * To mask top three MSBs of 32bit word to download into NPE IMEM - */ -#define IX_NPEDL_MASK_UNUSED_IMEM_BITS 0x1FFFFFFF; - - -/* - * typedefs - */ -typedef struct -{ - UINT32 regAddress; - UINT32 regSize; -} IxNpeDlCtxtRegAccessInfo; - -/* module statistics counters */ -typedef struct -{ - UINT32 insMemWrites; - UINT32 insMemWriteFails; - UINT32 dataMemWrites; - UINT32 dataMemWriteFails; - UINT32 ecsRegWrites; - UINT32 ecsRegReads; - UINT32 dbgInstructionExecs; - UINT32 contextRegWrites; - UINT32 physicalRegWrites; - UINT32 nextPcWrites; -} IxNpeDlNpeMgrUtilsStats; - - -/* - * Variable declarations global to this file only. Externs are followed by - * static variables. - */ - -/* - * contains useful address and function pointers to read/write Context Regs, - * eliminating some switch or if-else statements in places - */ -static IxNpeDlCtxtRegAccessInfo ixNpeDlCtxtRegAccInfo[IX_NPEDL_CTXT_REG_MAX] = -{ - { - IX_NPEDL_CTXT_REG_ADDR_STEVT, - IX_NPEDL_REG_SIZE_BYTE - }, - { - IX_NPEDL_CTXT_REG_ADDR_STARTPC, - IX_NPEDL_REG_SIZE_SHORT - }, - { - IX_NPEDL_CTXT_REG_ADDR_REGMAP, - IX_NPEDL_REG_SIZE_SHORT - }, - { - IX_NPEDL_CTXT_REG_ADDR_CINDEX, - IX_NPEDL_REG_SIZE_BYTE - } -}; - -static UINT32 ixNpeDlSavedExecCount = 0; -static UINT32 ixNpeDlSavedEcsDbgCtxtReg2 = 0; - -static IxNpeDlNpeMgrUtilsStats ixNpeDlNpeMgrUtilsStats; - - -/* - * static function prototypes. - */ -PRIVATE __inline__ void -ixNpeDlNpeMgrWriteCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, - UINT32 addr, UINT32 data); - -PRIVATE __inline__ UINT32 -ixNpeDlNpeMgrReadCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr); - -PRIVATE IX_STATUS -ixNpeDlNpeMgrLogicalRegRead (UINT32 npeBaseAddress, UINT32 regAddr, - UINT32 regSize, UINT32 ctxtNum, UINT32 *regVal); - -PRIVATE IX_STATUS -ixNpeDlNpeMgrLogicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr, - UINT32 regVal, UINT32 regSize, - UINT32 ctxtNum, BOOL verify); - -/* - * Function definition: ixNpeDlNpeMgrWriteCommandIssue - */ -PRIVATE __inline__ void -ixNpeDlNpeMgrWriteCommandIssue ( - UINT32 npeBaseAddress, - UINT32 cmd, - UINT32 addr, - UINT32 data) -{ - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, data); - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr); - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd); -} - - -/* - * Function definition: ixNpeDlNpeMgrReadCommandIssue - */ -PRIVATE __inline__ UINT32 -ixNpeDlNpeMgrReadCommandIssue ( - UINT32 npeBaseAddress, - UINT32 cmd, - UINT32 addr) -{ - UINT32 data = 0; - int i; - - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr); - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd); - for (i = 0; i <= IX_NPEDL_DELAY_READ_CYCLES; i++) - { - IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, &data); - } - - return data; -} - -/* - * Function definition: ixNpeDlNpeMgrInsMemWrite - */ -IX_STATUS -ixNpeDlNpeMgrInsMemWrite ( - UINT32 npeBaseAddress, - UINT32 insMemAddress, - UINT32 insMemData, - BOOL verify) -{ - UINT32 insMemDataRtn; - - ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress, - IX_NPEDL_EXCTL_CMD_WR_INS_MEM, - insMemAddress, insMemData); - if (verify) - { - /* write invalid data to this reg, so we can see if we're reading - the EXDATA register too early */ - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, - ~insMemData); - - /*Disabled since top 3 MSB are not used for Azusa hardware Refer WR:IXA00053900*/ - insMemData&=IX_NPEDL_MASK_UNUSED_IMEM_BITS; - - insMemDataRtn=ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress, - IX_NPEDL_EXCTL_CMD_RD_INS_MEM, - insMemAddress); - - insMemDataRtn&=IX_NPEDL_MASK_UNUSED_IMEM_BITS; - - if (insMemData != insMemDataRtn) - { - ixNpeDlNpeMgrUtilsStats.insMemWriteFails++; - return IX_FAIL; - } - } - - ixNpeDlNpeMgrUtilsStats.insMemWrites++; - return IX_SUCCESS; -} - - -/* - * Function definition: ixNpeDlNpeMgrDataMemWrite - */ -IX_STATUS -ixNpeDlNpeMgrDataMemWrite ( - UINT32 npeBaseAddress, - UINT32 dataMemAddress, - UINT32 dataMemData, - BOOL verify) -{ - ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress, - IX_NPEDL_EXCTL_CMD_WR_DATA_MEM, - dataMemAddress, dataMemData); - if (verify) - { - /* write invalid data to this reg, so we can see if we're reading - the EXDATA register too early */ - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, ~dataMemData); - - if (dataMemData != - ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress, - IX_NPEDL_EXCTL_CMD_RD_DATA_MEM, - dataMemAddress)) - { - ixNpeDlNpeMgrUtilsStats.dataMemWriteFails++; - return IX_FAIL; - } - } - - ixNpeDlNpeMgrUtilsStats.dataMemWrites++; - return IX_SUCCESS; -} - - -/* - * Function definition: ixNpeDlNpeMgrExecAccRegWrite - */ -void -ixNpeDlNpeMgrExecAccRegWrite ( - UINT32 npeBaseAddress, - UINT32 regAddress, - UINT32 regData) -{ - ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress, - IX_NPEDL_EXCTL_CMD_WR_ECS_REG, - regAddress, regData); - ixNpeDlNpeMgrUtilsStats.ecsRegWrites++; -} - - -/* - * Function definition: ixNpeDlNpeMgrExecAccRegRead - */ -UINT32 -ixNpeDlNpeMgrExecAccRegRead ( - UINT32 npeBaseAddress, - UINT32 regAddress) -{ - ixNpeDlNpeMgrUtilsStats.ecsRegReads++; - return ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress, - IX_NPEDL_EXCTL_CMD_RD_ECS_REG, - regAddress); -} - - -/* - * Function definition: ixNpeDlNpeMgrCommandIssue - */ -void -ixNpeDlNpeMgrCommandIssue ( - UINT32 npeBaseAddress, - UINT32 command) -{ - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrCommandIssue\n"); - - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, command); - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrCommandIssue\n"); -} - - -/* - * Function definition: ixNpeDlNpeMgrDebugInstructionPreExec - */ -void -ixNpeDlNpeMgrDebugInstructionPreExec( - UINT32 npeBaseAddress) -{ - /* turn off the halt bit by clearing Execution Count register. */ - /* save reg contents 1st and restore later */ - IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, - &ixNpeDlSavedExecCount); - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, 0); - - /* ensure that IF and IE are on (temporarily), so that we don't end up - * stepping forever */ - ixNpeDlSavedEcsDbgCtxtReg2 = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress, - IX_NPEDL_ECS_DBG_CTXT_REG_2); - - ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2, - (ixNpeDlSavedEcsDbgCtxtReg2 | - IX_NPEDL_MASK_ECS_DBG_REG_2_IF | - IX_NPEDL_MASK_ECS_DBG_REG_2_IE)); -} - - -/* - * Function definition: ixNpeDlNpeMgrDebugInstructionExec - */ -IX_STATUS -ixNpeDlNpeMgrDebugInstructionExec( - UINT32 npeBaseAddress, - UINT32 npeInstruction, - UINT32 ctxtNum, - UINT32 ldur) -{ - UINT32 ecsDbgRegVal; - UINT32 oldWatchcount, newWatchcount; - UINT32 retriesCount = 0; - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrDebugInstructionExec\n"); - - /* set the Active bit, and the LDUR, in the debug level */ - ecsDbgRegVal = IX_NPEDL_MASK_ECS_REG_0_ACTIVE | - (ldur << IX_NPEDL_OFFSET_ECS_REG_0_LDUR); - - ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0, - ecsDbgRegVal); - - /* - * set CCTXT at ECS DEBUG L3 to specify in which context to execute the - * instruction, and set SELCTXT at ECS DEBUG Level to specify which context - * store to access. - * Debug ECS Level Reg 1 has form 0x000n000n, where n = context number - */ - ecsDbgRegVal = (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_CCTXT) | - (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT); - - ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_1, - ecsDbgRegVal); - - /* clear the pipeline */ - ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE); - - /* load NPE instruction into the instruction register */ - ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_INSTRUCT_REG, - npeInstruction); - - /* we need this value later to wait for completion of NPE execution step */ - IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, &oldWatchcount); - - /* issue a Step One command via the Execution Control register */ - ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STEP); - - /* Watch Count register increments when NPE completes an instruction */ - IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, - &newWatchcount); - - /* - * force the XScale to wait until the NPE has finished execution step - * NOTE that this delay will be very small, just long enough to allow a - * single NPE instruction to complete execution; if instruction execution - * is not completed before timeout retries, exit the while loop - */ - while ((IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount) - && (newWatchcount == oldWatchcount)) - { - /* Watch Count register increments when NPE completes an instruction */ - IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, - &newWatchcount); - - retriesCount++; - } - - if (IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount) - { - ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs++; - } - else - { - /* Return timeout status as the instruction has not been executed - * after maximum retries */ - status = IX_NPEDL_CRITICAL_NPE_ERR; - } - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrDebugInstructionExec\n"); - - return status; -} - - -/* - * Function definition: ixNpeDlNpeMgrDebugInstructionPostExec - */ -void -ixNpeDlNpeMgrDebugInstructionPostExec( - UINT32 npeBaseAddress) -{ - /* clear active bit in debug level */ - ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0, - 0); - - /* clear the pipeline */ - ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE); - - /* restore Execution Count register contents. */ - IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, - ixNpeDlSavedExecCount); - - /* restore IF and IE bits to original values */ - ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2, - ixNpeDlSavedEcsDbgCtxtReg2); -} - - -/* - * Function definition: ixNpeDlNpeMgrLogicalRegRead - */ -PRIVATE IX_STATUS -ixNpeDlNpeMgrLogicalRegRead ( - UINT32 npeBaseAddress, - UINT32 regAddr, - UINT32 regSize, - UINT32 ctxtNum, - UINT32 *regVal) -{ - IX_STATUS status = IX_SUCCESS; - UINT32 npeInstruction = 0; - UINT32 mask = 0; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrLogicalRegRead\n"); - - switch (regSize) - { - case IX_NPEDL_REG_SIZE_BYTE: - npeInstruction = IX_NPEDL_INSTR_RD_REG_BYTE; - mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD; break; - case IX_NPEDL_REG_SIZE_SHORT: - npeInstruction = IX_NPEDL_INSTR_RD_REG_SHORT; - mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD; break; - case IX_NPEDL_REG_SIZE_WORD: - npeInstruction = IX_NPEDL_INSTR_RD_REG_WORD; - mask = IX_NPEDL_MASK_FULL_WORD; break; - } - - /* make regAddr be the SRC and DEST operands (e.g. movX d0, d0) */ - npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_SRC) | - (regAddr << IX_NPEDL_OFFSET_INSTR_DEST); - - /* step execution of NPE intruction using Debug Executing Context stack */ - status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, npeInstruction, - ctxtNum, IX_NPEDL_RD_INSTR_LDUR); - - if (IX_SUCCESS != status) - { - return status; - } - - /* read value of register from Execution Data register */ - IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, regVal); - - /* align value from left to right */ - *regVal = (*regVal >> (IX_NPEDL_REG_SIZE_WORD - regSize)) & mask; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrLogicalRegRead\n"); - - return IX_SUCCESS; -} - - -/* - * Function definition: ixNpeDlNpeMgrLogicalRegWrite - */ -PRIVATE IX_STATUS -ixNpeDlNpeMgrLogicalRegWrite ( - UINT32 npeBaseAddress, - UINT32 regAddr, - UINT32 regVal, - UINT32 regSize, - UINT32 ctxtNum, - BOOL verify) -{ - UINT32 npeInstruction = 0; - UINT32 mask = 0; - IX_STATUS status = IX_SUCCESS; - UINT32 retRegVal; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrLogicalRegWrite\n"); - - if (regSize == IX_NPEDL_REG_SIZE_WORD) - { - /* NPE register addressing is left-to-right: e.g. |d0|d1|d2|d3| */ - /* Write upper half-word (short) to |d0|d1| */ - status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr, - regVal >> IX_NPEDL_REG_SIZE_SHORT, - IX_NPEDL_REG_SIZE_SHORT, - ctxtNum, verify); - - if (IX_SUCCESS != status) - { - return status; - } - - /* Write lower half-word (short) to |d2|d3| */ - status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, - regAddr + IX_NPEDL_BYTES_PER_SHORT, - regVal & IX_NPEDL_MASK_LOWER_SHORT_OF_WORD, - IX_NPEDL_REG_SIZE_SHORT, - ctxtNum, verify); - - if (IX_SUCCESS != status) - { - return status; - } - } - else - { - switch (regSize) - { - case IX_NPEDL_REG_SIZE_BYTE: - npeInstruction = IX_NPEDL_INSTR_WR_REG_BYTE; - mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD; break; - case IX_NPEDL_REG_SIZE_SHORT: - npeInstruction = IX_NPEDL_INSTR_WR_REG_SHORT; - mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD; break; - } - /* mask out any redundant bits, so verify will work later */ - regVal &= mask; - - /* fill dest operand field of instruction with destination reg addr */ - npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_DEST); - - /* fill src operand field of instruction with least-sig 5 bits of val*/ - npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA) << - IX_NPEDL_OFFSET_INSTR_SRC); - - /* fill coprocessor field of instruction with most-sig 11 bits of val*/ - npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) << - IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA); - - /* step execution of NPE intruction using Debug ECS */ - status = ixNpeDlNpeMgrDebugInstructionExec(npeBaseAddress, npeInstruction, - ctxtNum, IX_NPEDL_WR_INSTR_LDUR); - - if (IX_SUCCESS != status) - { - return status; - } - }/* condition: if reg to be written is 8-bit or 16-bit (not 32-bit) */ - - if (verify) - { - status = ixNpeDlNpeMgrLogicalRegRead (npeBaseAddress, regAddr, - regSize, ctxtNum, &retRegVal); - - if (IX_SUCCESS == status) - { - if (regVal != retRegVal) - { - status = IX_FAIL; - } - } - } - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrLogicalRegWrite : status = %d\n", - status); - - return status; -} - - -/* - * Function definition: ixNpeDlNpeMgrPhysicalRegWrite - */ -IX_STATUS -ixNpeDlNpeMgrPhysicalRegWrite ( - UINT32 npeBaseAddress, - UINT32 regAddr, - UINT32 regValue, - BOOL verify) -{ - IX_STATUS status; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrPhysicalRegWrite\n"); - -/* - * There are 32 physical registers used in an NPE. These are - * treated as 16 pairs of 32-bit registers. To write one of the pair, - * write the pair number (0-16) to the REGMAP for Context 0. Then write - * the value to register 0 or 4 in the regfile, depending on which - * register of the pair is to be written - */ - - /* - * set REGMAP for context 0 to (regAddr >> 1) to choose which pair (0-16) - * of physical registers to write - */ - status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, - IX_NPEDL_CTXT_REG_ADDR_REGMAP, - (regAddr >> - IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP), - IX_NPEDL_REG_SIZE_SHORT, 0, verify); - if (status == IX_SUCCESS) - { - /* regAddr = 0 or 4 */ - regAddr = (regAddr & IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR) * - IX_NPEDL_BYTES_PER_WORD; - - status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr, regValue, - IX_NPEDL_REG_SIZE_WORD, 0, verify); - } - - if (status != IX_SUCCESS) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrPhysicalRegWrite: " - "error writing to physical register\n"); - } - - ixNpeDlNpeMgrUtilsStats.physicalRegWrites++; - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrPhysicalRegWrite : status = %d\n", - status); - return status; -} - - -/* - * Function definition: ixNpeDlNpeMgrCtxtRegWrite - */ -IX_STATUS -ixNpeDlNpeMgrCtxtRegWrite ( - UINT32 npeBaseAddress, - UINT32 ctxtNum, - IxNpeDlCtxtRegNum ctxtReg, - UINT32 ctxtRegVal, - BOOL verify) -{ - UINT32 tempRegVal; - UINT32 ctxtRegAddr; - UINT32 ctxtRegSize; - IX_STATUS status = IX_SUCCESS; - - IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, - "Entering ixNpeDlNpeMgrCtxtRegWrite\n"); - - /* - * Context 0 has no STARTPC. Instead, this value is used to set - * NextPC for Background ECS, to set where NPE starts executing code - */ - if ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STARTPC)) - { - /* read BG_CTXT_REG_0, update NEXTPC bits, and write back to reg */ - tempRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress, - IX_NPEDL_ECS_BG_CTXT_REG_0); - tempRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_NEXTPC; - tempRegVal |= (ctxtRegVal << IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC) & - IX_NPEDL_MASK_ECS_REG_0_NEXTPC; - - ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, - IX_NPEDL_ECS_BG_CTXT_REG_0, tempRegVal); - - ixNpeDlNpeMgrUtilsStats.nextPcWrites++; - } - else - { - ctxtRegAddr = ixNpeDlCtxtRegAccInfo[ctxtReg].regAddress; - ctxtRegSize = ixNpeDlCtxtRegAccInfo[ctxtReg].regSize; - status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, ctxtRegAddr, - ctxtRegVal, ctxtRegSize, - ctxtNum, verify); - if (status != IX_SUCCESS) - { - IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrCtxtRegWrite: " - "error writing to context store register\n"); - } - - ixNpeDlNpeMgrUtilsStats.contextRegWrites++; - } - - IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, - "Exiting ixNpeDlNpeMgrCtxtRegWrite : status = %d\n", - status); - - return status; -} - - -/* - * Function definition: ixNpeDlNpeMgrUtilsStatsShow - */ -void -ixNpeDlNpeMgrUtilsStatsShow (void) -{ - ixOsalLog (IX_OSAL_LOG_LVL_USER, - IX_OSAL_LOG_DEV_STDOUT, - "\nixNpeDlNpeMgrUtilsStatsShow:\n" - "\tInstruction Memory writes: %u\n" - "\tInstruction Memory writes failed: %u\n" - "\tData Memory writes: %u\n" - "\tData Memory writes failed: %u\n", - ixNpeDlNpeMgrUtilsStats.insMemWrites, - ixNpeDlNpeMgrUtilsStats.insMemWriteFails, - ixNpeDlNpeMgrUtilsStats.dataMemWrites, - ixNpeDlNpeMgrUtilsStats.dataMemWriteFails, - 0,0); - - ixOsalLog (IX_OSAL_LOG_LVL_USER, - IX_OSAL_LOG_DEV_STDOUT, - "\tExecuting Context Stack Register writes: %u\n" - "\tExecuting Context Stack Register reads: %u\n" - "\tPhysical Register writes: %u\n" - "\tContext Store Register writes: %u\n" - "\tExecution Backgound Context NextPC writes: %u\n" - "\tDebug Instructions Executed: %u\n\n", - ixNpeDlNpeMgrUtilsStats.ecsRegWrites, - ixNpeDlNpeMgrUtilsStats.ecsRegReads, - ixNpeDlNpeMgrUtilsStats.physicalRegWrites, - ixNpeDlNpeMgrUtilsStats.contextRegWrites, - ixNpeDlNpeMgrUtilsStats.nextPcWrites, - ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs); -} - - -/* - * Function definition: ixNpeDlNpeMgrUtilsStatsReset - */ -void -ixNpeDlNpeMgrUtilsStatsReset (void) -{ - ixNpeDlNpeMgrUtilsStats.insMemWrites = 0; - ixNpeDlNpeMgrUtilsStats.insMemWriteFails = 0; - ixNpeDlNpeMgrUtilsStats.dataMemWrites = 0; - ixNpeDlNpeMgrUtilsStats.dataMemWriteFails = 0; - ixNpeDlNpeMgrUtilsStats.ecsRegWrites = 0; - ixNpeDlNpeMgrUtilsStats.ecsRegReads = 0; - ixNpeDlNpeMgrUtilsStats.physicalRegWrites = 0; - ixNpeDlNpeMgrUtilsStats.contextRegWrites = 0; - ixNpeDlNpeMgrUtilsStats.nextPcWrites = 0; - ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs = 0; -} diff --git a/arch/arm/cpu/ixp/npe/IxNpeMh.c b/arch/arm/cpu/ixp/npe/IxNpeMh.c deleted file mode 100644 index 8703def..0000000 --- a/arch/arm/cpu/ixp/npe/IxNpeMh.c +++ /dev/null @@ -1,582 +0,0 @@ -/** - * @file IxNpeMh.c - * - * @author Intel Corporation - * @date 18 Jan 2002 - * - * @brief This file contains the implementation of the public API for the - * IXP425 NPE Message Handler component. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * Put the system defined include files required. - */ - -/* - * Put the user defined include files required. - */ - -#include "IxOsal.h" -#include "IxNpeMhMacros_p.h" - -#include "IxNpeMh.h" - -#include "IxNpeMhConfig_p.h" -#include "IxNpeMhReceive_p.h" -#include "IxNpeMhSend_p.h" -#include "IxNpeMhSolicitedCbMgr_p.h" -#include "IxNpeMhUnsolicitedCbMgr_p.h" - -/* - * #defines and macros used in this file. - */ - -/* - * Typedefs whose scope is limited to this file. - */ - -/* - * Variable declarations global to this file only. Externs are followed by - * static variables. - */ - -PRIVATE BOOL ixNpeMhInitialized = FALSE; - -/* - * Extern function prototypes. - */ - -/* - * Static function prototypes. - */ - -/* - * Function definition: ixNpeMhInitialize - */ - -PUBLIC IX_STATUS ixNpeMhInitialize ( - IxNpeMhNpeInterrupts npeInterrupts) -{ - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhInitialize\n"); - - /* check the npeInterrupts parameter */ - if ((npeInterrupts != IX_NPEMH_NPEINTERRUPTS_NO) && - (npeInterrupts != IX_NPEMH_NPEINTERRUPTS_YES)) - { - IX_NPEMH_ERROR_REPORT ("Illegal npeInterrupts parameter value\n"); - return IX_FAIL; - } - - /* parameters are ok ... */ - - /* initialize the Receive module */ - ixNpeMhReceiveInitialize (); - - /* initialize the Solicited Callback Manager module */ - ixNpeMhSolicitedCbMgrInitialize (); - - /* initialize the Unsolicited Callback Manager module */ - ixNpeMhUnsolicitedCbMgrInitialize (); - - /* initialize the Configuration module - * - * NOTE: This module was originally configured before the - * others, but the sequence was changed so that interrupts - * would only be enabled after the handler functions were - * set up. The above modules need to be initialised to - * handle the NPE interrupts. See SCR #2231. - */ - ixNpeMhConfigInitialize (npeInterrupts); - - ixNpeMhInitialized = TRUE; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhInitialize\n"); - - return IX_SUCCESS; -} - -/* - * Function definition: ixNpeMhUnload - */ - -PUBLIC IX_STATUS ixNpeMhUnload (void) -{ - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhUnload\n"); - - if (!ixNpeMhInitialized) - { - return IX_FAIL; - } - - /* Uninitialize the Configuration module */ - ixNpeMhConfigUninit (); - - ixNpeMhInitialized = FALSE; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhUnload\n"); - - return IX_SUCCESS; -} - - -/* - * Function definition: ixNpeMhUnsolicitedCallbackRegister - */ - -PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackRegister ( - IxNpeMhNpeId npeId, - IxNpeMhMessageId messageId, - IxNpeMhCallback unsolicitedCallback) -{ - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhUnsolicitedCallbackRegister\n"); - - /* check that we are initialized */ - if (!ixNpeMhInitialized) - { - IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); - return IX_FAIL; - } - - /* check the npeId parameter */ - if (!ixNpeMhConfigNpeIdIsValid (npeId)) - { - IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); - return IX_FAIL; - } - - /* check the messageId parameter */ - if ((messageId < IX_NPEMH_MIN_MESSAGE_ID) - || (messageId > IX_NPEMH_MAX_MESSAGE_ID)) - { - IX_NPEMH_ERROR_REPORT ("Message ID is out of range\n"); - return IX_FAIL; - } - - /* the unsolicitedCallback parameter is allowed to be NULL */ - - /* parameters are ok ... */ - - /* get the lock to prevent other clients from entering */ - ixNpeMhConfigLockGet (npeId); - - /* save the unsolicited callback for the message ID */ - ixNpeMhUnsolicitedCbMgrCallbackSave ( - npeId, messageId, unsolicitedCallback); - - /* release the lock to allow other clients back in */ - ixNpeMhConfigLockRelease (npeId); - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhUnsolicitedCallbackRegister\n"); - - return IX_SUCCESS; -} - -/* - * Function definition: ixNpeMhUnsolicitedCallbackForRangeRegister - */ - -PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackForRangeRegister ( - IxNpeMhNpeId npeId, - IxNpeMhMessageId minMessageId, - IxNpeMhMessageId maxMessageId, - IxNpeMhCallback unsolicitedCallback) -{ - IxNpeMhMessageId messageId; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhUnsolicitedCallbackForRangeRegister\n"); - - /* check that we are initialized */ - if (!ixNpeMhInitialized) - { - IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); - return IX_FAIL; - } - - /* check the npeId parameter */ - if (!ixNpeMhConfigNpeIdIsValid (npeId)) - { - IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); - return IX_FAIL; - } - - /* check the minMessageId parameter */ - if ((minMessageId < IX_NPEMH_MIN_MESSAGE_ID) - || (minMessageId > IX_NPEMH_MAX_MESSAGE_ID)) - { - IX_NPEMH_ERROR_REPORT ("Min message ID is out of range\n"); - return IX_FAIL; - } - - /* check the maxMessageId parameter */ - if ((maxMessageId < IX_NPEMH_MIN_MESSAGE_ID) - || (maxMessageId > IX_NPEMH_MAX_MESSAGE_ID)) - { - IX_NPEMH_ERROR_REPORT ("Max message ID is out of range\n"); - return IX_FAIL; - } - - /* check the semantics of the message range parameters */ - if (minMessageId > maxMessageId) - { - IX_NPEMH_ERROR_REPORT ("Min message ID greater than max message " - "ID\n"); - return IX_FAIL; - } - - /* the unsolicitedCallback parameter is allowed to be NULL */ - - /* parameters are ok ... */ - - /* get the lock to prevent other clients from entering */ - ixNpeMhConfigLockGet (npeId); - - /* for each message ID in the range ... */ - for (messageId = minMessageId; messageId <= maxMessageId; messageId++) - { - /* save the unsolicited callback for the message ID */ - ixNpeMhUnsolicitedCbMgrCallbackSave ( - npeId, messageId, unsolicitedCallback); - } - - /* release the lock to allow other clients back in */ - ixNpeMhConfigLockRelease (npeId); - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhUnsolicitedCallbackForRangeRegister\n"); - - return IX_SUCCESS; -} - -/* - * Function definition: ixNpeMhMessageSend - */ - -PUBLIC IX_STATUS ixNpeMhMessageSend ( - IxNpeMhNpeId npeId, - IxNpeMhMessage message, - UINT32 maxSendRetries) -{ - IX_STATUS status = IX_SUCCESS; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhMessageSend\n"); - - /* check that we are initialized */ - if (!ixNpeMhInitialized) - { - IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); - return IX_FAIL; - } - - /* check the npeId parameter */ - if (!ixNpeMhConfigNpeIdIsValid (npeId)) - { - IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); - return IX_FAIL; - } - - /* parameters are ok ... */ - - /* get the lock to prevent other clients from entering */ - ixNpeMhConfigLockGet (npeId); - - /* send the message */ - status = ixNpeMhSendMessageSend (npeId, message, maxSendRetries); - if (status != IX_SUCCESS) - { - IX_NPEMH_ERROR_REPORT ("Failed to send message\n"); - } - - /* release the lock to allow other clients back in */ - ixNpeMhConfigLockRelease (npeId); - - IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhMessageSend" - " : status = %d\n", status); - - return status; -} - -/* - * Function definition: ixNpeMhMessageWithResponseSend - */ - -PUBLIC IX_STATUS ixNpeMhMessageWithResponseSend ( - IxNpeMhNpeId npeId, - IxNpeMhMessage message, - IxNpeMhMessageId solicitedMessageId, - IxNpeMhCallback solicitedCallback, - UINT32 maxSendRetries) -{ - IX_STATUS status = IX_SUCCESS; - IxNpeMhCallback unsolicitedCallback = NULL; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhMessageWithResponseSend\n"); - - /* check that we are initialized */ - if (!ixNpeMhInitialized) - { - IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); - return IX_FAIL; - } - - /* the solicitecCallback parameter is allowed to be NULL. this */ - /* signifies the client is not interested in the response message */ - - /* check the npeId parameter */ - if (!ixNpeMhConfigNpeIdIsValid (npeId)) - { - IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); - return IX_FAIL; - } - - /* check the solicitedMessageId parameter */ - if ((solicitedMessageId < IX_NPEMH_MIN_MESSAGE_ID) - || (solicitedMessageId > IX_NPEMH_MAX_MESSAGE_ID)) - { - IX_NPEMH_ERROR_REPORT ("Solicited message ID is out of range\n"); - return IX_FAIL; - } - - /* check the solicitedMessageId parameter. if an unsolicited */ - /* callback has been registered for the specified message ID then */ - /* report an error and return failure */ - ixNpeMhUnsolicitedCbMgrCallbackRetrieve ( - npeId, solicitedMessageId, &unsolicitedCallback); - if (unsolicitedCallback != NULL) - { - IX_NPEMH_ERROR_REPORT ("Solicited message ID conflicts with " - "unsolicited message ID\n"); - return IX_FAIL; - } - - /* parameters are ok ... */ - - /* get the lock to prevent other clients from entering */ - ixNpeMhConfigLockGet (npeId); - - /* send the message */ - status = ixNpeMhSendMessageWithResponseSend ( - npeId, message, solicitedMessageId, solicitedCallback, - maxSendRetries); - if (status != IX_SUCCESS) - { - IX_NPEMH_ERROR_REPORT ("Failed to send message\n"); - } - - /* release the lock to allow other clients back in */ - ixNpeMhConfigLockRelease (npeId); - - IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhMessageWithResponseSend" - " : status = %d\n", status); - - return status; -} - -/* - * Function definition: ixNpeMhMessagesReceive - */ - -PUBLIC IX_STATUS ixNpeMhMessagesReceive ( - IxNpeMhNpeId npeId) -{ - IX_STATUS status = IX_SUCCESS; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhMessagesReceive\n"); - - /* check that we are initialized */ - if (!ixNpeMhInitialized) - { - IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); - return IX_FAIL; - } - - /* check the npeId parameter */ - if (!ixNpeMhConfigNpeIdIsValid (npeId)) - { - IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); - return IX_FAIL; - } - - /* parameters are ok ... */ - - /* get the lock to prevent other clients from entering */ - ixNpeMhConfigLockGet (npeId); - - /* receive messages from the NPE */ - status = ixNpeMhReceiveMessagesReceive (npeId); - - if (status != IX_SUCCESS) - { - IX_NPEMH_ERROR_REPORT ("Failed to receive message\n"); - } - - /* release the lock to allow other clients back in */ - ixNpeMhConfigLockRelease (npeId); - - IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhMessagesReceive" - " : status = %d\n", status); - - return status; -} - -/* - * Function definition: ixNpeMhShow - */ - -PUBLIC IX_STATUS ixNpeMhShow ( - IxNpeMhNpeId npeId) -{ - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhShow\n"); - - /* check that we are initialized */ - if (!ixNpeMhInitialized) - { - IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); - return IX_FAIL; - } - - /* check the npeId parameter */ - if (!ixNpeMhConfigNpeIdIsValid (npeId)) - { - IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); - return IX_FAIL; - } - - /* parameters are ok ... */ - - /* note we don't get the lock here as printing the statistics */ - /* to a console may take some time and we don't want to impact */ - /* system performance. this means that the statistics displayed */ - /* may be in a state of flux and make not represent a consistent */ - /* snapshot. */ - - /* display a header */ - ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, - "Current state of NPE ID %d:\n\n", npeId, 0, 0, 0, 0, 0); - - /* show the current state of each module */ - - /* show the current state of the Configuration module */ - ixNpeMhConfigShow (npeId); - - /* show the current state of the Receive module */ - ixNpeMhReceiveShow (npeId); - - /* show the current state of the Send module */ - ixNpeMhSendShow (npeId); - - /* show the current state of the Solicited Callback Manager module */ - ixNpeMhSolicitedCbMgrShow (npeId); - - /* show the current state of the Unsolicited Callback Manager module */ - ixNpeMhUnsolicitedCbMgrShow (npeId); - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhShow\n"); - - return IX_SUCCESS; -} - -/* - * Function definition: ixNpeMhShowReset - */ - -PUBLIC IX_STATUS ixNpeMhShowReset ( - IxNpeMhNpeId npeId) -{ - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhShowReset\n"); - - /* check that we are initialized */ - if (!ixNpeMhInitialized) - { - IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); - return IX_FAIL; - } - - /* check the npeId parameter */ - if (!ixNpeMhConfigNpeIdIsValid (npeId)) - { - IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); - return IX_FAIL; - } - - /* parameters are ok ... */ - - /* note we don't get the lock here as resetting the statistics */ - /* shouldn't impact system performance. */ - - /* reset the current state of each module */ - - /* reset the current state of the Configuration module */ - ixNpeMhConfigShowReset (npeId); - - /* reset the current state of the Receive module */ - ixNpeMhReceiveShowReset (npeId); - - /* reset the current state of the Send module */ - ixNpeMhSendShowReset (npeId); - - /* reset the current state of the Solicited Callback Manager module */ - ixNpeMhSolicitedCbMgrShowReset (npeId); - - /* reset the current state of the Unsolicited Callback Manager module */ - ixNpeMhUnsolicitedCbMgrShowReset (npeId); - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhShowReset\n"); - - return IX_SUCCESS; -} diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhConfig.c b/arch/arm/cpu/ixp/npe/IxNpeMhConfig.c deleted file mode 100644 index 50c8f21..0000000 --- a/arch/arm/cpu/ixp/npe/IxNpeMhConfig.c +++ /dev/null @@ -1,608 +0,0 @@ -/** - * @file IxNpeMhConfig.c - * - * @author Intel Corporation - * @date 18 Jan 2002 - * - * @brief This file contains the implementation of the private API for the - * Configuration module. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * Put the system defined include files required. - */ - - -/* - * Put the user defined include files required. - */ - -#include "IxOsal.h" - -#include "IxNpeMhMacros_p.h" - -#include "IxNpeMhConfig_p.h" - -/* - * #defines and macros used in this file. - */ -#define IX_NPE_MH_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of - * retries before - * timeout - */ - -/* - * Typedefs whose scope is limited to this file. - */ - -/** - * @struct IxNpeMhConfigStats - * - * @brief This structure is used to maintain statistics for the - * Configuration module. - */ - -typedef struct -{ - UINT32 outFifoReads; /**< outFifo reads */ - UINT32 inFifoWrites; /**< inFifo writes */ - UINT32 maxInFifoFullRetries; /**< max retries if inFIFO full */ - UINT32 maxOutFifoEmptyRetries; /**< max retries if outFIFO empty */ -} IxNpeMhConfigStats; - -/* - * Variable declarations global to this file only. Externs are followed by - * static variables. - */ - -IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES] = -{ - { - 0, - IX_NPEMH_NPEA_INT, - 0, - 0, - 0, - 0, - 0, - NULL, - FALSE - }, - { - 0, - IX_NPEMH_NPEB_INT, - 0, - 0, - 0, - 0, - 0, - NULL, - FALSE - }, - { - 0, - IX_NPEMH_NPEC_INT, - 0, - 0, - 0, - 0, - 0, - NULL, - FALSE - } -}; - -PRIVATE IxNpeMhConfigStats ixNpeMhConfigStats[IX_NPEMH_NUM_NPES]; - -/* - * Extern function prototypes. - */ - -/* - * Static function prototypes. - */ -PRIVATE -void ixNpeMhConfigIsr (void *parameter); - -/* - * Function definition: ixNpeMhConfigIsr - */ - -PRIVATE -void ixNpeMhConfigIsr (void *parameter) -{ - IxNpeMhNpeId npeId = (IxNpeMhNpeId)parameter; - UINT32 ofint; - volatile UINT32 *statusReg = - (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhConfigIsr\n"); - - /* get the OFINT (OutFifo interrupt) bit of the status register */ - IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofint, IX_NPEMH_NPE_STAT_OFINT); - - /* if the OFINT status bit is set */ - if (ofint) - { - /* if there is an ISR registered for this NPE */ - if (ixNpeMhConfigNpeInfo[npeId].isr != NULL) - { - /* invoke the ISR routine */ - ixNpeMhConfigNpeInfo[npeId].isr (npeId); - } - else - { - /* if we don't service the interrupt the NPE will continue */ - /* to trigger the interrupt indefinitely */ - IX_NPEMH_ERROR_REPORT ("No ISR registered to service " - "interrupt\n"); - } - } - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhConfigIsr\n"); -} - -/* - * Function definition: ixNpeMhConfigInitialize - */ - -void ixNpeMhConfigInitialize ( - IxNpeMhNpeInterrupts npeInterrupts) -{ - IxNpeMhNpeId npeId; - UINT32 virtualAddr[IX_NPEMH_NUM_NPES]; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhConfigInitialize\n"); - - /* Request a mapping for the NPE-A config register address space */ - virtualAddr[IX_NPEMH_NPEID_NPEA] = - (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEA_BASE, - IX_OSAL_IXP400_NPEA_MAP_SIZE); - IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEA]); - - /* Request a mapping for the NPE-B config register address space */ - virtualAddr[IX_NPEMH_NPEID_NPEB] = - (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEB_BASE, - IX_OSAL_IXP400_NPEB_MAP_SIZE); - IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEB]); - - /* Request a mapping for the NPE-C config register address space */ - virtualAddr[IX_NPEMH_NPEID_NPEC] = - (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEC_BASE, - IX_OSAL_IXP400_NPEC_MAP_SIZE); - IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEC]); - - /* for each NPE ... */ - for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) - { - /* declare a convenience pointer */ - IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId]; - - /* store the virtual addresses of the NPE registers for later use */ - npeInfo->virtualRegisterBase = virtualAddr[npeId]; - npeInfo->statusRegister = virtualAddr[npeId] + IX_NPEMH_NPESTAT_OFFSET; - npeInfo->controlRegister = virtualAddr[npeId] + IX_NPEMH_NPECTL_OFFSET; - npeInfo->inFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET; - npeInfo->outFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET; - - /* for test purposes - to verify the register addresses */ - IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d status register = " - "0x%08X\n", npeId, npeInfo->statusRegister); - IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d control register = " - "0x%08X\n", npeId, npeInfo->controlRegister); - IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d inFifo register = " - "0x%08X\n", npeId, npeInfo->inFifoRegister); - IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d outFifo register = " - "0x%08X\n", npeId, npeInfo->outFifoRegister); - - /* connect our ISR to the NPE interrupt */ - (void) ixOsalIrqBind ( - npeInfo->interruptId, ixNpeMhConfigIsr, (void *)npeId); - - /* initialise a mutex for this NPE */ - (void) ixOsalMutexInit (&npeInfo->mutex); - - /* if we should service the NPE's "outFIFO not empty" interrupt */ - if (npeInterrupts == IX_NPEMH_NPEINTERRUPTS_YES) - { - /* enable the NPE's "outFIFO not empty" interrupt */ - ixNpeMhConfigNpeInterruptEnable (npeId); - } - else - { - /* disable the NPE's "outFIFO not empty" interrupt */ - ixNpeMhConfigNpeInterruptDisable (npeId); - } - } - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhConfigInitialize\n"); -} - -/* - * Function definition: ixNpeMhConfigUninit - */ - -void ixNpeMhConfigUninit (void) -{ - IxNpeMhNpeId npeId; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhConfigUninit\n"); - - /* for each NPE ... */ - for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) - { - /* declare a convenience pointer */ - IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId]; - - /* disconnect ISR */ - ixOsalIrqUnbind(npeInfo->interruptId); - - /* destroy mutex associated with this NPE */ - ixOsalMutexDestroy(&npeInfo->mutex); - - IX_OSAL_MEM_UNMAP (npeInfo->virtualRegisterBase); - - npeInfo->virtualRegisterBase = 0; - npeInfo->statusRegister = 0; - npeInfo->controlRegister = 0; - npeInfo->inFifoRegister = 0; - npeInfo->outFifoRegister = 0; - } - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhConfigUninit\n"); -} - -/* - * Function definition: ixNpeMhConfigIsrRegister - */ - -void ixNpeMhConfigIsrRegister ( - IxNpeMhNpeId npeId, - IxNpeMhConfigIsr isr) -{ - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhConfigIsrRegister\n"); - - /* check if there is already an ISR registered for this NPE */ - if (ixNpeMhConfigNpeInfo[npeId].isr != NULL) - { - IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Over-writing registered NPE ISR\n"); - } - - /* save the ISR routine with the NPE info */ - ixNpeMhConfigNpeInfo[npeId].isr = isr; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhConfigIsrRegister\n"); -} - -/* - * Function definition: ixNpeMhConfigNpeInterruptEnable - */ - -BOOL ixNpeMhConfigNpeInterruptEnable ( - IxNpeMhNpeId npeId) -{ - UINT32 ofe; - volatile UINT32 *controlReg = - (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister; - - /* get the OFE (OutFifoEnable) bit of the control register */ - IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE); - - /* if the interrupt is disabled then we must enable it */ - if (!ofe) - { - /* set the OFE (OutFifoEnable) bit of the control register */ - /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */ - /* time for the write to have effect */ - IX_NPEMH_REGISTER_WRITE_BITS (controlReg, - (IX_NPEMH_NPE_CTL_OFE | - IX_NPEMH_NPE_CTL_OFEWE), - (IX_NPEMH_NPE_CTL_OFE | - IX_NPEMH_NPE_CTL_OFEWE)); - } - - /* return the previous state of the interrupt */ - return (ofe != 0); -} - -/* - * Function definition: ixNpeMhConfigNpeInterruptDisable - */ - -BOOL ixNpeMhConfigNpeInterruptDisable ( - IxNpeMhNpeId npeId) -{ - UINT32 ofe; - volatile UINT32 *controlReg = - (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister; - - /* get the OFE (OutFifoEnable) bit of the control register */ - IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE); - - /* if the interrupt is enabled then we must disable it */ - if (ofe) - { - /* unset the OFE (OutFifoEnable) bit of the control register */ - /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */ - /* time for the write to have effect */ - IX_NPEMH_REGISTER_WRITE_BITS (controlReg, - (0 | - IX_NPEMH_NPE_CTL_OFEWE), - (IX_NPEMH_NPE_CTL_OFE | - IX_NPEMH_NPE_CTL_OFEWE)); - } - - /* return the previous state of the interrupt */ - return (ofe != 0); -} - -/* - * Function definition: ixNpeMhConfigMessageIdGet - */ - -IxNpeMhMessageId ixNpeMhConfigMessageIdGet ( - IxNpeMhMessage message) -{ - /* return the most-significant byte of the first word of the */ - /* message */ - return ((IxNpeMhMessageId) ((message.data[0] >> 24) & 0xFF)); -} - -/* - * Function definition: ixNpeMhConfigNpeIdIsValid - */ - -BOOL ixNpeMhConfigNpeIdIsValid ( - IxNpeMhNpeId npeId) -{ - /* check that the npeId parameter is within the range of valid IDs */ - return (npeId >= 0 && npeId < IX_NPEMH_NUM_NPES); -} - -/* - * Function definition: ixNpeMhConfigLockGet - */ - -void ixNpeMhConfigLockGet ( - IxNpeMhNpeId npeId) -{ - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhConfigLockGet\n"); - - /* lock the mutex for this NPE */ - (void) ixOsalMutexLock (&ixNpeMhConfigNpeInfo[npeId].mutex, - IX_OSAL_WAIT_FOREVER); - - /* disable the NPE's "outFIFO not empty" interrupt */ - ixNpeMhConfigNpeInfo[npeId].oldInterruptState = - ixNpeMhConfigNpeInterruptDisable (npeId); - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhConfigLockGet\n"); -} - -/* - * Function definition: ixNpeMhConfigLockRelease - */ - -void ixNpeMhConfigLockRelease ( - IxNpeMhNpeId npeId) -{ - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhConfigLockRelease\n"); - - /* if the interrupt was previously enabled */ - if (ixNpeMhConfigNpeInfo[npeId].oldInterruptState) - { - /* enable the NPE's "outFIFO not empty" interrupt */ - ixNpeMhConfigNpeInfo[npeId].oldInterruptState = - ixNpeMhConfigNpeInterruptEnable (npeId); - } - - /* unlock the mutex for this NPE */ - (void) ixOsalMutexUnlock (&ixNpeMhConfigNpeInfo[npeId].mutex); - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhConfigLockRelease\n"); -} - -/* - * Function definition: ixNpeMhConfigInFifoWrite - */ - -IX_STATUS ixNpeMhConfigInFifoWrite ( - IxNpeMhNpeId npeId, - IxNpeMhMessage message) -{ - volatile UINT32 *npeInFifo = - (UINT32 *)ixNpeMhConfigNpeInfo[npeId].inFifoRegister; - UINT32 retriesCount = 0; - - /* write the first word of the message to the NPE's inFIFO */ - IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[0]); - - /* need to wait for room to write second word - see SCR #493, - poll for maximum number of retries, if exceed maximum - retries, exit from while loop */ - while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount) - && ixNpeMhConfigInFifoIsFull (npeId)) - { - retriesCount++; - } - - /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */ - if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount) - { - return IX_NPEMH_CRITICAL_NPE_ERR; - } - - /* write the second word of the message to the NPE's inFIFO */ - IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[1]); - - /* record in the stats the maximum number of retries needed */ - if (ixNpeMhConfigStats[npeId].maxInFifoFullRetries < retriesCount) - { - ixNpeMhConfigStats[npeId].maxInFifoFullRetries = retriesCount; - } - - /* update statistical info */ - ixNpeMhConfigStats[npeId].inFifoWrites++; - - return IX_SUCCESS; -} - -/* - * Function definition: ixNpeMhConfigOutFifoRead - */ - -IX_STATUS ixNpeMhConfigOutFifoRead ( - IxNpeMhNpeId npeId, - IxNpeMhMessage *message) -{ - volatile UINT32 *npeOutFifo = - (UINT32 *)ixNpeMhConfigNpeInfo[npeId].outFifoRegister; - UINT32 retriesCount = 0; - - /* read the first word of the message from the NPE's outFIFO */ - IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[0]); - - /* need to wait for NPE to write second word - see SCR #493 - poll for maximum number of retries, if exceed maximum - retries, exit from while loop */ - while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount) - && ixNpeMhConfigOutFifoIsEmpty (npeId)) - { - retriesCount++; - } - - /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */ - if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount) - { - return IX_NPEMH_CRITICAL_NPE_ERR; - } - - /* read the second word of the message from the NPE's outFIFO */ - IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[1]); - - /* record in the stats the maximum number of retries needed */ - if (ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries < retriesCount) - { - ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = retriesCount; - } - - /* update statistical info */ - ixNpeMhConfigStats[npeId].outFifoReads++; - - return IX_SUCCESS; -} - -/* - * Function definition: ixNpeMhConfigShow - */ - -void ixNpeMhConfigShow ( - IxNpeMhNpeId npeId) -{ - /* show the message fifo read counter */ - IX_NPEMH_SHOW ("Message FIFO reads", - ixNpeMhConfigStats[npeId].outFifoReads); - - /* show the message fifo write counter */ - IX_NPEMH_SHOW ("Message FIFO writes", - ixNpeMhConfigStats[npeId].inFifoWrites); - - /* show the max retries performed when inFIFO full */ - IX_NPEMH_SHOW ("Max inFIFO Full retries", - ixNpeMhConfigStats[npeId].maxInFifoFullRetries); - - /* show the max retries performed when outFIFO empty */ - IX_NPEMH_SHOW ("Max outFIFO Empty retries", - ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries); - - /* show the current status of the inFifo */ - ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, - "InFifo is %s and %s\n", - (ixNpeMhConfigInFifoIsEmpty (npeId) ? - (int) "EMPTY" : (int) "NOT EMPTY"), - (ixNpeMhConfigInFifoIsFull (npeId) ? - (int) "FULL" : (int) "NOT FULL"), - 0, 0, 0, 0); - - /* show the current status of the outFifo */ - ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, - "OutFifo is %s and %s\n", - (ixNpeMhConfigOutFifoIsEmpty (npeId) ? - (int) "EMPTY" : (int) "NOT EMPTY"), - (ixNpeMhConfigOutFifoIsFull (npeId) ? - (int) "FULL" : (int) "NOT FULL"), - 0, 0, 0, 0); -} - -/* - * Function definition: ixNpeMhConfigShowReset - */ - -void ixNpeMhConfigShowReset ( - IxNpeMhNpeId npeId) -{ - /* reset the message fifo read counter */ - ixNpeMhConfigStats[npeId].outFifoReads = 0; - - /* reset the message fifo write counter */ - ixNpeMhConfigStats[npeId].inFifoWrites = 0; - - /* reset the max inFIFO Full retries counter */ - ixNpeMhConfigStats[npeId].maxInFifoFullRetries = 0; - - /* reset the max outFIFO empty retries counter */ - ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = 0; -} - - diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhReceive.c b/arch/arm/cpu/ixp/npe/IxNpeMhReceive.c deleted file mode 100644 index 57c8be3..0000000 --- a/arch/arm/cpu/ixp/npe/IxNpeMhReceive.c +++ /dev/null @@ -1,320 +0,0 @@ -/** - * @file IxNpeMhReceive.c - * - * @author Intel Corporation - * @date 18 Jan 2002 - * - * @brief This file contains the implementation of the private API for the - * Receive module. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * Put the system defined include files required. - */ - - -/* - * Put the user defined include files required. - */ -#include "IxOsal.h" -#include "IxNpeMhMacros_p.h" -#include "IxNpeMhConfig_p.h" -#include "IxNpeMhReceive_p.h" -#include "IxNpeMhSolicitedCbMgr_p.h" -#include "IxNpeMhUnsolicitedCbMgr_p.h" - -/* - * #defines and macros used in this file. - */ - -/* - * Typedefs whose scope is limited to this file. - */ - -/** - * @struct IxNpeMhReceiveStats - * - * @brief This structure is used to maintain statistics for the Receive - * module. - */ - -typedef struct -{ - UINT32 isrs; /**< receive ISR invocations */ - UINT32 receives; /**< receive messages invocations */ - UINT32 messages; /**< messages received */ - UINT32 solicited; /**< solicited messages received */ - UINT32 unsolicited; /**< unsolicited messages received */ - UINT32 callbacks; /**< callbacks invoked */ -} IxNpeMhReceiveStats; - -/* - * Variable declarations global to this file only. Externs are followed by - * static variables. - */ - -PRIVATE IxNpeMhReceiveStats ixNpeMhReceiveStats[IX_NPEMH_NUM_NPES]; - -/* - * Extern function prototypes. - */ - -/* - * Static function prototypes. - */ -PRIVATE -void ixNpeMhReceiveIsr (int npeId); - -PRIVATE -void ixNpeMhReceiveIsr (int npeId) -{ - int lockKey; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhReceiveIsr\n"); - - lockKey = ixOsalIrqLock (); - - /* invoke the message receive routine to get messages from the NPE */ - ixNpeMhReceiveMessagesReceive (npeId); - - /* update statistical info */ - ixNpeMhReceiveStats[npeId].isrs++; - - ixOsalIrqUnlock (lockKey); - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhReceiveIsr\n"); -} - -/* - * Function definition: ixNpeMhReceiveInitialize - */ - -void ixNpeMhReceiveInitialize (void) -{ - IxNpeMhNpeId npeId = 0; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhReceiveInitialize\n"); - - /* for each NPE ... */ - for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) - { - /* register our internal ISR for the NPE to handle "outFIFO not */ - /* empty" interrupts */ - ixNpeMhConfigIsrRegister (npeId, ixNpeMhReceiveIsr); - } - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhReceiveInitialize\n"); -} - -/* - * Function definition: ixNpeMhReceiveMessagesReceive - */ - -IX_STATUS ixNpeMhReceiveMessagesReceive ( - IxNpeMhNpeId npeId) -{ - IxNpeMhMessage message = { { 0, 0 } }; - IxNpeMhMessageId messageId = 0; - IxNpeMhCallback callback = NULL; - IX_STATUS status; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhReceiveMessagesReceive\n"); - - /* update statistical info */ - ixNpeMhReceiveStats[npeId].receives++; - - /* while the NPE has messages in its outFIFO */ - while (!ixNpeMhConfigOutFifoIsEmpty (npeId)) - { - /* read a message from the NPE's outFIFO */ - status = ixNpeMhConfigOutFifoRead (npeId, &message); - - if (IX_SUCCESS != status) - { - return status; - } - - /* get the ID of the message */ - messageId = ixNpeMhConfigMessageIdGet (message); - - IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, - "Received message from NPE %d with ID 0x%02X\n", - npeId, messageId); - - /* update statistical info */ - ixNpeMhReceiveStats[npeId].messages++; - - /* try to find a matching unsolicited callback for this message. */ - - /* we assume the message is unsolicited. only if there is no */ - /* unsolicited callback for this message type do we assume the */ - /* message is solicited. it is much faster to check for an */ - /* unsolicited callback, so doing this check first should result */ - /* in better performance. */ - - ixNpeMhUnsolicitedCbMgrCallbackRetrieve ( - npeId, messageId, &callback); - - if (callback != NULL) - { - IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, - "Found matching unsolicited callback\n"); - - /* update statistical info */ - ixNpeMhReceiveStats[npeId].unsolicited++; - } - - /* if no unsolicited callback was found try to find a matching */ - /* solicited callback for this message */ - if (callback == NULL) - { - ixNpeMhSolicitedCbMgrCallbackRetrieve ( - npeId, messageId, &callback); - - if (callback != NULL) - { - IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, - "Found matching solicited callback\n"); - - /* update statistical info */ - ixNpeMhReceiveStats[npeId].solicited++; - } - } - - /* if a callback (either unsolicited or solicited) was found */ - if (callback != NULL) - { - /* invoke the callback to pass the message back to the client */ - callback (npeId, message); - - /* update statistical info */ - ixNpeMhReceiveStats[npeId].callbacks++; - } - else /* no callback (neither unsolicited nor solicited) was found */ - { - IX_NPEMH_TRACE2 (IX_NPEMH_WARNING, - "No matching callback for NPE %d" - " and ID 0x%02X, discarding message\n", - npeId, messageId); - - /* the message will be discarded. this is normal behaviour */ - /* if the client passes a NULL solicited callback when */ - /* sending a message. this indicates that the client is not */ - /* interested in receiving the response. alternatively a */ - /* NULL callback here may signify an unsolicited message */ - /* with no appropriate registered callback. */ - } - } - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhReceiveMessagesReceive\n"); - - return IX_SUCCESS; -} - -/* - * Function definition: ixNpeMhReceiveShow - */ - -void ixNpeMhReceiveShow ( - IxNpeMhNpeId npeId) -{ - /* show the ISR invocation counter */ - IX_NPEMH_SHOW ("Receive ISR invocations", - ixNpeMhReceiveStats[npeId].isrs); - - /* show the receive message invocation counter */ - IX_NPEMH_SHOW ("Receive messages invocations", - ixNpeMhReceiveStats[npeId].receives); - - /* show the message received counter */ - IX_NPEMH_SHOW ("Messages received", - ixNpeMhReceiveStats[npeId].messages); - - /* show the solicited message counter */ - IX_NPEMH_SHOW ("Solicited messages received", - ixNpeMhReceiveStats[npeId].solicited); - - /* show the unsolicited message counter */ - IX_NPEMH_SHOW ("Unsolicited messages received", - ixNpeMhReceiveStats[npeId].unsolicited); - - /* show the callback invoked counter */ - IX_NPEMH_SHOW ("Callbacks invoked", - ixNpeMhReceiveStats[npeId].callbacks); - - /* show the message discarded counter */ - IX_NPEMH_SHOW ("Received messages discarded", - (ixNpeMhReceiveStats[npeId].messages - - ixNpeMhReceiveStats[npeId].callbacks)); -} - -/* - * Function definition: ixNpeMhReceiveShowReset - */ - -void ixNpeMhReceiveShowReset ( - IxNpeMhNpeId npeId) -{ - /* reset the ISR invocation counter */ - ixNpeMhReceiveStats[npeId].isrs = 0; - - /* reset the receive message invocation counter */ - ixNpeMhReceiveStats[npeId].receives = 0; - - /* reset the message received counter */ - ixNpeMhReceiveStats[npeId].messages = 0; - - /* reset the solicited message counter */ - ixNpeMhReceiveStats[npeId].solicited = 0; - - /* reset the unsolicited message counter */ - ixNpeMhReceiveStats[npeId].unsolicited = 0; - - /* reset the callback invoked counter */ - ixNpeMhReceiveStats[npeId].callbacks = 0; -} diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhSend.c b/arch/arm/cpu/ixp/npe/IxNpeMhSend.c deleted file mode 100644 index 318913a..0000000 --- a/arch/arm/cpu/ixp/npe/IxNpeMhSend.c +++ /dev/null @@ -1,307 +0,0 @@ -/** - * @file IxNpeMhSend.c - * - * @author Intel Corporation - * @date 18 Jan 2002 - * - * @brief This file contains the implementation of the private API for the - * Send module. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * Put the system defined include files required. - */ - - -/* - * Put the user defined include files required. - */ - -#include "IxNpeMhMacros_p.h" - -#include "IxNpeMhConfig_p.h" -#include "IxNpeMhSend_p.h" -#include "IxNpeMhSolicitedCbMgr_p.h" - -/* - * #defines and macros used in this file. - */ - -/** - * @def IX_NPEMH_INFIFO_RETRY_DELAY_US - * - * @brief Amount of time (uSecs) to delay between retries - * while inFIFO is Full when attempting to send a message - */ -#define IX_NPEMH_INFIFO_RETRY_DELAY_US (1) - - -/* - * Typedefs whose scope is limited to this file. - */ - -/** - * @struct IxNpeMhSendStats - * - * @brief This structure is used to maintain statistics for the Send - * module. - */ - -typedef struct -{ - UINT32 sends; /**< send invocations */ - UINT32 sendWithResponses; /**< send with response invocations */ - UINT32 queueFulls; /**< fifo queue full occurrences */ - UINT32 queueFullRetries; /**< fifo queue full retry occurrences */ - UINT32 maxQueueFullRetries; /**< max fifo queue full retries */ - UINT32 callbackFulls; /**< callback list full occurrences */ -} IxNpeMhSendStats; - -/* - * Variable declarations global to this file only. Externs are followed by - * static variables. - */ - -PRIVATE IxNpeMhSendStats ixNpeMhSendStats[IX_NPEMH_NUM_NPES]; - -/* - * Extern function prototypes. - */ - -/* - * Static function prototypes. - */ -PRIVATE -BOOL ixNpeMhSendInFifoIsFull( - IxNpeMhNpeId npeId, - UINT32 maxSendRetries); - -/* - * Function definition: ixNpeMhSendInFifoIsFull - */ - -PRIVATE -BOOL ixNpeMhSendInFifoIsFull( - IxNpeMhNpeId npeId, - UINT32 maxSendRetries) -{ - BOOL isFull = FALSE; - UINT32 numRetries = 0; - - /* check the NPE's inFIFO */ - isFull = ixNpeMhConfigInFifoIsFull (npeId); - - /* we retry a few times, just to give the NPE a chance to read from */ - /* the FIFO if the FIFO is currently full */ - while (isFull && (numRetries++ < maxSendRetries)) - { - if (numRetries >= IX_NPEMH_SEND_RETRIES_DEFAULT) - { - /* Delay here for as short a time as possible (1 us). */ - /* Adding a delay here should ensure we are not hogging */ - /* the AHB bus while we are retrying */ - ixOsalBusySleep (IX_NPEMH_INFIFO_RETRY_DELAY_US); - } - - /* re-check the NPE's inFIFO */ - isFull = ixNpeMhConfigInFifoIsFull (npeId); - - /* update statistical info */ - ixNpeMhSendStats[npeId].queueFullRetries++; - } - - /* record the highest number of retries that occurred */ - if (ixNpeMhSendStats[npeId].maxQueueFullRetries < numRetries) - { - ixNpeMhSendStats[npeId].maxQueueFullRetries = numRetries; - } - - if (isFull) - { - /* update statistical info */ - ixNpeMhSendStats[npeId].queueFulls++; - } - - return isFull; -} - -/* - * Function definition: ixNpeMhSendMessageSend - */ - -IX_STATUS ixNpeMhSendMessageSend ( - IxNpeMhNpeId npeId, - IxNpeMhMessage message, - UINT32 maxSendRetries) -{ - IX_STATUS status; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhSendMessageSend\n"); - - /* update statistical info */ - ixNpeMhSendStats[npeId].sends++; - - /* check if the NPE's inFIFO is full - if so return an error */ - if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries)) - { - IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n"); - return IX_FAIL; - } - - /* write the message to the NPE's inFIFO */ - status = ixNpeMhConfigInFifoWrite (npeId, message); - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhSendMessageSend\n"); - - return status; -} - -/* - * Function definition: ixNpeMhSendMessageWithResponseSend - */ - -IX_STATUS ixNpeMhSendMessageWithResponseSend ( - IxNpeMhNpeId npeId, - IxNpeMhMessage message, - IxNpeMhMessageId solicitedMessageId, - IxNpeMhCallback solicitedCallback, - UINT32 maxSendRetries) -{ - IX_STATUS status = IX_SUCCESS; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhSendMessageWithResponseSend\n"); - - /* update statistical info */ - ixNpeMhSendStats[npeId].sendWithResponses++; - - /* sr: this sleep will call the receive routine (no interrupts used!!!) */ - ixOsalSleep (IX_NPEMH_INFIFO_RETRY_DELAY_US); - - /* check if the NPE's inFIFO is full - if so return an error */ - if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries)) - { - IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n"); - return IX_FAIL; - } - - /* save the solicited callback */ - status = ixNpeMhSolicitedCbMgrCallbackSave ( - npeId, solicitedMessageId, solicitedCallback); - if (status != IX_SUCCESS) - { - IX_NPEMH_ERROR_REPORT ("Failed to save solicited callback\n"); - - /* update statistical info */ - ixNpeMhSendStats[npeId].callbackFulls++; - - return status; - } - - /* write the message to the NPE's inFIFO */ - status = ixNpeMhConfigInFifoWrite (npeId, message); - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhSendMessageWithResponseSend\n"); - - return status; -} - -/* - * Function definition: ixNpeMhSendShow - */ - -void ixNpeMhSendShow ( - IxNpeMhNpeId npeId) -{ - /* show the message send invocation counter */ - IX_NPEMH_SHOW ("Send invocations", - ixNpeMhSendStats[npeId].sends); - - /* show the message send with response invocation counter */ - IX_NPEMH_SHOW ("Send with response invocations", - ixNpeMhSendStats[npeId].sendWithResponses); - - /* show the fifo queue full occurrence counter */ - IX_NPEMH_SHOW ("Fifo queue full occurrences", - ixNpeMhSendStats[npeId].queueFulls); - - /* show the fifo queue full retry occurrence counter */ - IX_NPEMH_SHOW ("Fifo queue full retry occurrences", - ixNpeMhSendStats[npeId].queueFullRetries); - - /* show the fifo queue full maximum retries counter */ - IX_NPEMH_SHOW ("Maximum fifo queue full retries", - ixNpeMhSendStats[npeId].maxQueueFullRetries); - - /* show the callback list full occurrence counter */ - IX_NPEMH_SHOW ("Solicited callback list full occurrences", - ixNpeMhSendStats[npeId].callbackFulls); -} - -/* - * Function definition: ixNpeMhSendShowReset - */ - -void ixNpeMhSendShowReset ( - IxNpeMhNpeId npeId) -{ - /* reset the message send invocation counter */ - ixNpeMhSendStats[npeId].sends = 0; - - /* reset the message send with response invocation counter */ - ixNpeMhSendStats[npeId].sendWithResponses = 0; - - /* reset the fifo queue full occurrence counter */ - ixNpeMhSendStats[npeId].queueFulls = 0; - - /* reset the fifo queue full retry occurrence counter */ - ixNpeMhSendStats[npeId].queueFullRetries = 0; - - /* reset the max fifo queue full retries counter */ - ixNpeMhSendStats[npeId].maxQueueFullRetries = 0; - - /* reset the callback list full occurrence counter */ - ixNpeMhSendStats[npeId].callbackFulls = 0; -} diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c b/arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c deleted file mode 100644 index 8e083a6..0000000 --- a/arch/arm/cpu/ixp/npe/IxNpeMhSolicitedCbMgr.c +++ /dev/null @@ -1,358 +0,0 @@ -/** - * @file IxNpeMhSolicitedCbMgr.c - * - * @author Intel Corporation - * @date 18 Jan 2002 - * - * @brief This file contains the implementation of the private API for the - * Solicited Callback Manager module. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ -#ifndef IXNPEMHCONFIG_P_H -# define IXNPEMHSOLICITEDCBMGR_C -#else -# error "Error, IxNpeMhConfig_p.h should not be included before this definition." -#endif - -/* - * Put the system defined include files required. - */ - - -/* - * Put the user defined include files required. - */ - -#include "IxOsal.h" - -#include "IxNpeMhMacros_p.h" -#include "IxNpeMhSolicitedCbMgr_p.h" -#include "IxNpeMhConfig_p.h" -/* - * #defines and macros used in this file. - */ - -/* - * Typedefs whose scope is limited to this file. - */ - -/** - * @struct IxNpeMhSolicitedCallbackListEntry - * - * @brief This structure is used to store the information associated with - * an entry in the callback list. This consists of the ID of the send - * message (which indicates the ID of the corresponding response message) - * and the callback function pointer itself. - * - */ - -typedef struct IxNpeMhSolicitedCallbackListEntry -{ - /** message ID */ - IxNpeMhMessageId messageId; - - /** callback function pointer */ - IxNpeMhCallback callback; - - /** pointer to next entry in the list */ - struct IxNpeMhSolicitedCallbackListEntry *next; -} IxNpeMhSolicitedCallbackListEntry; - -/** - * @struct IxNpeMhSolicitedCallbackList - * - * @brief This structure is used to maintain the list of response - * callbacks. The number of entries in this list will be variable, and - * they will be stored in a linked list fashion for ease of addition and - * removal. The entries themselves are statically allocated, and are - * organised into a "free" list and a "callback" list. Adding an entry - * means taking an entry from the "free" list and adding it to the - * "callback" list. Removing an entry means removing it from the - * "callback" list and returning it to the "free" list. - */ - -typedef struct -{ - /** pointer to the head of the free list */ - IxNpeMhSolicitedCallbackListEntry *freeHead; - - /** pointer to the head of the callback list */ - IxNpeMhSolicitedCallbackListEntry *callbackHead; - - /** pointer to the tail of the callback list */ - IxNpeMhSolicitedCallbackListEntry *callbackTail; - - /** array of entries - the first entry is used as a dummy entry to */ - /* avoid the scenario of having an empty list, hence '+ 1' */ - IxNpeMhSolicitedCallbackListEntry entries[IX_NPEMH_MAX_CALLBACKS + 1]; -} IxNpeMhSolicitedCallbackList; - -/** - * @struct IxNpeMhSolicitedCbMgrStats - * - * @brief This structure is used to maintain statistics for the Solicited - * Callback Manager module. - */ - -typedef struct -{ - UINT32 saves; /**< callback list saves */ - UINT32 retrieves; /**< callback list retrieves */ -} IxNpeMhSolicitedCbMgrStats; - -/* - * Variable declarations global to this file only. Externs are followed by - * static variables. - */ - -PRIVATE IxNpeMhSolicitedCallbackList -ixNpeMhSolicitedCbMgrCallbackLists[IX_NPEMH_NUM_NPES]; - -PRIVATE IxNpeMhSolicitedCbMgrStats -ixNpeMhSolicitedCbMgrStats[IX_NPEMH_NUM_NPES]; - -/* - * Extern function prototypes. - */ - -/* - * Static function prototypes. - */ - -/* - * Function definition: ixNpeMhSolicitedCbMgrInitialize - */ - -void ixNpeMhSolicitedCbMgrInitialize (void) -{ - IxNpeMhNpeId npeId; - UINT32 localIndex; - IxNpeMhSolicitedCallbackList *list = NULL; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhSolicitedCbMgrInitialize\n"); - - /* for each NPE ... */ - for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) - { - /* initialise a pointer to the list for convenience */ - list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId]; - - /* for each entry in the list, after the dummy entry ... */ - for (localIndex = 1; localIndex <= IX_NPEMH_MAX_CALLBACKS; localIndex++) - { - /* initialise the entry */ - list->entries[localIndex].messageId = 0x00; - list->entries[localIndex].callback = NULL; - - /* if this entry is before the last entry */ - if (localIndex < IX_NPEMH_MAX_CALLBACKS) - { - /* chain this entry to the following entry */ - list->entries[localIndex].next = &(list->entries[localIndex + 1]); - } - else /* this entry is the last entry */ - { - /* the last entry isn't chained to anything */ - list->entries[localIndex].next = NULL; - } - } - - /* set the free list pointer to point to the first real entry */ - /* (all real entries begin chained together on the free list) */ - list->freeHead = &(list->entries[1]); - - /* set the callback list pointers to point to the dummy entry */ - /* (the callback list is initially empty) */ - list->callbackHead = &(list->entries[0]); - list->callbackTail = &(list->entries[0]); - } - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhSolicitedCbMgrInitialize\n"); -} - -/* - * Function definition: ixNpeMhSolicitedCbMgrCallbackSave - */ - -IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave ( - IxNpeMhNpeId npeId, - IxNpeMhMessageId solicitedMessageId, - IxNpeMhCallback solicitedCallback) -{ - IxNpeMhSolicitedCallbackList *list = NULL; - IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhSolicitedCbMgrCallbackSave\n"); - - /* initialise a pointer to the list for convenience */ - list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId]; - - /* check to see if there are any entries in the free list */ - if (list->freeHead == NULL) - { - IX_NPEMH_ERROR_REPORT ("Solicited callback list is full\n"); - return IX_FAIL; - } - - /* there is an entry in the free list we can use */ - - /* update statistical info */ - ixNpeMhSolicitedCbMgrStats[npeId].saves++; - - /* remove a callback entry from the start of the free list */ - callbackEntry = list->freeHead; - list->freeHead = callbackEntry->next; - - /* fill in the callback entry with the new data */ - callbackEntry->messageId = solicitedMessageId; - callbackEntry->callback = solicitedCallback; - - /* the new callback entry will be added to the tail of the callback */ - /* list, so it isn't chained to anything */ - callbackEntry->next = NULL; - - /* chain new callback entry to the last entry of the callback list */ - list->callbackTail->next = callbackEntry; - list->callbackTail = callbackEntry; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhSolicitedCbMgrCallbackSave\n"); - - return IX_SUCCESS; -} - -/* - * Function definition: ixNpeMhSolicitedCbMgrCallbackRetrieve - */ - -void ixNpeMhSolicitedCbMgrCallbackRetrieve ( - IxNpeMhNpeId npeId, - IxNpeMhMessageId solicitedMessageId, - IxNpeMhCallback *solicitedCallback) -{ - IxNpeMhSolicitedCallbackList *list = NULL; - IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL; - IxNpeMhSolicitedCallbackListEntry *previousEntry = NULL; - - /* initialise a pointer to the list for convenience */ - list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId]; - - /* initialise the callback entry to the first entry of the callback */ - /* list - we must skip over the dummy entry, which is the previous */ - callbackEntry = list->callbackHead->next; - previousEntry = list->callbackHead; - - /* traverse the callback list looking for an entry with a matching */ - /* message ID. note we also save the previous entry's pointer to */ - /* allow us to unchain the matching entry from the callback list */ - while ((callbackEntry != NULL) && - (callbackEntry->messageId != solicitedMessageId)) - { - previousEntry = callbackEntry; - callbackEntry = callbackEntry->next; - } - - /* if we didn't find a matching callback entry */ - if (callbackEntry == NULL) - { - /* return a NULL callback in the outgoing parameter */ - *solicitedCallback = NULL; - } - else /* we found a matching callback entry */ - { - /* update statistical info */ - ixNpeMhSolicitedCbMgrStats[npeId].retrieves++; - - /* return the callback in the outgoing parameter */ - *solicitedCallback = callbackEntry->callback; - - /* unchain callback entry by chaining previous entry to next */ - previousEntry->next = callbackEntry->next; - - /* if the callback entry is at the tail of the list */ - if (list->callbackTail == callbackEntry) - { - /* update the tail of the callback list */ - list->callbackTail = previousEntry; - } - - /* re-initialise the callback entry */ - callbackEntry->messageId = 0x00; - callbackEntry->callback = NULL; - - /* add the callback entry to the start of the free list */ - callbackEntry->next = list->freeHead; - list->freeHead = callbackEntry; - } -} - -/* - * Function definition: ixNpeMhSolicitedCbMgrShow - */ - -void ixNpeMhSolicitedCbMgrShow ( - IxNpeMhNpeId npeId) -{ - /* show the solicited callback list save counter */ - IX_NPEMH_SHOW ("Solicited callback list saves", - ixNpeMhSolicitedCbMgrStats[npeId].saves); - - /* show the solicited callback list retrieve counter */ - IX_NPEMH_SHOW ("Solicited callback list retrieves", - ixNpeMhSolicitedCbMgrStats[npeId].retrieves); -} - -/* - * Function definition: ixNpeMhSolicitedCbMgrShowReset - */ - -void ixNpeMhSolicitedCbMgrShowReset ( - IxNpeMhNpeId npeId) -{ - /* reset the solicited callback list save counter */ - ixNpeMhSolicitedCbMgrStats[npeId].saves = 0; - - /* reset the solicited callback list retrieve counter */ - ixNpeMhSolicitedCbMgrStats[npeId].retrieves = 0; -} diff --git a/arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c b/arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c deleted file mode 100644 index d37f9f9..0000000 --- a/arch/arm/cpu/ixp/npe/IxNpeMhUnsolicitedCbMgr.c +++ /dev/null @@ -1,246 +0,0 @@ -/** - * @file IxNpeMhUnsolicitedCbMgr.c - * - * @author Intel Corporation - * @date 18 Jan 2002 - * - * @brief This file contains the implementation of the private API for - * the Unsolicited Callback Manager module. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * Put the system defined include files required. - */ - - -/* - * Put the user defined include files required. - */ -#include "IxOsal.h" - -#include "IxNpeMhMacros_p.h" - -#include "IxNpeMhUnsolicitedCbMgr_p.h" - - -/* - * #defines and macros used in this file. - */ - -/* - * Typedefs whose scope is limited to this file. - */ - -/** - * @struct IxNpeMhUnsolicitedCallbackTable - * - * @brief This structure is used to maintain the list of registered - * callbacks. One entry exists for each message ID, and a NULL entry will - * signify that no callback has been registered for that ID. - */ - -typedef struct -{ - /** array of entries */ - IxNpeMhCallback entries[IX_NPEMH_MAX_MESSAGE_ID + 1]; -} IxNpeMhUnsolicitedCallbackTable; - -/** - * @struct IxNpeMhUnsolicitedCbMgrStats - * - * @brief This structure is used to maintain statistics for the Unsolicited - * Callback Manager module. - */ - -typedef struct -{ - UINT32 saves; /**< callback table saves */ - UINT32 overwrites; /**< callback table overwrites */ -} IxNpeMhUnsolicitedCbMgrStats; - -/* - * Variable declarations global to this file only. Externs are followed by - * static variables. - */ - -PRIVATE IxNpeMhUnsolicitedCallbackTable -ixNpeMhUnsolicitedCallbackTables[IX_NPEMH_NUM_NPES]; - -PRIVATE IxNpeMhUnsolicitedCbMgrStats -ixNpeMhUnsolicitedCbMgrStats[IX_NPEMH_NUM_NPES]; - -/* - * Extern function prototypes. - */ - -/* - * Static function prototypes. - */ - -/* - * Function definition: ixNpeMhUnsolicitedCbMgrInitialize - */ - -void ixNpeMhUnsolicitedCbMgrInitialize (void) -{ - IxNpeMhNpeId npeId = 0; - IxNpeMhUnsolicitedCallbackTable *table = NULL; - IxNpeMhMessageId messageId = 0; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhUnsolicitedCbMgrInitialize\n"); - - /* for each NPE ... */ - for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) - { - /* initialise a pointer to the table for convenience */ - table = &ixNpeMhUnsolicitedCallbackTables[npeId]; - - /* for each message ID ... */ - for (messageId = IX_NPEMH_MIN_MESSAGE_ID; - messageId <= IX_NPEMH_MAX_MESSAGE_ID; messageId++) - { - /* initialise the callback for this message ID to NULL */ - table->entries[messageId] = NULL; - } - } - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhUnsolicitedCbMgrInitialize\n"); -} - -/* - * Function definition: ixNpeMhUnsolicitedCbMgrCallbackSave - */ - -void ixNpeMhUnsolicitedCbMgrCallbackSave ( - IxNpeMhNpeId npeId, - IxNpeMhMessageId unsolicitedMessageId, - IxNpeMhCallback unsolicitedCallback) -{ - IxNpeMhUnsolicitedCallbackTable *table = NULL; - - /* initialise a pointer to the table for convenience */ - table = &ixNpeMhUnsolicitedCallbackTables[npeId]; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " - "ixNpeMhUnsolicitedCbMgrCallbackSave\n"); - - /* update statistical info */ - ixNpeMhUnsolicitedCbMgrStats[npeId].saves++; - - /* check if there is a callback already registered for this NPE and */ - /* message ID */ - if (table->entries[unsolicitedMessageId] != NULL) - { - /* if we are overwriting an existing callback */ - if (unsolicitedCallback != NULL) - { - IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "Unsolicited callback " - "overwriting existing callback for NPE ID %d " - "message ID 0x%02X\n", npeId, unsolicitedMessageId); - } - else /* if we are clearing an existing callback */ - { - IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NULL unsolicited callback " - "clearing existing callback for NPE ID %d " - "message ID 0x%02X\n", npeId, unsolicitedMessageId); - } - - /* update statistical info */ - ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites++; - } - - /* save the callback into the table */ - table->entries[unsolicitedMessageId] = unsolicitedCallback; - - IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " - "ixNpeMhUnsolicitedCbMgrCallbackSave\n"); -} - -/* - * Function definition: ixNpeMhUnsolicitedCbMgrCallbackRetrieve - */ - -void ixNpeMhUnsolicitedCbMgrCallbackRetrieve ( - IxNpeMhNpeId npeId, - IxNpeMhMessageId unsolicitedMessageId, - IxNpeMhCallback *unsolicitedCallback) -{ - IxNpeMhUnsolicitedCallbackTable *table = NULL; - - /* initialise a pointer to the table for convenience */ - table = &ixNpeMhUnsolicitedCallbackTables[npeId]; - - /* retrieve the callback from the table */ - *unsolicitedCallback = table->entries[unsolicitedMessageId]; -} - -/* - * Function definition: ixNpeMhUnsolicitedCbMgrShow - */ - -void ixNpeMhUnsolicitedCbMgrShow ( - IxNpeMhNpeId npeId) -{ - /* show the unsolicited callback table save counter */ - IX_NPEMH_SHOW ("Unsolicited callback table saves", - ixNpeMhUnsolicitedCbMgrStats[npeId].saves); - - /* show the unsolicited callback table overwrite counter */ - IX_NPEMH_SHOW ("Unsolicited callback table overwrites", - ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites); -} - -/* - * Function definition: ixNpeMhUnsolicitedCbMgrShowReset - */ - -void ixNpeMhUnsolicitedCbMgrShowReset ( - IxNpeMhNpeId npeId) -{ - /* reset the unsolicited callback table save counter */ - ixNpeMhUnsolicitedCbMgrStats[npeId].saves = 0; - - /* reset the unsolicited callback table overwrite counter */ - ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites = 0; -} diff --git a/arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c b/arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c deleted file mode 100644 index fa8db47..0000000 --- a/arch/arm/cpu/ixp/npe/IxOsalBufferMgt.c +++ /dev/null @@ -1,800 +0,0 @@ -/** - * @file IxOsalBufferMgt.c - * - * @brief Default buffer pool management and buffer management - * Implementation. - * - * Design Notes: - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/* - * OS may choose to use default bufferMgt by defining - * IX_OSAL_USE_DEFAULT_BUFFER_MGT in IxOsalOsBufferMgt.h - */ - -#include "IxOsal.h" - -#define IX_OSAL_BUFFER_FREE_PROTECTION /* Define this to enable Illegal MBuf Freed Protection*/ - -/* - * The implementation is only used when the following - * is defined. - */ -#ifdef IX_OSAL_USE_DEFAULT_BUFFER_MGT - - -#define IX_OSAL_MBUF_SYS_SIGNATURE (0x8BADF00D) -#define IX_OSAL_MBUF_SYS_SIGNATURE_MASK (0xEFFFFFFF) -#define IX_OSAL_MBUF_USED_FLAG (0x10000000) -#define IX_OSAL_MBUF_SYS_SIGNATURE_INIT(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) = (UINT32)IX_OSAL_MBUF_SYS_SIGNATURE - -/* -* This implementation is protect, the buffer pool management's ixOsalMBufFree -* against an invalid MBUF pointer argument that already has been freed earlier -* or in other words resides in the free pool of MBUFs. This added feature, -* checks the MBUF "USED" FLAG. The Flag tells if the MBUF is still not freed -* back to the Buffer Pool. -* Disable this feature for performance reasons by undef -* IX_OSAL_BUFFER_FREE_PROTECTION macro. -*/ -#ifdef IX_OSAL_BUFFER_FREE_PROTECTION /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/ - -#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&(IX_OSAL_MBUF_SYS_SIGNATURE_MASK) ) -#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr) do { \ - IX_OSAL_MBUF_SIGNATURE (bufPtr)&(~IX_OSAL_MBUF_SYS_SIGNATURE_MASK);\ - IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_SYS_SIGNATURE; \ - }while(0) - -#define IX_OSAL_MBUF_SET_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_USED_FLAG -#define IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)&=~IX_OSAL_MBUF_USED_FLAG -#define IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&IX_OSAL_MBUF_USED_FLAG) - -#else - -#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) -#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) = IX_OSAL_MBUF_SYS_SIGNATURE - -#endif /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/ -/* - * Variable declarations global to this file only. Externs are followed by - * static variables. - */ - -/* - * A unit of 32, used to provide bit-shift for pool - * management. Needs some work if users want more than 32 pools. - */ -#define IX_OSAL_BUFF_FREE_BITS 32 - -PRIVATE UINT32 ixOsalBuffFreePools[IX_OSAL_MBUF_MAX_POOLS / - IX_OSAL_BUFF_FREE_BITS]; - -PUBLIC IX_OSAL_MBUF_POOL ixOsalBuffPools[IX_OSAL_MBUF_MAX_POOLS]; - -static int ixOsalBuffPoolsInUse = 0; - -#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY -PRIVATE IX_OSAL_MBUF * -ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned, - UINT32 dataSizeAligned, - IX_OSAL_MBUF_POOL *poolPtr); -#endif - -PRIVATE IX_OSAL_MBUF_POOL * ixOsalPoolAlloc (void); - -/* - * Function definition: ixOsalPoolAlloc - */ - -/****************************/ - -PRIVATE IX_OSAL_MBUF_POOL * -ixOsalPoolAlloc (void) -{ - register unsigned int i = 0; - - /* - * Scan for the first free buffer. Free buffers are indicated by 0 - * on the corrsponding bit in ixOsalBuffFreePools. - */ - if (ixOsalBuffPoolsInUse >= IX_OSAL_MBUF_MAX_POOLS) - { - /* - * Fail to grab a ptr this time - */ - return NULL; - } - - while (ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] & - (1 << (i % IX_OSAL_BUFF_FREE_BITS))) - i++; - /* - * Free buffer found. Mark it as busy and initialize. - */ - ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] |= - (1 << (i % IX_OSAL_BUFF_FREE_BITS)); - - memset (&ixOsalBuffPools[i], 0, sizeof (IX_OSAL_MBUF_POOL)); - - ixOsalBuffPools[i].poolIdx = i; - ixOsalBuffPoolsInUse++; - - return &ixOsalBuffPools[i]; -} - - -#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY -PRIVATE IX_OSAL_MBUF * -ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned, - UINT32 dataSizeAligned, - IX_OSAL_MBUF_POOL *poolPtr) -{ - UINT8 *dataPtr; - IX_OSAL_MBUF *realMbufPtr; - /* Allocate cache-aligned memory for mbuf header */ - realMbufPtr = (IX_OSAL_MBUF *) IX_OSAL_CACHE_DMA_MALLOC (mbufSizeAligned); - IX_OSAL_ASSERT (realMbufPtr != NULL); - memset (realMbufPtr, 0, mbufSizeAligned); - - /* Allocate cache-aligned memory for mbuf data */ - dataPtr = (UINT8 *) IX_OSAL_CACHE_DMA_MALLOC (dataSizeAligned); - IX_OSAL_ASSERT (dataPtr != NULL); - memset (dataPtr, 0, dataSizeAligned); - - /* Fill in mbuf header fields */ - IX_OSAL_MBUF_MDATA (realMbufPtr) = dataPtr; - IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (realMbufPtr) = (UINT32)dataPtr; - - IX_OSAL_MBUF_MLEN (realMbufPtr) = dataSizeAligned; - IX_OSAL_MBUF_ALLOCATED_BUFF_LEN (realMbufPtr) = dataSizeAligned; - - IX_OSAL_MBUF_NET_POOL (realMbufPtr) = (IX_OSAL_MBUF_POOL *) poolPtr; - - IX_OSAL_MBUF_SYS_SIGNATURE_INIT(realMbufPtr); - - /* update some statistical information */ - poolPtr->mbufMemSize += mbufSizeAligned; - poolPtr->dataMemSize += dataSizeAligned; - - return realMbufPtr; -} -#endif /* #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY */ - -/* - * Function definition: ixOsalBuffPoolInit - */ - -PUBLIC IX_OSAL_MBUF_POOL * -ixOsalPoolInit (UINT32 count, UINT32 size, const char *name) -{ - - /* These variables are only used if UX_OSAL_BUFFER_ALLOC_SEPERATELY - * is defined . - */ -#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY - UINT32 i, mbufSizeAligned, dataSizeAligned; - IX_OSAL_MBUF *currentMbufPtr = NULL; -#else - void *poolBufPtr; - void *poolDataPtr; - int mbufMemSize; - int dataMemSize; -#endif - - IX_OSAL_MBUF_POOL *poolPtr = NULL; - - if (count <= 0) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalPoolInit(): " "count = 0 \n", 0, 0, 0, 0, 0, 0); - return NULL; - } - - if (name == NULL) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalPoolInit(): " "NULL name \n", 0, 0, 0, 0, 0, 0); - return NULL; - } - - if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalPoolInit(): " - "ERROR - name length should be no greater than %d \n", - IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0); - return NULL; - } - -/* OS can choose whether to allocate all buffers all together (if it - * can handle a huge single alloc request), or to allocate buffers - * separately by the defining IX_OSAL_BUFFER_ALLOC_SEPARATELY. - */ -#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY - /* Get a pool Ptr */ - poolPtr = ixOsalPoolAlloc (); - - if (poolPtr == NULL) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalPoolInit(): " "Fail to Get PoolPtr \n", 0, 0, 0, 0, 0, 0); - return NULL; - } - - mbufSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF)); - dataSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN(size); - - poolPtr->nextFreeBuf = NULL; - poolPtr->mbufMemPtr = NULL; - poolPtr->dataMemPtr = NULL; - poolPtr->bufDataSize = dataSizeAligned; - poolPtr->totalBufsInPool = count; - poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC; - strcpy (poolPtr->name, name); - - - for (i = 0; i < count; i++) - { - /* create an mbuf */ - currentMbufPtr = ixOsalBuffPoolMbufInit (mbufSizeAligned, - dataSizeAligned, - poolPtr); - -#ifdef IX_OSAL_BUFFER_FREE_PROTECTION -/* Set the Buffer USED Flag. If not, ixOsalMBufFree will fail. - ixOsalMbufFree used here is in a special case whereby, it's - used to add MBUF to the Pool. By specification, ixOsalMbufFree - deallocates an allocated MBUF from Pool. -*/ - IX_OSAL_MBUF_SET_USED_FLAG(currentMbufPtr); -#endif - /* Add it to the pool */ - ixOsalMbufFree (currentMbufPtr); - - /* flush the pool information to RAM */ - IX_OSAL_CACHE_FLUSH (currentMbufPtr, mbufSizeAligned); - } - - /* - * update the number of free buffers in the pool - */ - poolPtr->freeBufsInPool = count; - -#else -/* Otherwise allocate buffers in a continuous block fashion */ - poolBufPtr = IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC (count, mbufMemSize); - IX_OSAL_ASSERT (poolBufPtr != NULL); - poolDataPtr = - IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC (count, size, dataMemSize); - IX_OSAL_ASSERT (poolDataPtr != NULL); - - poolPtr = ixOsalNoAllocPoolInit (poolBufPtr, poolDataPtr, - count, size, name); - if (poolPtr == NULL) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalPoolInit(): " "Fail to get pool ptr \n", 0, 0, 0, 0, 0, 0); - return NULL; - } - - poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC; - -#endif /* IX_OSAL_BUFFER_ALLOC_SEPARATELY */ - return poolPtr; -} - -PUBLIC IX_OSAL_MBUF_POOL * -ixOsalNoAllocPoolInit (void *poolBufPtr, - void *poolDataPtr, UINT32 count, UINT32 size, const char *name) -{ - UINT32 i, mbufSizeAligned, sizeAligned; - IX_OSAL_MBUF *currentMbufPtr = NULL; - IX_OSAL_MBUF *nextMbufPtr = NULL; - IX_OSAL_MBUF_POOL *poolPtr = NULL; - - /* - * check parameters - */ - if (poolBufPtr == NULL) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalNoAllocPoolInit(): " - "ERROR - NULL poolBufPtr \n", 0, 0, 0, 0, 0, 0); - return NULL; - } - - if (count <= 0) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalNoAllocPoolInit(): " - "ERROR - count must > 0 \n", 0, 0, 0, 0, 0, 0); - return NULL; - } - - if (name == NULL) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalNoAllocPoolInit(): " - "ERROR - NULL name ptr \n", 0, 0, 0, 0, 0, 0); - return NULL; - } - - if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalNoAllocPoolInit(): " - "ERROR - name length should be no greater than %d \n", - IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0); - return NULL; - } - - poolPtr = ixOsalPoolAlloc (); - - if (poolPtr == NULL) - { - return NULL; - } - - /* - * Adjust sizes to ensure alignment on cache line boundaries - */ - mbufSizeAligned = - IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF)); - /* - * clear the mbuf memory area - */ - memset (poolBufPtr, 0, mbufSizeAligned * count); - - if (poolDataPtr != NULL) - { - /* - * Adjust sizes to ensure alignment on cache line boundaries - */ - sizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (size); - /* - * clear the data memory area - */ - memset (poolDataPtr, 0, sizeAligned * count); - } - else - { - sizeAligned = 0; - } - - /* - * initialise pool fields - */ - strcpy ((poolPtr)->name, name); - - poolPtr->dataMemPtr = poolDataPtr; - poolPtr->mbufMemPtr = poolBufPtr; - poolPtr->bufDataSize = sizeAligned; - poolPtr->totalBufsInPool = count; - poolPtr->mbufMemSize = mbufSizeAligned * count; - poolPtr->dataMemSize = sizeAligned * count; - - currentMbufPtr = (IX_OSAL_MBUF *) poolBufPtr; - - poolPtr->nextFreeBuf = currentMbufPtr; - - for (i = 0; i < count; i++) - { - if (i < (count - 1)) - { - nextMbufPtr = - (IX_OSAL_MBUF *) ((unsigned) currentMbufPtr + - mbufSizeAligned); - } - else - { /* last mbuf in chain */ - nextMbufPtr = NULL; - } - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (currentMbufPtr) = nextMbufPtr; - IX_OSAL_MBUF_NET_POOL (currentMbufPtr) = poolPtr; - - IX_OSAL_MBUF_SYS_SIGNATURE_INIT(currentMbufPtr); - - if (poolDataPtr != NULL) - { - IX_OSAL_MBUF_MDATA (currentMbufPtr) = poolDataPtr; - IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(currentMbufPtr) = (UINT32) poolDataPtr; - - IX_OSAL_MBUF_MLEN (currentMbufPtr) = sizeAligned; - IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(currentMbufPtr) = sizeAligned; - - poolDataPtr = (void *) ((unsigned) poolDataPtr + sizeAligned); - } - - currentMbufPtr = nextMbufPtr; - } - - /* - * update the number of free buffers in the pool - */ - poolPtr->freeBufsInPool = count; - - poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC; - - return poolPtr; -} - -/* - * Get a mbuf ptr from the pool - */ -PUBLIC IX_OSAL_MBUF * -ixOsalMbufAlloc (IX_OSAL_MBUF_POOL * poolPtr) -{ - int lock; - IX_OSAL_MBUF *newBufPtr = NULL; - - /* - * check parameters - */ - if (poolPtr == NULL) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalMbufAlloc(): " - "ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0); - return NULL; - } - - lock = ixOsalIrqLock (); - - newBufPtr = poolPtr->nextFreeBuf; - if (newBufPtr) - { - poolPtr->nextFreeBuf = - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr); - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr) = NULL; - - /* - * update the number of free buffers in the pool - */ - poolPtr->freeBufsInPool--; - } - else - { - /* Return NULL to indicate to caller that request is denied. */ - ixOsalIrqUnlock (lock); - - return NULL; - } - -#ifdef IX_OSAL_BUFFER_FREE_PROTECTION - /* Set Buffer Used Flag to indicate state.*/ - IX_OSAL_MBUF_SET_USED_FLAG(newBufPtr); -#endif - - ixOsalIrqUnlock (lock); - - return newBufPtr; -} - -PUBLIC IX_OSAL_MBUF * -ixOsalMbufFree (IX_OSAL_MBUF * bufPtr) -{ - int lock; - IX_OSAL_MBUF_POOL *poolPtr; - - IX_OSAL_MBUF *nextBufPtr = NULL; - - /* - * check parameters - */ - if (bufPtr == NULL) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalMbufFree(): " - "ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0); - return NULL; - } - - - - lock = ixOsalIrqLock (); - -#ifdef IX_OSAL_BUFFER_FREE_PROTECTION - - /* Prevention for Buffer freed more than once*/ - if(!IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr)) - { - return NULL; - } - IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr); -#endif - - poolPtr = IX_OSAL_MBUF_NET_POOL (bufPtr); - - /* - * check the mbuf wrapper signature (if mbuf wrapper was used) - */ - if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC) - { - IX_OSAL_ENSURE ( (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) == IX_OSAL_MBUF_SYS_SIGNATURE), - "ixOsalBuffPoolBufFree: ERROR - Invalid mbuf signature."); - } - - nextBufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr); - - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr) = poolPtr->nextFreeBuf; - poolPtr->nextFreeBuf = bufPtr; - - /* - * update the number of free buffers in the pool - */ - poolPtr->freeBufsInPool++; - - ixOsalIrqUnlock (lock); - - return nextBufPtr; -} - -PUBLIC void -ixOsalMbufChainFree (IX_OSAL_MBUF * bufPtr) -{ - while ((bufPtr = ixOsalMbufFree (bufPtr))); -} - -/* - * Function definition: ixOsalBuffPoolShow - */ -PUBLIC void -ixOsalMbufPoolShow (IX_OSAL_MBUF_POOL * poolPtr) -{ - IX_OSAL_MBUF *nextBufPtr; - int count = 0; - int lock; - - /* - * check parameters - */ - if (poolPtr == NULL) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalBuffPoolShow(): " - "ERROR - Invalid Parameter", 0, 0, 0, 0, 0, 0); - /* - * return IX_FAIL; - */ - return; - } - - lock = ixOsalIrqLock (); - count = poolPtr->freeBufsInPool; - nextBufPtr = poolPtr->nextFreeBuf; - ixOsalIrqUnlock (lock); - - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, - IX_OSAL_LOG_DEV_STDOUT, "=== POOL INFORMATION ===\n", 0, 0, 0, - 0, 0, 0); - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, - "Pool Name: %s\n", - (unsigned int) poolPtr->name, 0, 0, 0, 0, 0); - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, - "Pool Allocation Type: %d\n", - (unsigned int) poolPtr->poolAllocType, 0, 0, 0, 0, 0); - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, - "Pool Mbuf Mem Usage (bytes): %d\n", - (unsigned int) poolPtr->mbufMemSize, 0, 0, 0, 0, 0); - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, - "Pool Data Mem Usage (bytes): %d\n", - (unsigned int) poolPtr->dataMemSize, 0, 0, 0, 0, 0); - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, - "Mbuf Data Capacity (bytes): %d\n", - (unsigned int) poolPtr->bufDataSize, 0, 0, 0, 0, 0); - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, - "Total Mbufs in Pool: %d\n", - (unsigned int) poolPtr->totalBufsInPool, 0, 0, 0, 0, 0); - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, - "Available Mbufs: %d\n", (unsigned int) count, 0, - 0, 0, 0, 0); - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, - "Next Available Mbuf: %p\n", (unsigned int) nextBufPtr, - 0, 0, 0, 0, 0); - - if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC) - { - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, - IX_OSAL_LOG_DEV_STDOUT, - "Mbuf Mem Area Start address: %p\n", - (unsigned int) poolPtr->mbufMemPtr, 0, 0, 0, 0, 0); - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, - "Data Mem Area Start address: %p\n", - (unsigned int) poolPtr->dataMemPtr, 0, 0, 0, 0, 0); - } -} - -PUBLIC void -ixOsalMbufDataPtrReset (IX_OSAL_MBUF * bufPtr) -{ - IX_OSAL_MBUF_POOL *poolPtr; - UINT8 *poolDataPtr; - - if (bufPtr == NULL) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, - "ixOsalBuffPoolBufDataPtrReset" - ": ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0); - return; - } - - poolPtr = (IX_OSAL_MBUF_POOL *) IX_OSAL_MBUF_NET_POOL (bufPtr); - poolDataPtr = poolPtr->dataMemPtr; - - if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC) - { - if (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) != IX_OSAL_MBUF_SYS_SIGNATURE) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, - "ixOsalBuffPoolBufDataPtrReset" - ": invalid mbuf, cannot reset mData pointer\n", 0, 0, - 0, 0, 0, 0); - return; - } - IX_OSAL_MBUF_MDATA (bufPtr) = (UINT8*)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (bufPtr); - } - else - { - if (poolDataPtr) - { - unsigned int bufSize = poolPtr->bufDataSize; - unsigned int bufDataAddr = - (unsigned int) IX_OSAL_MBUF_MDATA (bufPtr); - unsigned int poolDataAddr = (unsigned int) poolDataPtr; - - /* - * the pointer is still pointing somewhere in the mbuf payload. - * This operation moves the pointer to the beginning of the - * mbuf payload - */ - bufDataAddr = ((bufDataAddr - poolDataAddr) / bufSize) * bufSize; - IX_OSAL_MBUF_MDATA (bufPtr) = &poolDataPtr[bufDataAddr]; - } - else - { - ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, - "ixOsalBuffPoolBufDataPtrReset" - ": cannot be used if user supplied NULL pointer for pool data area " - "when pool was created\n", 0, 0, 0, 0, 0, 0); - return; - } - } - -} - -/* - * Function definition: ixOsalBuffPoolUninit - */ -PUBLIC IX_STATUS -ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool) -{ - if (!pool) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, - "ixOsalBuffPoolUninit: NULL ptr \n", 0, 0, 0, 0, 0, 0); - return IX_FAIL; - } - - if (pool->freeBufsInPool != pool->totalBufsInPool) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, - "ixOsalBuffPoolUninit: need to return all ptrs to the pool first! \n", - 0, 0, 0, 0, 0, 0); - return IX_FAIL; - } - - if (pool->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC) - { -#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY - UINT32 i; - IX_OSAL_MBUF* pBuf; - - pBuf = pool->nextFreeBuf; - /* Freed the Buffer one by one till all the Memory is freed*/ - for (i= pool->freeBufsInPool; i >0 && pBuf!=NULL ;i--){ - IX_OSAL_MBUF* pBufTemp; - pBufTemp = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(pBuf); - /* Freed MBUF Data Memory area*/ - IX_OSAL_CACHE_DMA_FREE( (void *) (IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(pBuf)) ); - /* Freed MBUF Struct Memory area*/ - IX_OSAL_CACHE_DMA_FREE(pBuf); - pBuf = pBufTemp; - } - -#else - IX_OSAL_CACHE_DMA_FREE (pool->mbufMemPtr); - IX_OSAL_CACHE_DMA_FREE (pool->dataMemPtr); -#endif - } - - ixOsalBuffFreePools[pool->poolIdx / IX_OSAL_BUFF_FREE_BITS] &= - ~(1 << (pool->poolIdx % IX_OSAL_BUFF_FREE_BITS)); - ixOsalBuffPoolsInUse--; - return IX_SUCCESS; -} - -/* - * Function definition: ixOsalBuffPoolDataAreaSizeGet - */ -PUBLIC UINT32 -ixOsalBuffPoolDataAreaSizeGet (int count, int size) -{ - UINT32 memorySize; - memorySize = count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (size); - return memorySize; -} - -/* - * Function definition: ixOsalBuffPoolMbufAreaSizeGet - */ -PUBLIC UINT32 -ixOsalBuffPoolMbufAreaSizeGet (int count) -{ - UINT32 memorySize; - memorySize = - count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF)); - return memorySize; -} - -/* - * Function definition: ixOsalBuffPoolFreeCountGet - */ -PUBLIC UINT32 ixOsalBuffPoolFreeCountGet(IX_OSAL_MBUF_POOL * poolPtr) - -{ - - return poolPtr->freeBufsInPool; - -} - -#endif /* IX_OSAL_USE_DEFAULT_BUFFER_MGT */ diff --git a/arch/arm/cpu/ixp/npe/IxOsalIoMem.c b/arch/arm/cpu/ixp/npe/IxOsalIoMem.c deleted file mode 100644 index 34df92b..0000000 --- a/arch/arm/cpu/ixp/npe/IxOsalIoMem.c +++ /dev/null @@ -1,332 +0,0 @@ -/** - * @file IxOsalIoMem.c - * - * @brief OS-independent IO/Mem implementation - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/* Access to the global mem map is only allowed in this file */ -#define IxOsalIoMem_C - -#include "IxOsal.h" - -#define SEARCH_PHYSICAL_ADDRESS (1) -#define SEARCH_VIRTUAL_ADDRESS (2) - -/* - * Searches for map using one of the following criteria: - * - * - enough room to include a zone starting with the physical "requestedAddress" of size "size" (for mapping) - * - includes the virtual "requestedAddress" in its virtual address space (already mapped, for unmapping) - * - correct coherency - * - * Returns a pointer to the map or NULL if a suitable map is not found. - */ -PRIVATE IxOsalMemoryMap * -ixOsalMemMapFind (UINT32 requestedAddress, - UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType) -{ - UINT32 mapIndex; - - UINT32 numMapElements = - sizeof (ixOsalGlobalMemoryMap) / sizeof (IxOsalMemoryMap); - - for (mapIndex = 0; mapIndex < numMapElements; mapIndex++) - { - IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex]; - - if (searchCriteria == SEARCH_PHYSICAL_ADDRESS - && requestedAddress >= map->physicalAddress - && (requestedAddress + size) <= (map->physicalAddress + map->size) - && (map->mapEndianType & requestedEndianType) != 0) - { - return map; - } - else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS - && requestedAddress >= map->virtualAddress - && requestedAddress <= (map->virtualAddress + map->size) - && (map->mapEndianType & requestedEndianType) != 0) - { - return map; - } - else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS) - { - ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, - IX_OSAL_LOG_DEV_STDOUT, - "Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n", - map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0); - } - } - - /* - * not found - */ - return NULL; -} - -/* - * This function maps an I/O mapped physical memory zone of the given size - * into a virtual memory zone accessible by the caller and returns a cookie - - * the start address of the virtual memory zone. - * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned - * virtual address. - * The memory zone is to be unmapped using ixOsalMemUnmap once the caller has - * finished using this zone (e.g. on driver unload) using the cookie as - * parameter. - * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write - * the mapped memory, adding the necessary offsets to the address cookie. - * - * Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP - * instead. - */ -PUBLIC void * -ixOsalIoMemMap (UINT32 requestedAddress, - UINT32 size, IxOsalMapEndianessType requestedEndianType) -{ - IxOsalMemoryMap *map; - - ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, - IX_OSAL_LOG_DEV_STDOUT, - "OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n", - requestedAddress, size, requestedEndianType, 0, 0, 0); - - if (requestedEndianType == IX_OSAL_LE) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n", - 0, 0, 0, 0, 0, 0); - return (NULL); - } - map = ixOsalMemMapFind (requestedAddress, - size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType); - if (map != NULL) - { - UINT32 offset = requestedAddress - map->physicalAddress; - - ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, - IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0); - ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, - IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0); - ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, - IX_OSAL_LOG_DEV_STDOUT, - ":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n", - map->physicalAddress, map->virtualAddress, - map->size, map->refCount, map->mapEndianType, 0); - - if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0) - { - if (map->mapFunction != NULL) - { - map->mapFunction (map); - - if (map->virtualAddress == 0) - { - /* - * failed - */ - ixOsalLog (IX_OSAL_LOG_LVL_FATAL, - IX_OSAL_LOG_DEV_STDERR, - "OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n", - requestedAddress, size, requestedEndianType, 0, 0, 0); - return NULL; - } - } - else - { - /* - * error, no map function for a dynamic map - */ - ixOsalLog (IX_OSAL_LOG_LVL_FATAL, - IX_OSAL_LOG_DEV_STDERR, - "OSAL: No map function for a dynamic map - " - "[addr 0x%x:size 0x%x:endianType %d]\n", - requestedAddress, size, requestedEndianType, 0, 0, 0); - - return NULL; - } - } - - /* - * increment reference count - */ - map->refCount++; - - return (void *) (map->virtualAddress + offset); - } - - /* - * requested address is not described in the global memory map - */ - ixOsalLog (IX_OSAL_LOG_LVL_FATAL, - IX_OSAL_LOG_DEV_STDERR, - "OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n", - requestedAddress, size, requestedEndianType, 0, 0, 0); - return NULL; -} - -/* - * This function unmaps a previously mapped I/O memory zone using - * the cookie obtained in the mapping operation. The memory zone in question - * becomes unavailable to the caller once unmapped and the cookie should be - * discarded. - * - * This function cannot fail if the given parameter is correct and does not - * return a value. - * - * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP - * instead. - */ -PUBLIC void -ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType) -{ - IxOsalMemoryMap *map; - - if (endianType == IX_OSAL_LE) - { - ixOsalLog (IX_OSAL_LOG_LVL_ERROR, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n", - 0, 0, 0, 0, 0, 0); - return; - } - - if (requestedAddress == 0) - { - /* - * invalid virtual address - */ - return; - } - - map = - ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS, - endianType); - - if (map != NULL) - { - if (map->refCount > 0) - { - /* - * decrement reference count - */ - map->refCount--; - - if (map->refCount == 0) - { - /* - * no longer used, deallocate - */ - if (map->type == IX_OSAL_DYNAMIC_MAP - && map->unmapFunction != NULL) - { - map->unmapFunction (map); - } - } - } - } - else - { - ixOsalLog (IX_OSAL_LOG_LVL_WARNING, - IX_OSAL_LOG_DEV_STDERR, - "OSAL: ixOsServMemUnmap didn't find the requested map " - "[virt addr 0x%x: endianType %d], ignoring call\n", - requestedAddress, endianType, 0, 0, 0, 0); - } -} - -/* - * This function Converts a virtual address into a physical - * address, including the dynamically mapped memory. - * - * Parameters virtAddr - virtual address to convert - * Return value: corresponding physical address, or NULL - * if there is no physical address addressable - * by the given virtual address - * OS: VxWorks, Linux, WinCE, QNX, eCos - * Reentrant: Yes - * IRQ safe: Yes - */ -PUBLIC UINT32 -ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency) -{ - IxOsalMemoryMap *map = - ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS, - requestedCoherency); - - if (map != NULL) - { - return map->physicalAddress + virtualAddress - map->virtualAddress; - } - else - { - return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress); - } -} - -/* - * This function Converts a virtual address into a physical - * address, including the dynamically mapped memory. - * - * Parameters virtAddr - virtual address to convert - * Return value: corresponding physical address, or NULL - * if there is no physical address addressable - * by the given virtual address - * OS: VxWorks, Linux, WinCE, QNX, eCos - * Reentrant: Yes - * IRQ safe: Yes - */ -PUBLIC UINT32 -ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency) -{ - IxOsalMemoryMap *map = - ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS, - requestedCoherency); - - if (map != NULL) - { - return map->virtualAddress + physicalAddress - map->physicalAddress; - } - else - { - return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress); - } -} diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c b/arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c deleted file mode 100644 index 3db1a70..0000000 --- a/arch/arm/cpu/ixp/npe/IxOsalOsCacheMMU.c +++ /dev/null @@ -1,67 +0,0 @@ -/** - * @file IxOsalOsCacheMMU.c (linux) - * - * @brief Cache MemAlloc and MemFree. - * - * - * @par - * IXP400 SW Release version 1.5 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxOsal.h" - -#include - -/* - * Allocate on a cache line boundary (null pointers are - * not affected by this operation). This operation is NOT cache safe. - */ -void * -ixOsalCacheDmaMalloc (UINT32 n) -{ - return malloc(n); -} - -/* - * - */ -void -ixOsalCacheDmaFree (void *ptr) -{ - free(ptr); -} diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c b/arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c deleted file mode 100644 index 45a5c68..0000000 --- a/arch/arm/cpu/ixp/npe/IxOsalOsMsgQ.c +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @file IxOsalOsMsgQ.c (eCos) - * - * @brief OS-specific Message Queue implementation. - * - * - * @par - * IXP400 SW Release version 1.5 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxOsal.h" - -/******************************* - * Public functions - *******************************/ -PUBLIC IX_STATUS -ixOsalMessageQueueCreate (IxOsalMessageQueue * queue, - UINT32 msgCount, UINT32 msgLen) -{ - diag_printf("%s called\n", __FUNCTION__); - return IX_FAIL; -} - -PUBLIC IX_STATUS -ixOsalMessageQueueDelete (IxOsalMessageQueue * queue) -{ - diag_printf("%s called\n", __FUNCTION__); - return IX_FAIL; -} - -PUBLIC IX_STATUS -ixOsalMessageQueueSend (IxOsalMessageQueue * queue, UINT8 * message) -{ - diag_printf("%s called\n", __FUNCTION__); - return IX_FAIL; -} - -PUBLIC IX_STATUS -ixOsalMessageQueueReceive (IxOsalMessageQueue * queue, UINT8 * message) -{ - diag_printf("%s called\n", __FUNCTION__); - return IX_FAIL; -} - diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c b/arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c deleted file mode 100644 index 443aefd..0000000 --- a/arch/arm/cpu/ixp/npe/IxOsalOsSemaphore.c +++ /dev/null @@ -1,233 +0,0 @@ -/** - * @file IxOsalOsSemaphore.c (eCos) - * - * @brief Implementation for semaphore and mutex. - * - * - * @par - * IXP400 SW Release version 1.5 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxOsal.h" -#include "IxNpeMhReceive_p.h" - -/* Define a large number */ -#define IX_OSAL_MAX_LONG (0x7FFFFFFF) - -/* Max timeout in MS, used to guard against possible overflow */ -#define IX_OSAL_MAX_TIMEOUT_MS (IX_OSAL_MAX_LONG/HZ) - - -PUBLIC IX_STATUS -ixOsalSemaphoreInit (IxOsalSemaphore * sid, UINT32 start_value) -{ - diag_printf("%s called\n", __FUNCTION__); - return IX_SUCCESS; -} - -/** - * DESCRIPTION: If the semaphore is 'empty', the calling thread is blocked. - * If the semaphore is 'full', it is taken and control is returned - * to the caller. If the time indicated in 'timeout' is reached, - * the thread will unblock and return an error indication. If the - * timeout is set to 'IX_OSAL_WAIT_NONE', the thread will never block; - * if it is set to 'IX_OSAL_WAIT_FOREVER', the thread will block until - * the semaphore is available. - * - * - */ - - -PUBLIC IX_STATUS -ixOsalSemaphoreWait (IxOsalOsSemaphore * sid, INT32 timeout) -{ - diag_printf("%s called\n", __FUNCTION__); - return IX_SUCCESS; -} - -/* - * Attempt to get semaphore, return immediately, - * no error info because users expect some failures - * when using this API. - */ -PUBLIC IX_STATUS -ixOsalSemaphoreTryWait (IxOsalSemaphore * sid) -{ - diag_printf("%s called\n", __FUNCTION__); - return IX_FAIL; -} - -/** - * - * DESCRIPTION: This function causes the next available thread in the pend queue - * to be unblocked. If no thread is pending on this semaphore, the - * semaphore becomes 'full'. - */ -PUBLIC IX_STATUS -ixOsalSemaphorePost (IxOsalSemaphore * sid) -{ - diag_printf("%s called\n", __FUNCTION__); - return IX_SUCCESS; -} - -PUBLIC IX_STATUS -ixOsalSemaphoreGetValue (IxOsalSemaphore * sid, UINT32 * value) -{ - diag_printf("%s called\n", __FUNCTION__); - return IX_FAIL; -} - -PUBLIC IX_STATUS -ixOsalSemaphoreDestroy (IxOsalSemaphore * sid) -{ - diag_printf("%s called\n", __FUNCTION__); - return IX_FAIL; -} - -/**************************** - * Mutex - ****************************/ - -static void drv_mutex_init(IxOsalMutex *mutex) -{ - *mutex = 0; -} - -static void drv_mutex_destroy(IxOsalMutex *mutex) -{ - *mutex = -1; -} - -static int drv_mutex_trylock(IxOsalMutex *mutex) -{ - int result = TRUE; - - if (*mutex == 1) - result = FALSE; - - return result; -} - -static void drv_mutex_unlock(IxOsalMutex *mutex) -{ - if (*mutex == 1) - printf("Trying to unlock unlocked mutex!"); - - *mutex = 0; -} - -PUBLIC IX_STATUS -ixOsalMutexInit (IxOsalMutex * mutex) -{ - drv_mutex_init(mutex); - return IX_SUCCESS; -} - -PUBLIC IX_STATUS -ixOsalMutexLock (IxOsalMutex * mutex, INT32 timeout) -{ - int tries; - - if (timeout == IX_OSAL_WAIT_NONE) { - if (drv_mutex_trylock(mutex)) - return IX_SUCCESS; - else - return IX_FAIL; - } - - tries = (timeout * 1000) / 50; - while (1) { - if (drv_mutex_trylock(mutex)) - return IX_SUCCESS; - if (timeout != IX_OSAL_WAIT_FOREVER && tries-- <= 0) - break; - udelay(50); - } - return IX_FAIL; -} - -PUBLIC IX_STATUS -ixOsalMutexUnlock (IxOsalMutex * mutex) -{ - drv_mutex_unlock(mutex); - return IX_SUCCESS; -} - -/* - * Attempt to get mutex, return immediately, - * no error info because users expect some failures - * when using this API. - */ -PUBLIC IX_STATUS -ixOsalMutexTryLock (IxOsalMutex * mutex) -{ - if (drv_mutex_trylock(mutex)) - return IX_SUCCESS; - return IX_FAIL; -} - -PUBLIC IX_STATUS -ixOsalMutexDestroy (IxOsalMutex * mutex) -{ - drv_mutex_destroy(mutex); - return IX_SUCCESS; -} - -PUBLIC IX_STATUS -ixOsalFastMutexInit (IxOsalFastMutex * mutex) -{ - return ixOsalMutexInit(mutex); -} - -PUBLIC IX_STATUS ixOsalFastMutexTryLock(IxOsalFastMutex *mutex) -{ - return ixOsalMutexTryLock(mutex); -} - - -PUBLIC IX_STATUS -ixOsalFastMutexUnlock (IxOsalFastMutex * mutex) -{ - return ixOsalMutexUnlock(mutex); -} - -PUBLIC IX_STATUS -ixOsalFastMutexDestroy (IxOsalFastMutex * mutex) -{ - return ixOsalMutexDestroy(mutex); -} diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsServices.c b/arch/arm/cpu/ixp/npe/IxOsalOsServices.c deleted file mode 100644 index e18c6c4..0000000 --- a/arch/arm/cpu/ixp/npe/IxOsalOsServices.c +++ /dev/null @@ -1,251 +0,0 @@ -/** - * @file IxOsalOsServices.c (linux) - * - * @brief Implementation for Irq, Mem, sleep. - * - * - * @par - * IXP400 SW Release version 1.5 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include -#include -#include "IxOsal.h" -#include -#include -#include -#include -#include - -static char *traceHeaders[] = { - "", - "[fatal] ", - "[error] ", - "[warning] ", - "[message] ", - "[debug1] ", - "[debug2] ", - "[debug3] ", - "[all]" -}; - -/* by default trace all but debug message */ -PRIVATE int ixOsalCurrLogLevel = IX_OSAL_LOG_LVL_MESSAGE; - -/************************************** - * Irq services - *************************************/ - -PUBLIC IX_STATUS -ixOsalIrqBind (UINT32 vector, IxOsalVoidFnVoidPtr routine, void *parameter) -{ - return IX_FAIL; -} - -PUBLIC IX_STATUS -ixOsalIrqUnbind (UINT32 vector) -{ - return IX_FAIL; -} - -PUBLIC UINT32 -ixOsalIrqLock () -{ - return 0; -} - -/* Enable interrupts and task scheduling, - * input parameter: irqEnable status returned - * by ixOsalIrqLock(). - */ -PUBLIC void -ixOsalIrqUnlock (UINT32 lockKey) -{ -} - -PUBLIC UINT32 -ixOsalIrqLevelSet (UINT32 level) -{ - return IX_FAIL; -} - -PUBLIC void -ixOsalIrqEnable (UINT32 irqLevel) -{ -} - -PUBLIC void -ixOsalIrqDisable (UINT32 irqLevel) -{ -} - -/********************* - * Log function - *********************/ - -INT32 -ixOsalLog (IxOsalLogLevel level, - IxOsalLogDevice device, - char *format, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) -{ - /* - * Return -1 for custom display devices - */ - if ((device != IX_OSAL_LOG_DEV_STDOUT) - && (device != IX_OSAL_LOG_DEV_STDERR)) - { - debug("ixOsalLog: only IX_OSAL_LOG_DEV_STDOUT and IX_OSAL_LOG_DEV_STDERR are supported \n"); - return (IX_OSAL_LOG_ERROR); - } - - if (level <= ixOsalCurrLogLevel && level != IX_OSAL_LOG_LVL_NONE) - { -#if 0 /* sr: U-Boots printf or debug doesn't return a length */ - int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : diag_printf(traceHeaders[level - 1]); - - return headerByteCount + diag_printf (format, arg1, arg2, arg3, arg4, arg5, arg6); -#else - int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : strlen(traceHeaders[level - 1]); - - return headerByteCount + strlen(format); -#endif - } - else - { - /* - * Return error - */ - return (IX_OSAL_LOG_ERROR); - } -} - -PUBLIC UINT32 -ixOsalLogLevelSet (UINT32 level) -{ - UINT32 oldLevel; - - /* - * Check value first - */ - if ((level < IX_OSAL_LOG_LVL_NONE) || (level > IX_OSAL_LOG_LVL_ALL)) - { - ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, - IX_OSAL_LOG_DEV_STDOUT, - "ixOsalLogLevelSet: Log Level is between %d and%d \n", - IX_OSAL_LOG_LVL_NONE, IX_OSAL_LOG_LVL_ALL, 0, 0, 0, 0); - return IX_OSAL_LOG_LVL_NONE; - } - oldLevel = ixOsalCurrLogLevel; - - ixOsalCurrLogLevel = level; - - return oldLevel; -} - -/************************************** - * Task services - *************************************/ - -PUBLIC void -ixOsalBusySleep (UINT32 microseconds) -{ - udelay(microseconds); -} - -PUBLIC void -ixOsalSleep (UINT32 milliseconds) -{ - if (milliseconds != 0) { -#if 1 - /* - * sr: We poll while we wait because interrupts are off in U-Boot - * and CSR expects messages, etc to be dispatched while sleeping. - */ - int i; - IxQMgrDispatcherFuncPtr qDispatcherFunc; - - ixQMgrDispatcherLoopGet(&qDispatcherFunc); - - while (milliseconds--) { - for (i = 1; i <= 2; i++) - ixNpeMhMessagesReceive(i); - (*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP); - - udelay(1000); - } -#endif - } -} - -/************************************** - * Memory functions - *************************************/ - -void * -ixOsalMemAlloc (UINT32 size) -{ - return (void *)0; -} - -void -ixOsalMemFree (void *ptr) -{ -} - -/* - * Copy count bytes from src to dest , - * returns pointer to the dest mem zone. - */ -void * -ixOsalMemCopy (void *dest, void *src, UINT32 count) -{ - IX_OSAL_ASSERT (dest != NULL); - IX_OSAL_ASSERT (src != NULL); - return (memcpy (dest, src, count)); -} - -/* - * Fills a memory zone with a given constant byte, - * returns pointer to the memory zone. - */ -void * -ixOsalMemSet (void *ptr, UINT8 filler, UINT32 count) -{ - IX_OSAL_ASSERT (ptr != NULL); - return (memset (ptr, filler, count)); -} diff --git a/arch/arm/cpu/ixp/npe/IxOsalOsThread.c b/arch/arm/cpu/ixp/npe/IxOsalOsThread.c deleted file mode 100644 index e6a4967..0000000 --- a/arch/arm/cpu/ixp/npe/IxOsalOsThread.c +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file IxOsalOsThread.c (eCos) - * - * @brief OS-specific thread implementation. - * - * - * @par - * IXP400 SW Release version 1.5 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include "IxOsal.h" - -/* Thread attribute is ignored */ -PUBLIC IX_STATUS -ixOsalThreadCreate (IxOsalThread * ptrTid, - IxOsalThreadAttr * threadAttr, IxOsalVoidFnVoidPtr entryPoint, void *arg) -{ - return IX_SUCCESS; -} - -/* - * Start thread after given its thread handle - */ -PUBLIC IX_STATUS -ixOsalThreadStart (IxOsalThread * tId) -{ - /* Thread already started upon creation */ - return IX_SUCCESS; -} - -/* - * In Linux threadKill does not actually destroy the thread, - * it will stop the signal handling. - */ -PUBLIC IX_STATUS -ixOsalThreadKill (IxOsalThread * tid) -{ - return IX_SUCCESS; -} - -PUBLIC void -ixOsalThreadExit (void) -{ -} - -PUBLIC IX_STATUS -ixOsalThreadPrioritySet (IxOsalOsThread * tid, UINT32 priority) -{ - return IX_SUCCESS; -} - -PUBLIC IX_STATUS -ixOsalThreadSuspend (IxOsalThread * tId) -{ - return IX_SUCCESS; - -} - -PUBLIC IX_STATUS -ixOsalThreadResume (IxOsalThread * tId) -{ - return IX_SUCCESS; -} diff --git a/arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c b/arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c deleted file mode 100644 index 7386513..0000000 --- a/arch/arm/cpu/ixp/npe/IxQMgrAqmIf.c +++ /dev/null @@ -1,963 +0,0 @@ -/* - * @file: IxQMgrAqmIf.c - * - * @author Intel Corporation - * @date 30-Oct-2001 - * - * @brief This component provides a set of functions for - * perfoming I/O on the AQM hardware. - * - * Design Notes: - * These functions are intended to be as fast as possible - * and as a result perform NO PARAMETER CHECKING. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * Inlines are compiled as function when this is defined. - * N.B. Must be placed before #include of "IxQMgrAqmIf_p.h - */ -#ifndef IXQMGRAQMIF_P_H -# define IXQMGRAQMIF_C -#else -# error -#endif - -/* - * User defined include files. - */ -#include "IxOsal.h" -#include "IxQMgr.h" -#include "IxQMgrAqmIf_p.h" -#include "IxQMgrLog_p.h" - - -/* - * #defines and macros used in this file. - */ - -/* These defines are the bit offsets of the various fields of - * the queue configuration register - */ -#define IX_QMGR_Q_CONFIG_WRPTR_OFFSET 0x00 -#define IX_QMGR_Q_CONFIG_RDPTR_OFFSET 0x07 -#define IX_QMGR_Q_CONFIG_BADDR_OFFSET 0x0E -#define IX_QMGR_Q_CONFIG_ESIZE_OFFSET 0x16 -#define IX_QMGR_Q_CONFIG_BSIZE_OFFSET 0x18 -#define IX_QMGR_Q_CONFIG_NE_OFFSET 0x1A -#define IX_QMGR_Q_CONFIG_NF_OFFSET 0x1D - -#define IX_QMGR_BASE_ADDR_16_WORD_ALIGN 0x40 -#define IX_QMGR_BASE_ADDR_16_WORD_SHIFT 0x6 - -#define IX_QMGR_NE_NF_CLEAR_MASK 0x03FFFFFF -#define IX_QMGR_NE_MASK 0x7 -#define IX_QMGR_NF_MASK 0x7 -#define IX_QMGR_SIZE_MASK 0x3 -#define IX_QMGR_ENTRY_SIZE_MASK 0x3 -#define IX_QMGR_BADDR_MASK 0x003FC000 -#define IX_QMGR_RDPTR_MASK 0x7F -#define IX_QMGR_WRPTR_MASK 0x7F -#define IX_QMGR_RDWRPTR_MASK 0x00003FFF - -#define IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS 0x1000 - -/* Base address of AQM SRAM */ -#define IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET \ -((IX_QMGR_QUECONFIG_BASE_OFFSET) + (IX_QMGR_QUECONFIG_SIZE)) - -/* Min buffer size used for generating buffer size in QUECONFIG */ -#define IX_QMGR_MIN_BUFFER_SIZE 16 - -/* Reset values of QMgr hardware registers */ -#define IX_QMGR_QUELOWSTAT_RESET_VALUE 0x33333333 -#define IX_QMGR_QUEUOSTAT_RESET_VALUE 0x00000000 -#define IX_QMGR_QUEUPPSTAT0_RESET_VALUE 0xFFFFFFFF -#define IX_QMGR_QUEUPPSTAT1_RESET_VALUE 0x00000000 -#define IX_QMGR_INT0SRCSELREG_RESET_VALUE 0x00000000 -#define IX_QMGR_QUEIEREG_RESET_VALUE 0x00000000 -#define IX_QMGR_QINTREG_RESET_VALUE 0xFFFFFFFF -#define IX_QMGR_QUECONFIG_RESET_VALUE 0x00000000 - -#define IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS IX_OSAL_IXP400_QMGR_PHYS_BASE - -#define IX_QMGR_QUELOWSTAT_BITS_PER_Q (BITS_PER_WORD/IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) - -#define IX_QMGR_QUELOWSTAT_QID_MASK 0x7 -#define IX_QMGR_Q_CONFIG_ADDR_GET(qId)\ - (((qId) * IX_QMGR_NUM_BYTES_PER_WORD) +\ - IX_QMGR_QUECONFIG_BASE_OFFSET) - -#define IX_QMGR_ENTRY1_OFFSET 0 -#define IX_QMGR_ENTRY2_OFFSET 1 -#define IX_QMGR_ENTRY4_OFFSET 3 - -/* - * Variable declarations global to this file. Externs are followed by - * statics. - */ -UINT32 aqmBaseAddress = 0; -/* Store addresses and bit-masks for certain queue access and status registers. - * This is to facilitate inlining of QRead, QWrite and QStatusGet functions - * in IxQMgr,h - */ -extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; -UINT32 * ixQMgrAqmIfQueAccRegAddr[IX_QMGR_MAX_NUM_QUEUES]; -UINT32 ixQMgrAqmIfQueLowStatRegAddr[IX_QMGR_MIN_QUEUPP_QID]; -UINT32 ixQMgrAqmIfQueLowStatBitsOffset[IX_QMGR_MIN_QUEUPP_QID]; -UINT32 ixQMgrAqmIfQueLowStatBitsMask; -UINT32 ixQMgrAqmIfQueUppStat0RegAddr; -UINT32 ixQMgrAqmIfQueUppStat1RegAddr; -UINT32 ixQMgrAqmIfQueUppStat0BitMask[IX_QMGR_MIN_QUEUPP_QID]; -UINT32 ixQMgrAqmIfQueUppStat1BitMask[IX_QMGR_MIN_QUEUPP_QID]; - -/* - * Fast mutexes, one for each queue, used to protect peek & poke functions - */ -IxOsalFastMutex ixQMgrAqmIfPeekPokeFastMutex[IX_QMGR_MAX_NUM_QUEUES]; - -/* - * Function prototypes - */ -PRIVATE unsigned -watermarkToAqmWatermark (IxQMgrWMLevel watermark ); - -PRIVATE unsigned -entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize); - -PRIVATE unsigned -bufferSizeToAqmBufferSize (unsigned bufferSizeInWords); - -PRIVATE void -ixQMgrAqmIfRegistersReset (void); - -PRIVATE void -ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex, - UINT32 configRegWord, - unsigned int qEntrySizeInwords, - unsigned int qSizeInWords, - UINT32 **address); -/* - * Function definitions - */ -void -ixQMgrAqmIfInit (void) -{ - UINT32 aqmVirtualAddr; - int i; - - /* The value of aqmBaseAddress depends on the logical address - * assigned by the MMU. - */ - aqmVirtualAddr = - (UINT32) IX_OSAL_MEM_MAP(IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS, - IX_OSAL_IXP400_QMGR_MAP_SIZE); - IX_OSAL_ASSERT (aqmVirtualAddr); - - ixQMgrAqmIfBaseAddressSet (aqmVirtualAddr); - - ixQMgrAqmIfRegistersReset (); - - for (i = 0; i< IX_QMGR_MAX_NUM_QUEUES; i++) - { - ixOsalFastMutexInit(&ixQMgrAqmIfPeekPokeFastMutex[i]); - - /******************************************************************** - * Register addresses and bit masks are calculated and stored here to - * facilitate inlining of QRead, QWrite and QStatusGet functions in - * IxQMgr.h. - * These calculations are normally performed dynamically in inlined - * functions in IxQMgrAqmIf_p.h, and their semantics are reused here. - */ - - /* AQM Queue access reg addresses, per queue */ - ixQMgrAqmIfQueAccRegAddr[i] = - (UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i)); - ixQMgrQInlinedReadWriteInfo[i].qAccRegAddr = - (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i)); - - - ixQMgrQInlinedReadWriteInfo[i].qConfigRegAddr = - (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(i)); - - /* AQM Queue lower-group (0-31), only */ - if (i < IX_QMGR_MIN_QUEUPP_QID) - { - /* AQM Q underflow/overflow status register addresses, per queue */ - ixQMgrQInlinedReadWriteInfo[i].qUOStatRegAddr = - (volatile UINT32 *)(aqmBaseAddress + - IX_QMGR_QUEUOSTAT0_OFFSET + - ((i / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD) * - IX_QMGR_NUM_BYTES_PER_WORD)); - - /* AQM Q underflow status bit masks for status register per queue */ - ixQMgrQInlinedReadWriteInfo[i].qUflowStatBitMask = - (IX_QMGR_UNDERFLOW_BIT_OFFSET + 1) << - ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) * - (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD)); - - /* AQM Q overflow status bit masks for status register, per queue */ - ixQMgrQInlinedReadWriteInfo[i].qOflowStatBitMask = - (IX_QMGR_OVERFLOW_BIT_OFFSET + 1) << - ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) * - (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD)); - - /* AQM Q lower-group (0-31) status register addresses, per queue */ - ixQMgrAqmIfQueLowStatRegAddr[i] = aqmBaseAddress + - IX_QMGR_QUELOWSTAT0_OFFSET + - ((i / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) * - IX_QMGR_NUM_BYTES_PER_WORD); - - /* AQM Q lower-group (0-31) status register bit offset */ - ixQMgrAqmIfQueLowStatBitsOffset[i] = - (i & (IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD - 1)) * - (BITS_PER_WORD / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD); - } - else /* AQM Q upper-group (32-63), only */ - { - /* AQM Q upper-group (32-63) Nearly Empty status reg bit masks */ - ixQMgrAqmIfQueUppStat0BitMask[i - IX_QMGR_MIN_QUEUPP_QID] = - (1 << (i - IX_QMGR_MIN_QUEUPP_QID)); - - /* AQM Q upper-group (32-63) Full status register bit masks */ - ixQMgrAqmIfQueUppStat1BitMask[i - IX_QMGR_MIN_QUEUPP_QID] = - (1 << (i - IX_QMGR_MIN_QUEUPP_QID)); - } - } - - /* AQM Q lower-group (0-31) status register bit mask */ - ixQMgrAqmIfQueLowStatBitsMask = (1 << - (BITS_PER_WORD / - IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)) - 1; - - /* AQM Q upper-group (32-63) Nearly Empty status register address */ - ixQMgrAqmIfQueUppStat0RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET; - - /* AQM Q upper-group (32-63) Full status register address */ - ixQMgrAqmIfQueUppStat1RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET; -} - -/* - * Uninitialise the AqmIf module by unmapping memory, etc - */ -void -ixQMgrAqmIfUninit (void) -{ - UINT32 virtAddr; - - ixQMgrAqmIfBaseAddressGet (&virtAddr); - IX_OSAL_MEM_UNMAP (virtAddr); - ixQMgrAqmIfBaseAddressSet (0); -} - -/* - * Set the the logical base address of AQM - */ -void -ixQMgrAqmIfBaseAddressSet (UINT32 address) -{ - aqmBaseAddress = address; -} - -/* - * Get the logical base address of AQM - */ -void -ixQMgrAqmIfBaseAddressGet (UINT32 *address) -{ - *address = aqmBaseAddress; -} - -/* - * Get the logical base address of AQM SRAM - */ -void -ixQMgrAqmIfSramBaseAddressGet (UINT32 *address) -{ - *address = aqmBaseAddress + - IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET; -} - -/* - * This function will write the status bits of a queue - * specified by qId. - */ -void -ixQMgrAqmIfQRegisterBitsWrite (IxQMgrQId qId, - UINT32 registerBaseAddrOffset, - unsigned queuesPerRegWord, - UINT32 value) -{ - volatile UINT32 *registerAddress; - UINT32 registerWord; - UINT32 statusBitsMask; - UINT32 bitsPerQueue; - - bitsPerQueue = BITS_PER_WORD / queuesPerRegWord; - - /* - * Calculate the registerAddress - * multiple queues split accross registers - */ - registerAddress = (UINT32*)(aqmBaseAddress + - registerBaseAddrOffset + - ((qId / queuesPerRegWord) * - IX_QMGR_NUM_BYTES_PER_WORD)); - - /* Read the current data */ - ixQMgrAqmIfWordRead (registerAddress, ®isterWord); - - - if( (registerBaseAddrOffset == IX_QMGR_INT0SRCSELREG0_OFFSET) && - (qId == IX_QMGR_QUEUE_0) ) - { - statusBitsMask = 0x7 ; - - /* Queue 0 at INT0SRCSELREG should not corrupt the value bit-3 */ - value &= 0x7 ; - } - else - { - /* Calculate the mask for the status bits for this queue. */ - statusBitsMask = ((1 << bitsPerQueue) - 1); - statusBitsMask <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue); - - /* Mask out bits in value that would overwrite other q data */ - value <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue); - value &= statusBitsMask; - } - - /* Mask out bits to write to */ - registerWord &= ~statusBitsMask; - - - /* Set the write bits */ - registerWord |= value; - - /* - * Write the data - */ - ixQMgrAqmIfWordWrite (registerAddress, registerWord); -} - -/* - * This function generates the parameters that can be used to - * check if a Qs status matches the specified source select. - * It calculates which status word to check (statusWordOffset), - * the value to check the status against (checkValue) and the - * mask (mask) to mask out all but the bits to check in the status word. - */ -void -ixQMgrAqmIfQStatusCheckValsCalc (IxQMgrQId qId, - IxQMgrSourceId srcSel, - unsigned int *statusWordOffset, - UINT32 *checkValue, - UINT32 *mask) -{ - UINT32 shiftVal; - - if (qId < IX_QMGR_MIN_QUEUPP_QID) - { - switch (srcSel) - { - case IX_QMGR_Q_SOURCE_ID_E: - *checkValue = IX_QMGR_Q_STATUS_E_BIT_MASK; - *mask = IX_QMGR_Q_STATUS_E_BIT_MASK; - break; - case IX_QMGR_Q_SOURCE_ID_NE: - *checkValue = IX_QMGR_Q_STATUS_NE_BIT_MASK; - *mask = IX_QMGR_Q_STATUS_NE_BIT_MASK; - break; - case IX_QMGR_Q_SOURCE_ID_NF: - *checkValue = IX_QMGR_Q_STATUS_NF_BIT_MASK; - *mask = IX_QMGR_Q_STATUS_NF_BIT_MASK; - break; - case IX_QMGR_Q_SOURCE_ID_F: - *checkValue = IX_QMGR_Q_STATUS_F_BIT_MASK; - *mask = IX_QMGR_Q_STATUS_F_BIT_MASK; - break; - case IX_QMGR_Q_SOURCE_ID_NOT_E: - *checkValue = 0; - *mask = IX_QMGR_Q_STATUS_E_BIT_MASK; - break; - case IX_QMGR_Q_SOURCE_ID_NOT_NE: - *checkValue = 0; - *mask = IX_QMGR_Q_STATUS_NE_BIT_MASK; - break; - case IX_QMGR_Q_SOURCE_ID_NOT_NF: - *checkValue = 0; - *mask = IX_QMGR_Q_STATUS_NF_BIT_MASK; - break; - case IX_QMGR_Q_SOURCE_ID_NOT_F: - *checkValue = 0; - *mask = IX_QMGR_Q_STATUS_F_BIT_MASK; - break; - default: - /* Should never hit */ - IX_OSAL_ASSERT(0); - break; - } - - /* One nibble of status per queue so need to shift the - * check value and mask out to the correct position. - */ - shiftVal = (qId % IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) * - IX_QMGR_QUELOWSTAT_BITS_PER_Q; - - /* Calculate the which status word to check from the qId, - * 8 Qs status per word - */ - *statusWordOffset = qId / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD; - - *checkValue <<= shiftVal; - *mask <<= shiftVal; - } - else - { - /* One status word */ - *statusWordOffset = 0; - /* Single bits per queue and int source bit hardwired NE, - * Qs start at 32. - */ - *mask = 1 << (qId - IX_QMGR_MIN_QUEUPP_QID); - *checkValue = *mask; - } -} - -void -ixQMgrAqmIfQInterruptEnable (IxQMgrQId qId) -{ - volatile UINT32 *registerAddress; - UINT32 registerWord; - UINT32 actualBitOffset; - - if (qId < IX_QMGR_MIN_QUEUPP_QID) - { - registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET); - } - else - { - registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET); - } - - actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID); - - ixQMgrAqmIfWordRead (registerAddress, ®isterWord); - ixQMgrAqmIfWordWrite (registerAddress, (registerWord | actualBitOffset)); -} - -void -ixQMgrAqmIfQInterruptDisable (IxQMgrQId qId) -{ - volatile UINT32 *registerAddress; - UINT32 registerWord; - UINT32 actualBitOffset; - - if (qId < IX_QMGR_MIN_QUEUPP_QID) - { - registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET); - } - else - { - registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET); - } - - actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID); - - ixQMgrAqmIfWordRead (registerAddress, ®isterWord); - ixQMgrAqmIfWordWrite (registerAddress, registerWord & (~actualBitOffset)); -} - -void -ixQMgrAqmIfQueCfgWrite (IxQMgrQId qId, - IxQMgrQSizeInWords qSizeInWords, - IxQMgrQEntrySizeInWords entrySizeInWords, - UINT32 freeSRAMAddress) -{ - volatile UINT32 *cfgAddress = NULL; - UINT32 qCfg = 0; - UINT32 baseAddress = 0; - unsigned aqmEntrySize = 0; - unsigned aqmBufferSize = 0; - - /* Build config register */ - aqmEntrySize = entrySizeToAqmEntrySize (entrySizeInWords); - qCfg |= (aqmEntrySize&IX_QMGR_ENTRY_SIZE_MASK) << - IX_QMGR_Q_CONFIG_ESIZE_OFFSET; - - aqmBufferSize = bufferSizeToAqmBufferSize (qSizeInWords); - qCfg |= (aqmBufferSize&IX_QMGR_SIZE_MASK) << IX_QMGR_Q_CONFIG_BSIZE_OFFSET; - - /* baseAddress, calculated relative to aqmBaseAddress and start address */ - baseAddress = freeSRAMAddress - - (aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET); - - /* Verify base address aligned to a 16 word boundary */ - if ((baseAddress % IX_QMGR_BASE_ADDR_16_WORD_ALIGN) != 0) - { - IX_QMGR_LOG_ERROR0("ixQMgrAqmIfQueCfgWrite () address is not on 16 word boundary\n"); - } - /* Now convert it to a 16 word pointer as required by QUECONFIG register */ - baseAddress >>= IX_QMGR_BASE_ADDR_16_WORD_SHIFT; - - - qCfg |= (baseAddress << IX_QMGR_Q_CONFIG_BADDR_OFFSET); - - - cfgAddress = (UINT32*)(aqmBaseAddress + - IX_QMGR_Q_CONFIG_ADDR_GET(qId)); - - - /* NOTE: High and Low watermarks are set to zero */ - ixQMgrAqmIfWordWrite (cfgAddress, qCfg); -} - -void -ixQMgrAqmIfQueCfgRead (IxQMgrQId qId, - unsigned int numEntries, - UINT32 *baseAddress, - unsigned int *ne, - unsigned int *nf, - UINT32 *readPtr, - UINT32 *writePtr) -{ - UINT32 qcfg; - UINT32 *cfgAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId)); - unsigned int qEntrySizeInwords; - unsigned int qSizeInWords; - UINT32 *readPtr_ = NULL; - - /* Read the queue configuration register */ - ixQMgrAqmIfWordRead (cfgAddress, &qcfg); - - /* Extract the base address */ - *baseAddress = (UINT32)((qcfg & IX_QMGR_BADDR_MASK) >> - (IX_QMGR_Q_CONFIG_BADDR_OFFSET)); - - /* Base address is a 16 word pointer from the start of AQM SRAM. - * Convert to absolute word address. - */ - *baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT; - *baseAddress += (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET; - - /* - * Extract the watermarks. 0->0 entries, 1->1 entries, 2->2 entries, 3->4 entries...... - * If ne > 0 ==> neInEntries = 2^(ne - 1) - * If ne == 0 ==> neInEntries = 0 - * The same applies. - */ - *ne = ((qcfg) >> (IX_QMGR_Q_CONFIG_NE_OFFSET)) & IX_QMGR_NE_MASK; - *nf = ((qcfg) >> (IX_QMGR_Q_CONFIG_NF_OFFSET)) & IX_QMGR_NF_MASK; - - if (0 != *ne) - { - *ne = 1 << (*ne - 1); - } - if (0 != *nf) - { - *nf = 1 << (*nf - 1); - } - - /* Get the queue entry size in words */ - qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId); - - /* Get the queue size in words */ - qSizeInWords = ixQMgrQSizeInWordsGet (qId); - - ixQMgrAqmIfEntryAddressGet (0/* Entry 0. i.e the readPtr*/, - qcfg, - qEntrySizeInwords, - qSizeInWords, - &readPtr_); - *readPtr = (UINT32)readPtr_; - *readPtr -= (UINT32)aqmBaseAddress;/* Offset, not absolute address */ - - *writePtr = (qcfg >> IX_QMGR_Q_CONFIG_WRPTR_OFFSET) & IX_QMGR_WRPTR_MASK; - *writePtr = *baseAddress + (*writePtr * (IX_QMGR_NUM_BYTES_PER_WORD)); - return; -} - -unsigned -ixQMgrAqmIfLog2 (unsigned number) -{ - unsigned count = 0; - - /* - * N.B. this function will return 0 - * for ixQMgrAqmIfLog2 (0) - */ - while (number/2) - { - number /=2; - count++; - } - - return count; -} - -void ixQMgrAqmIfIntSrcSelReg0Bit3Set (void) -{ - - volatile UINT32 *registerAddress; - UINT32 registerWord; - - /* - * Calculate the registerAddress - * multiple queues split accross registers - */ - registerAddress = (UINT32*)(aqmBaseAddress + - IX_QMGR_INT0SRCSELREG0_OFFSET); - - /* Read the current data */ - ixQMgrAqmIfWordRead (registerAddress, ®isterWord); - - /* Set the write bits */ - registerWord |= (1<> - (IX_QMGR_Q_CONFIG_BADDR_OFFSET)); - - /* Base address is a 16 word pointer from the start of AQM SRAM. - * Convert to absolute word address. - */ - baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT; - baseAddress += ((UINT32)aqmBaseAddress + (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET); - - /* Extract the read pointer. Read pointer is a word pointer */ - readPtr = (UINT32)((configRegWord >> - IX_QMGR_Q_CONFIG_RDPTR_OFFSET)&IX_QMGR_RDPTR_MASK); - - /* Read/Write pointers(word pointers) are offsets from the queue buffer space base address. - * Calculate the absolute read pointer address. NOTE: Queues are circular buffers. - */ - readPtr = (readPtr + (entryIndex * qEntrySizeInwords)) & (qSizeInWords - 1); /* Mask by queue size */ - *address = (UINT32 *)(baseAddress + (readPtr * (IX_QMGR_NUM_BYTES_PER_WORD))); - - switch (qEntrySizeInwords) - { - case IX_QMGR_Q_ENTRY_SIZE1: - IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY1_OFFSET) < topOfAqmSram); - break; - case IX_QMGR_Q_ENTRY_SIZE2: - IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY2_OFFSET) < topOfAqmSram); - break; - case IX_QMGR_Q_ENTRY_SIZE4: - IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY4_OFFSET) < topOfAqmSram); - break; - default: - IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfEntryAddressGet"); - break; - } - -} - -IX_STATUS -ixQMgrAqmIfQPeek (IxQMgrQId qId, - unsigned int entryIndex, - unsigned int *entry) -{ - UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId)); - UINT32 *entryAddress = NULL; - UINT32 configRegWordOnEntry; - UINT32 configRegWordOnExit; - unsigned int qEntrySizeInwords; - unsigned int qSizeInWords; - - /* Get the queue entry size in words */ - qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId); - - /* Get the queue size in words */ - qSizeInWords = ixQMgrQSizeInWordsGet (qId); - - /* Read the config register */ - ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry); - - /* Get the entry address */ - ixQMgrAqmIfEntryAddressGet (entryIndex, - configRegWordOnEntry, - qEntrySizeInwords, - qSizeInWords, - &entryAddress); - - /* Get the lock or return busy */ - if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId])) - { - return IX_FAIL; - } - - while(qEntrySizeInwords--) - { - ixQMgrAqmIfWordRead (entryAddress++, entry++); - } - - /* Release the lock */ - ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]); - - /* Read the config register */ - ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit); - - /* Check that the read and write pointers have not changed */ - if (configRegWordOnEntry != configRegWordOnExit) - { - return IX_FAIL; - } - - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrAqmIfQPoke (IxQMgrQId qId, - unsigned entryIndex, - unsigned int *entry) -{ - UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId)); - UINT32 *entryAddress = NULL; - UINT32 configRegWordOnEntry; - UINT32 configRegWordOnExit; - unsigned int qEntrySizeInwords; - unsigned int qSizeInWords; - - /* Get the queue entry size in words */ - qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId); - - /* Get the queue size in words */ - qSizeInWords = ixQMgrQSizeInWordsGet (qId); - - /* Read the config register */ - ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry); - - /* Get the entry address */ - ixQMgrAqmIfEntryAddressGet (entryIndex, - configRegWordOnEntry, - qEntrySizeInwords, - qSizeInWords, - &entryAddress); - - /* Get the lock or return busy */ - if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId])) - { - return IX_FAIL; - } - - /* Else read the entry directly from SRAM. This will not move the read pointer */ - while(qEntrySizeInwords--) - { - ixQMgrAqmIfWordWrite (entryAddress++, *entry++); - } - - /* Release the lock */ - ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]); - - /* Read the config register */ - ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit); - - /* Check that the read and write pointers have not changed */ - if (configRegWordOnEntry != configRegWordOnExit) - { - return IX_FAIL; - } - - return IX_SUCCESS; -} - -PRIVATE unsigned -watermarkToAqmWatermark (IxQMgrWMLevel watermark ) -{ - unsigned aqmWatermark = 0; - - /* - * Watermarks 0("000"),1("001"),2("010"),4("011"), - * 8("100"),16("101"),32("110"),64("111") - */ - aqmWatermark = ixQMgrAqmIfLog2 (watermark * 2); - - return aqmWatermark; -} - -PRIVATE unsigned -entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize) -{ - /* entrySize 1("00"),2("01"),4("10") */ - return (ixQMgrAqmIfLog2 (entrySize)); -} - -PRIVATE unsigned -bufferSizeToAqmBufferSize (unsigned bufferSizeInWords) -{ - /* bufferSize 16("00"),32("01),64("10"),128("11") */ - return (ixQMgrAqmIfLog2 (bufferSizeInWords / IX_QMGR_MIN_BUFFER_SIZE)); -} - -/* - * Reset AQM registers to default values. - */ -PRIVATE void -ixQMgrAqmIfRegistersReset (void) -{ - volatile UINT32 *qConfigWordAddress = NULL; - unsigned int i; - - /* - * Need to initialize AQM hardware registers to an initial - * value as init may have been called as a result of a soft - * reset. i.e. soft reset does not reset hardware registers. - */ - - /* Reset queues 0..31 status registers 0..3 */ - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT0_OFFSET), - IX_QMGR_QUELOWSTAT_RESET_VALUE); - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT1_OFFSET), - IX_QMGR_QUELOWSTAT_RESET_VALUE); - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT2_OFFSET), - IX_QMGR_QUELOWSTAT_RESET_VALUE); - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT3_OFFSET), - IX_QMGR_QUELOWSTAT_RESET_VALUE); - - /* Reset underflow/overflow status registers 0..1 */ - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT0_OFFSET), - IX_QMGR_QUEUOSTAT_RESET_VALUE); - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT1_OFFSET), - IX_QMGR_QUEUOSTAT_RESET_VALUE); - - /* Reset queues 32..63 nearly empty status registers */ - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET), - IX_QMGR_QUEUPPSTAT0_RESET_VALUE); - - /* Reset queues 32..63 full status registers */ - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET), - IX_QMGR_QUEUPPSTAT1_RESET_VALUE); - - /* Reset int0 status flag source select registers 0..3 */ - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG0_OFFSET), - IX_QMGR_INT0SRCSELREG_RESET_VALUE); - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG1_OFFSET), - IX_QMGR_INT0SRCSELREG_RESET_VALUE); - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG2_OFFSET), - IX_QMGR_INT0SRCSELREG_RESET_VALUE); - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG3_OFFSET), - IX_QMGR_INT0SRCSELREG_RESET_VALUE); - - /* Reset queue interrupt enable register 0..1 */ - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET), - IX_QMGR_QUEIEREG_RESET_VALUE); - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET), - IX_QMGR_QUEIEREG_RESET_VALUE); - - /* Reset queue interrupt register 0..1 */ - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG0_OFFSET), - IX_QMGR_QINTREG_RESET_VALUE); - ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG1_OFFSET), - IX_QMGR_QINTREG_RESET_VALUE); - - /* Reset queue configuration words 0..63 */ - qConfigWordAddress = (UINT32 *)(aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET); - for (i = 0; i < (IX_QMGR_QUECONFIG_SIZE / sizeof(UINT32)); i++) - { - ixQMgrAqmIfWordWrite(qConfigWordAddress, - IX_QMGR_QUECONFIG_RESET_VALUE); - /* Next word */ - qConfigWordAddress++; - } -} - diff --git a/arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c b/arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c deleted file mode 100644 index 9cb1439..0000000 --- a/arch/arm/cpu/ixp/npe/IxQMgrDispatcher.c +++ /dev/null @@ -1,1344 +0,0 @@ -/** - * @file IxQMgrDispatcher.c - * - * @author Intel Corporation - * @date 20-Dec-2001 - * - * @brief This file contains the implementation of the Dispatcher sub component - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * User defined include files. - */ -#include "IxQMgr.h" -#include "IxQMgrAqmIf_p.h" -#include "IxQMgrQCfg_p.h" -#include "IxQMgrDispatcher_p.h" -#include "IxQMgrLog_p.h" -#include "IxQMgrDefines_p.h" -#include "IxFeatureCtrl.h" -#include "IxOsal.h" - - - -/* - * #defines and macros used in this file. - */ - - -/* - * This constant is used to indicate the number of priority levels supported - */ -#define IX_QMGR_NUM_PRIORITY_LEVELS 3 - -/* - * This constant is used to set the size of the array of status words - */ -#define MAX_Q_STATUS_WORDS 4 - -/* - * This macro is used to check if a given priority is valid - */ -#define IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority) \ -(((priority) >= IX_QMGR_Q_PRIORITY_0) && ((priority) <= IX_QMGR_Q_PRIORITY_2)) - -/* - * This macto is used to check that a given interrupt source is valid - */ -#define IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel) \ -(((srcSel) >= IX_QMGR_Q_SOURCE_ID_E) && ((srcSel) <= IX_QMGR_Q_SOURCE_ID_NOT_F)) - -/* - * Number of times a dummy callback is called before logging a trace - * message - */ -#define LOG_THROTTLE_COUNT 1000000 - -/* Priority tables limits */ -#define IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX (0) -#define IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX (16) -#define IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX (31) -#define IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX (32) -#define IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX (48) -#define IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX (63) - -/* - * This macro is used to check if a given callback type is valid - */ -#define IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type) \ - (((type) >= IX_QMGR_TYPE_REALTIME_OTHER) && \ - ((type) <= IX_QMGR_TYPE_REALTIME_SPORADIC)) - -/* - * define max index in lower queue to use in loops - */ -#define IX_QMGR_MAX_LOW_QUE_TABLE_INDEX (31) - -/* - * Typedefs whose scope is limited to this file. - */ - -/* - * Information on a queue needed by the Dispatcher - */ -typedef struct -{ - IxQMgrCallback callback; /* Notification callback */ - IxQMgrCallbackId callbackId; /* Notification callback identifier */ - unsigned dummyCallbackCount; /* Number of times runs of dummy callback */ - IxQMgrPriority priority; /* Dispatch priority */ - unsigned int statusWordOffset; /* Offset to the status word to check */ - UINT32 statusMask; /* Status mask */ - UINT32 statusCheckValue; /* Status check value */ - UINT32 intRegCheckMask; /* Interrupt register check mask */ -} IxQMgrQInfo; - -/* - * Variable declarations global to this file. Externs are followed by - * statics. - */ - -/* - * Flag to keep record of what dispatcher set in featureCtrl when ixQMgrInit() - * is called. This is needed because it is possible that a client might - * change whether the live lock prevention dispatcher is used between - * calls to ixQMgrInit() and ixQMgrDispatcherLoopGet(). - */ -PRIVATE IX_STATUS ixQMgrOrigB0Dispatcher = IX_FEATURE_CTRL_COMPONENT_ENABLED; - -/* - * keep record of Q types - not in IxQMgrQInfo for performance as - * it is only used with ixQMgrDispatcherLoopRunB0LLP() - */ -PRIVATE IxQMgrType ixQMgrQTypes[IX_QMGR_MAX_NUM_QUEUES]; - -/* - * This array contains a list of queue identifiers ordered by priority. The table - * is split logically between queue identifiers 0-31 and 32-63. - */ -static IxQMgrQId priorityTable[IX_QMGR_MAX_NUM_QUEUES]; - -/* - * This flag indicates to the dispatcher that the priority table needs to be rebuilt. - */ -static BOOL rebuildTable = FALSE; - -/* Dispatcher statistics */ -static IxQMgrDispatcherStats dispatcherStats; - -/* Table of queue information */ -static IxQMgrQInfo dispatchQInfo[IX_QMGR_MAX_NUM_QUEUES]; - -/* Masks use to identify the first queues in the priority tables -* when comparing with the interrupt register -*/ -static unsigned int lowPriorityTableFirstHalfMask; -static unsigned int uppPriorityTableFirstHalfMask; - -/* - * Static function prototypes - */ - -/* - * This function is the default callback for all queues - */ -PRIVATE void -dummyCallback (IxQMgrQId qId, - IxQMgrCallbackId cbId); - -PRIVATE void -ixQMgrDispatcherReBuildPriorityTable (void); - -/* - * Function definitions. - */ -void -ixQMgrDispatcherInit (void) -{ - int i; - IxFeatureCtrlProductId productId = 0; - IxFeatureCtrlDeviceId deviceId = 0; - BOOL stickyIntSilicon = TRUE; - - /* Set default priorities */ - for (i=0; i< IX_QMGR_MAX_NUM_QUEUES; i++) - { - dispatchQInfo[i].callback = dummyCallback; - dispatchQInfo[i].callbackId = 0; - dispatchQInfo[i].dummyCallbackCount = 0; - dispatchQInfo[i].priority = IX_QMGR_Q_PRIORITY_2; - dispatchQInfo[i].statusWordOffset = 0; - dispatchQInfo[i].statusCheckValue = 0; - dispatchQInfo[i].statusMask = 0; - /* - * There are two interrupt registers, 32 bits each. One for the lower - * queues(0-31) and one for the upper queues(32-63). Therefore need to - * mod by 32 i.e the min upper queue identifier. - */ - dispatchQInfo[i].intRegCheckMask = (1<<(i%(IX_QMGR_MIN_QUEUPP_QID))); - - /* - * Set the Q types - will only be used with livelock - */ - ixQMgrQTypes[i] = IX_QMGR_TYPE_REALTIME_OTHER; - - /* Reset queue statistics */ - dispatcherStats.queueStats[i].callbackCnt = 0; - dispatcherStats.queueStats[i].priorityChangeCnt = 0; - dispatcherStats.queueStats[i].intNoCallbackCnt = 0; - dispatcherStats.queueStats[i].intLostCallbackCnt = 0; - dispatcherStats.queueStats[i].notificationEnabled = FALSE; - dispatcherStats.queueStats[i].srcSel = 0; - - } - - /* Priority table. Order the table from queue 0 to 63 */ - ixQMgrDispatcherReBuildPriorityTable(); - - /* Reset statistics */ - dispatcherStats.loopRunCnt = 0; - - /* Get the device ID for the underlying silicon */ - deviceId = ixFeatureCtrlDeviceRead(); - - /* Get the product ID for the underlying silicon */ - productId = ixFeatureCtrlProductIdRead(); - - /* - * Check featureCtrl to see if Livelock prevention is required - */ - ixQMgrOrigB0Dispatcher = ixFeatureCtrlSwConfigurationCheck( - IX_FEATURECTRL_ORIGB0_DISPATCHER); - - /* - * Check if the silicon supports the sticky interrupt feature. - * IF (IXP42X AND A0) -> No sticky interrupt feature supported - */ - if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X == - (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) && - (IX_FEATURE_CTRL_SILICON_TYPE_A0 == - (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId))) - { - stickyIntSilicon = FALSE; - } - - /* - * IF user wants livelock prev option AND silicon supports sticky interrupt - * feature -> enable the sticky interrupt bit - */ - if ((IX_FEATURE_CTRL_SWCONFIG_DISABLED == ixQMgrOrigB0Dispatcher) && - stickyIntSilicon) - { - ixQMgrStickyInterruptRegEnable(); - } -} - -IX_STATUS -ixQMgrDispatcherPrioritySet (IxQMgrQId qId, - IxQMgrPriority priority) -{ - int ixQMgrLockKey; - - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - - if (!IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority)) - { - return IX_QMGR_Q_INVALID_PRIORITY; - } - - ixQMgrLockKey = ixOsalIrqLock(); - - /* Change priority */ - dispatchQInfo[qId].priority = priority; - /* Set flag */ - rebuildTable = TRUE; - - ixOsalIrqUnlock(ixQMgrLockKey); - -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qId].priorityChangeCnt++; -#endif - - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrNotificationCallbackSet (IxQMgrQId qId, - IxQMgrCallback callback, - IxQMgrCallbackId callbackId) -{ - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - - if (NULL == callback) - { - /* Reset to dummy callback */ - dispatchQInfo[qId].callback = dummyCallback; - dispatchQInfo[qId].dummyCallbackCount = 0; - dispatchQInfo[qId].callbackId = 0; - } - else - { - dispatchQInfo[qId].callback = callback; - dispatchQInfo[qId].callbackId = callbackId; - } - - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrNotificationEnable (IxQMgrQId qId, - IxQMgrSourceId srcSel) -{ - IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */ - IxQMgrQStatus qStatusOnExit; /* to this function */ - int ixQMgrLockKey; - -#ifndef NDEBUG - if (!ixQMgrQIsConfigured (qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - - if ((qId < IX_QMGR_MIN_QUEUPP_QID) && - !IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel)) - { - /* QId 0-31 source id invalid */ - return IX_QMGR_INVALID_INT_SOURCE_ID; - } - - if ((IX_QMGR_Q_SOURCE_ID_NE != srcSel) && - (qId >= IX_QMGR_MIN_QUEUPP_QID)) - { - /* - * For queues 32-63 the interrupt source is fixed to the Nearly - * Empty status flag and therefore should have a srcSel of NE. - */ - return IX_QMGR_INVALID_INT_SOURCE_ID; - } -#endif - -#ifndef NDEBUG - dispatcherStats.queueStats[qId].notificationEnabled = TRUE; - dispatcherStats.queueStats[qId].srcSel = srcSel; -#endif - - /* Get the current queue status */ - ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry); - - /* - * Enabling interrupts results in Read-Modify-Write - * so need critical section - */ - - ixQMgrLockKey = ixOsalIrqLock(); - - /* Calculate the checkMask and checkValue for this q */ - ixQMgrAqmIfQStatusCheckValsCalc (qId, - srcSel, - &dispatchQInfo[qId].statusWordOffset, - &dispatchQInfo[qId].statusCheckValue, - &dispatchQInfo[qId].statusMask); - - - /* Set the interrupt source is this queue is in the range 0-31 */ - if (qId < IX_QMGR_MIN_QUEUPP_QID) - { - ixQMgrAqmIfIntSrcSelWrite (qId, srcSel); - } - - /* Enable the interrupt */ - ixQMgrAqmIfQInterruptEnable (qId); - - ixOsalIrqUnlock(ixQMgrLockKey); - - /* Get the current queue status */ - ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit); - - /* If the status has changed return a warning */ - if (qStatusOnEntry != qStatusOnExit) - { - return IX_QMGR_WARNING; - } - - return IX_SUCCESS; -} - - -IX_STATUS -ixQMgrNotificationDisable (IxQMgrQId qId) -{ - int ixQMgrLockKey; - -#ifndef NDEBUG - /* Validate parameters */ - if (!ixQMgrQIsConfigured (qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } -#endif - - /* - * Enabling interrupts results in Read-Modify-Write - * so need critical section - */ -#ifndef NDEBUG - dispatcherStats.queueStats[qId].notificationEnabled = FALSE; -#endif - - ixQMgrLockKey = ixOsalIrqLock(); - - ixQMgrAqmIfQInterruptDisable (qId); - - ixOsalIrqUnlock(ixQMgrLockKey); - - return IX_SUCCESS; -} - -void -ixQMgrStickyInterruptRegEnable(void) -{ - /* Use Aqm If function to set Interrupt Register0 Bit-3 */ - ixQMgrAqmIfIntSrcSelReg0Bit3Set (); -} - -#if !defined __XSCALE__ || defined __linux - -/* Count the number of leading zero bits in a word, - * and return the same value than the CLZ instruction. - * - * word (in) return value (out) - * 0x80000000 0 - * 0x40000000 1 - * ,,, ,,, - * 0x00000002 30 - * 0x00000001 31 - * 0x00000000 32 - * - * The C version of this function is used as a replacement - * for system not providing the equivalent of the CLZ - * assembly language instruction. - * - * Note that this version is big-endian - */ -unsigned int -ixQMgrCountLeadingZeros(UINT32 word) -{ - unsigned int leadingZerosCount = 0; - - if (word == 0) - { - return 32; - } - /* search the first bit set by testing the MSB and shifting the input word */ - while ((word & 0x80000000) == 0) - { - word <<= 1; - leadingZerosCount++; - } - return leadingZerosCount; -} -#endif /* not __XSCALE__ or __linux */ - -void -ixQMgrDispatcherLoopGet (IxQMgrDispatcherFuncPtr *qDispatcherFuncPtr) -{ - IxFeatureCtrlProductId productId = 0; - IxFeatureCtrlDeviceId deviceId = 0; - - /* Get the device ID for the underlying silicon */ - deviceId = ixFeatureCtrlDeviceRead(); - - /* Get the product ID for the underlying silicon */ - productId = ixFeatureCtrlProductIdRead (); - - /* IF (IXP42X AND A0 silicon) -> use ixQMgrDispatcherLoopRunA0 */ - if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X == - (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) && - (IX_FEATURE_CTRL_SILICON_TYPE_A0 == - (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId))) - { - /*For IXP42X A0 silicon */ - *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunA0 ; - } - else /*For IXP42X B0 or IXP46X silicon*/ - { - if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixQMgrOrigB0Dispatcher) - { - /* Default for IXP42X B0 and IXP46X silicon */ - *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0; - } - else - { - /* FeatureCtrl indicated that livelock dispatcher be used */ - *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0LLP; - } - } -} - -void -ixQMgrDispatcherLoopRunA0 (IxQMgrDispatchGroup group) -{ - UINT32 intRegVal; /* Interrupt reg val */ - UINT32 intRegValAfterWrite; /* Interrupt reg val after writing back */ - UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ - UINT32 qStatusWordsB4Write[MAX_Q_STATUS_WORDS]; /* Status b4 interrupt write */ - UINT32 qStatusWordsAfterWrite[MAX_Q_STATUS_WORDS]; /* Status after interrupt write */ - IxQMgrQInfo *currDispatchQInfo; - BOOL statusChangeFlag; - - int priorityTableIndex;/* Priority table index */ - int qIndex; /* Current queue being processed */ - int endIndex; /* Index of last queue to process */ - -#ifndef NDEBUG - IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || - (group == IX_QMGR_QUELOW_GROUP)); -#endif - - /* Read Q status registers before interrupt status read/write */ - ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsB4Write); - - /* Read the interrupt register */ - ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); - - /* No bit set : nothing to process (the reaminder of the algorithm is - * based on the fact that the interrupt register value contains at - * least one bit set - */ - if (intRegVal == 0) - { -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.loopRunCnt++; -#endif - - /* Rebuild the priority table if needed */ - if (rebuildTable) - { - ixQMgrDispatcherReBuildPriorityTable (); - } - - return; - } - - /* Write it back to clear the interrupt */ - ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); - - /* Read Q status registers after interrupt status read/write */ - ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsAfterWrite); - - /* get the first queue Id from the interrupt register value */ - qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); - - /* check if any change occured during hw register modifications */ - if (IX_QMGR_QUELOW_GROUP == group) - { - statusChangeFlag = - (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]) || - (qStatusWordsB4Write[1] != qStatusWordsAfterWrite[1]) || - (qStatusWordsB4Write[2] != qStatusWordsAfterWrite[2]) || - (qStatusWordsB4Write[3] != qStatusWordsAfterWrite[3]); - } - else - { - statusChangeFlag = - (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]); - /* Set the queue range based on the queue group to proccess */ - qIndex += IX_QMGR_MIN_QUEUPP_QID; - } - - if (statusChangeFlag == FALSE) - { - /* check if the interrupt register contains - * only 1 bit set (happy day scenario) - */ - currDispatchQInfo = &dispatchQInfo[qIndex]; - if (intRegVal == currDispatchQInfo->intRegCheckMask) - { - /* only 1 queue event triggered a notification * - * Call the callback function for this queue - */ - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - } - else - { - /* the event is triggered by more than 1 queue, - * the queue search will be starting from the beginning - * or the middle of the priority table - * - * the serach will end when all the bits of the interrupt - * register are cleared. There is no need to maintain - * a seperate value and test it at each iteration. - */ - if (IX_QMGR_QUELOW_GROUP == group) - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & lowPriorityTableFirstHalfMask) - { - priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; - } - } - else - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & uppPriorityTableFirstHalfMask) - { - priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; - } - } - - /* iterate following the priority table until all the bits - * of the interrupt register are cleared. - */ - do - { - qIndex = priorityTable[priorityTableIndex++]; - currDispatchQInfo = &dispatchQInfo[qIndex]; - intRegCheckMask = currDispatchQInfo->intRegCheckMask; - - /* If this queue caused this interrupt to be raised */ - if (intRegVal & intRegCheckMask) - { - /* Call the callback function for this queue */ - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - - /* Clear the interrupt register bit */ - intRegVal &= ~intRegCheckMask; - } - } - while(intRegVal); - } - } - else - { - /* A change in queue status occured during the hw interrupt - * register update. To maintain the interrupt consistency, it - * is necessary to iterate through all queues of the queue group. - */ - - /* Read interrupt status again */ - ixQMgrAqmIfQInterruptRegRead (group, &intRegValAfterWrite); - - if (IX_QMGR_QUELOW_GROUP == group) - { - priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; - endIndex = IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; - endIndex = IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX; - } - - for ( ; priorityTableIndex<=endIndex; priorityTableIndex++) - { - qIndex = priorityTable[priorityTableIndex]; - currDispatchQInfo = &dispatchQInfo[qIndex]; - intRegCheckMask = currDispatchQInfo->intRegCheckMask; - - /* If this queue caused this interrupt to be raised */ - if (intRegVal & intRegCheckMask) - { - /* Call the callback function for this queue */ - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - - } /* if (intRegVal .. */ - - /* - * If interrupt bit is set in intRegValAfterWrite don't - * proceed as this will be caught in next interrupt - */ - else if ((intRegValAfterWrite & intRegCheckMask) == 0) - { - /* Check if an interrupt was lost for this Q */ - if (ixQMgrAqmIfQStatusCheck(qStatusWordsB4Write, - qStatusWordsAfterWrite, - currDispatchQInfo->statusWordOffset, - currDispatchQInfo->statusCheckValue, - currDispatchQInfo->statusMask)) - { - /* Call the callback function for this queue */ - currDispatchQInfo->callback (qIndex, - dispatchQInfo[qIndex].callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; - dispatcherStats.queueStats[qIndex].intLostCallbackCnt++; -#endif - } /* if ixQMgrAqmIfQStatusCheck(.. */ - } /* else if ((intRegValAfterWrite ... */ - } /* for (priorityTableIndex=0 ... */ - } - - /* Rebuild the priority table if needed */ - if (rebuildTable) - { - ixQMgrDispatcherReBuildPriorityTable (); - } - -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.loopRunCnt++; -#endif -} - - - -void -ixQMgrDispatcherLoopRunB0 (IxQMgrDispatchGroup group) -{ - UINT32 intRegVal; /* Interrupt reg val */ - UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ - IxQMgrQInfo *currDispatchQInfo; - - - int priorityTableIndex; /* Priority table index */ - int qIndex; /* Current queue being processed */ - -#ifndef NDEBUG - IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || - (group == IX_QMGR_QUELOW_GROUP)); - IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || - (group == IX_QMGR_QUELOW_GROUP)); -#endif - - /* Read the interrupt register */ - ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); - - - /* No queue has interrupt register set */ - if (intRegVal != 0) - { - - /* Write it back to clear the interrupt */ - ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); - - /* get the first queue Id from the interrupt register value */ - qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); - - if (IX_QMGR_QUEUPP_GROUP == group) - { - /* Set the queue range based on the queue group to proccess */ - qIndex += IX_QMGR_MIN_QUEUPP_QID; - } - - /* check if the interrupt register contains - * only 1 bit set - * For example: - * intRegVal = 0x0010 - * currDispatchQInfo->intRegCheckMask = 0x0010 - * intRegVal == currDispatchQInfo->intRegCheckMask is TRUE. - */ - currDispatchQInfo = &dispatchQInfo[qIndex]; - if (intRegVal == currDispatchQInfo->intRegCheckMask) - { - /* only 1 queue event triggered a notification * - * Call the callback function for this queue - */ - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - } - else - { - /* the event is triggered by more than 1 queue, - * the queue search will be starting from the beginning - * or the middle of the priority table - * - * the serach will end when all the bits of the interrupt - * register are cleared. There is no need to maintain - * a seperate value and test it at each iteration. - */ - if (IX_QMGR_QUELOW_GROUP == group) - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & lowPriorityTableFirstHalfMask) - { - priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; - } - } - else - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & uppPriorityTableFirstHalfMask) - { - priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; - } - } - - /* iterate following the priority table until all the bits - * of the interrupt register are cleared. - */ - do - { - qIndex = priorityTable[priorityTableIndex++]; - currDispatchQInfo = &dispatchQInfo[qIndex]; - intRegCheckMask = currDispatchQInfo->intRegCheckMask; - - /* If this queue caused this interrupt to be raised */ - if (intRegVal & intRegCheckMask) - { - /* Call the callback function for this queue */ - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - - /* Clear the interrupt register bit */ - intRegVal &= ~intRegCheckMask; - } - } - while(intRegVal); - } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */ - } /* End of intRegVal != 0 */ - -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.loopRunCnt++; -#endif - - /* Rebuild the priority table if needed */ - if (rebuildTable) - { - ixQMgrDispatcherReBuildPriorityTable (); - } -} - -void -ixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group) -{ - UINT32 intRegVal =0; /* Interrupt reg val */ - UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ - IxQMgrQInfo *currDispatchQInfo; - - int priorityTableIndex; /* Priority table index */ - int qIndex; /* Current queue being processed */ - - UINT32 intRegValCopy = 0; - UINT32 intEnableRegVal = 0; - UINT8 i = 0; - -#ifndef NDEBUG - IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || - (group == IX_QMGR_QUELOW_GROUP)); -#endif - - /* Read the interrupt register */ - ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); - - /* - * mask any interrupts that are not enabled - */ - ixQMgrAqmIfQInterruptEnableRegRead (group, &intEnableRegVal); - intRegVal &= intEnableRegVal; - - /* No queue has interrupt register set */ - if (intRegVal != 0) - { - if (IX_QMGR_QUELOW_GROUP == group) - { - /* - * As the sticky bit is set, the interrupt register will - * not clear if write back at this point because the condition - * has not been cleared. Take a copy and write back later after - * the condition has been cleared - */ - intRegValCopy = intRegVal; - } - else - { - /* no sticky for upper Q's, so write back now */ - ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); - } - - /* get the first queue Id from the interrupt register value */ - qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); - - if (IX_QMGR_QUEUPP_GROUP == group) - { - /* Set the queue range based on the queue group to proccess */ - qIndex += IX_QMGR_MIN_QUEUPP_QID; - } - - /* check if the interrupt register contains - * only 1 bit set - * For example: - * intRegVal = 0x0010 - * currDispatchQInfo->intRegCheckMask = 0x0010 - * intRegVal == currDispatchQInfo->intRegCheckMask is TRUE. - */ - currDispatchQInfo = &dispatchQInfo[qIndex]; - if (intRegVal == currDispatchQInfo->intRegCheckMask) - { - - /* - * check if Q type periodic - only lower queues can - * have there type set to periodic - */ - if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex]) - { - /* - * Disable the notifications on any sporadics - */ - for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) - { - if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i]) - { - ixQMgrNotificationDisable(i); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[i].disableCount++; -#endif - } - } - } - - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - } - else - { - /* the event is triggered by more than 1 queue, - * the queue search will be starting from the beginning - * or the middle of the priority table - * - * the serach will end when all the bits of the interrupt - * register are cleared. There is no need to maintain - * a seperate value and test it at each iteration. - */ - if (IX_QMGR_QUELOW_GROUP == group) - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & lowPriorityTableFirstHalfMask) - { - priorityTableIndex = - IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = - IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; - } - } - else - { - /* check if any bit related to queues in the first - * half of the priority table is set - */ - if (intRegVal & uppPriorityTableFirstHalfMask) - { - priorityTableIndex = - IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; - } - else - { - priorityTableIndex = - IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; - } - } - - /* iterate following the priority table until all the bits - * of the interrupt register are cleared. - */ - do - { - qIndex = priorityTable[priorityTableIndex++]; - currDispatchQInfo = &dispatchQInfo[qIndex]; - intRegCheckMask = currDispatchQInfo->intRegCheckMask; - - /* If this queue caused this interrupt to be raised */ - if (intRegVal & intRegCheckMask) - { - /* - * check if Q type periodic - only lower queues can - * have there type set to periodic. There can only be one - * periodic queue, so the sporadics are only disabled once. - */ - if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex]) - { - /* - * Disable the notifications on any sporadics - */ - for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) - { - if (IX_QMGR_TYPE_REALTIME_SPORADIC == - ixQMgrQTypes[i]) - { - ixQMgrNotificationDisable(i); - /* - * remove from intRegVal as we don't want - * to service any sporadics now - */ - intRegVal &= ~dispatchQInfo[i].intRegCheckMask; -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[i].disableCount++; -#endif - } - } - } - - currDispatchQInfo->callback (qIndex, - currDispatchQInfo->callbackId); -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.queueStats[qIndex].callbackCnt++; -#endif - /* Clear the interrupt register bit */ - intRegVal &= ~intRegCheckMask; - } - } - while(intRegVal); - } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */ - } /* End of intRegVal != 0 */ - -#ifndef NDEBUG - /* Update statistics */ - dispatcherStats.loopRunCnt++; -#endif - - if ((intRegValCopy != 0) && (IX_QMGR_QUELOW_GROUP == group)) - { - /* - * lower groups (therefore sticky) AND at least one enabled interrupt - * Write back to clear the interrupt - */ - ixQMgrAqmIfQInterruptRegWrite (IX_QMGR_QUELOW_GROUP, intRegValCopy); - } - - /* Rebuild the priority table if needed */ - if (rebuildTable) - { - ixQMgrDispatcherReBuildPriorityTable (); - } -} - -PRIVATE void -ixQMgrDispatcherReBuildPriorityTable (void) -{ - UINT32 qIndex; - UINT32 priority; - int lowQuePriorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; - int uppQuePriorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; - - /* Reset the rebuild flag */ - rebuildTable = FALSE; - - /* initialize the mak used to identify the queues in the first half - * of the priority table - */ - lowPriorityTableFirstHalfMask = 0; - uppPriorityTableFirstHalfMask = 0; - - /* For each priority level */ - for(priority=0; priority dummyCallback: qId (%d), callbackId (%d)\n",qId,cbId); - } - dispatchQInfo[qId].dummyCallbackCount++; - -#ifndef NDEBUG - /* Update statistcs */ - dispatcherStats.queueStats[qId].intNoCallbackCnt++; -#endif -} -void -ixQMgrLLPShow (int resetStats) -{ -#ifndef NDEBUG - UINT8 i = 0; - UINT32 intEnableRegVal = 0; - - printf ("Livelock statistics are printed on the fly.\n"); - printf ("qId Type EnableCnt DisableCnt IntEnableState Callbacks\n"); - printf ("=== ======== ========= ========== ============== =========\n"); - - for (i=0; i<= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) - { - if (ixQMgrQTypes[i] != IX_QMGR_TYPE_REALTIME_OTHER) - { - printf (" %2d ", i); - - if (ixQMgrQTypes[i] == IX_QMGR_TYPE_REALTIME_SPORADIC) - { - printf ("Sporadic"); - } - else - { - printf ("Periodic"); - } - - - ixQMgrAqmIfQInterruptEnableRegRead (IX_QMGR_QUELOW_GROUP, - &intEnableRegVal); - - - intEnableRegVal &= dispatchQInfo[i].intRegCheckMask; - intEnableRegVal = intEnableRegVal >> i; - - printf (" %10d %10d %10d %10d\n", - dispatcherStats.queueStats[i].enableCount, - dispatcherStats.queueStats[i].disableCount, - intEnableRegVal, - dispatcherStats.queueStats[i].callbackCnt); - - if (resetStats) - { - dispatcherStats.queueStats[i].enableCount = - dispatcherStats.queueStats[i].disableCount = - dispatcherStats.queueStats[i].callbackCnt = 0; - } - } - } -#else - IX_QMGR_LOG0("Livelock Prevention statistics are only collected in debug mode\n"); -#endif -} - -void -ixQMgrPeriodicDone (void) -{ - UINT32 i = 0; - UINT32 ixQMgrLockKey = 0; - - /* - * for the lower queues - */ - for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) - { - /* - * check for sporadics - */ - if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i]) - { - /* - * enable any sporadics - */ - ixQMgrLockKey = ixOsalIrqLock(); - ixQMgrAqmIfQInterruptEnable(i); - ixOsalIrqUnlock(ixQMgrLockKey); -#ifndef NDEBUG - /* - * Update statistics - */ - dispatcherStats.queueStats[i].enableCount++; - dispatcherStats.queueStats[i].notificationEnabled = TRUE; -#endif - } - } -} -IX_STATUS -ixQMgrCallbackTypeSet (IxQMgrQId qId, - IxQMgrType type) -{ - UINT32 ixQMgrLockKey = 0; - IxQMgrType ixQMgrOldType =0; - -#ifndef NDEBUG - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - if (qId >= IX_QMGR_MIN_QUEUPP_QID) - { - return IX_QMGR_PARAMETER_ERROR; - } - if(!IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type)) - { - return IX_QMGR_PARAMETER_ERROR; - } -#endif - - ixQMgrOldType = ixQMgrQTypes[qId]; - ixQMgrQTypes[qId] = type; - - /* - * check if Q has been changed from type SPORADIC - */ - if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrOldType) - { - /* - * previously Q was a SPORADIC, this means that LLP - * might have had it disabled. enable it now. - */ - ixQMgrLockKey = ixOsalIrqLock(); - ixQMgrAqmIfQInterruptEnable(qId); - ixOsalIrqUnlock(ixQMgrLockKey); - -#ifndef NDEBUG - /* - * Update statistics - */ - dispatcherStats.queueStats[qId].enableCount++; -#endif - } - - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrCallbackTypeGet (IxQMgrQId qId, - IxQMgrType *type) -{ -#ifndef NDEBUG - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - if (qId >= IX_QMGR_MIN_QUEUPP_QID) - { - return IX_QMGR_PARAMETER_ERROR; - } - if(type == NULL) - { - return IX_QMGR_PARAMETER_ERROR; - } -#endif - - *type = ixQMgrQTypes[qId]; - return IX_SUCCESS; -} diff --git a/arch/arm/cpu/ixp/npe/IxQMgrInit.c b/arch/arm/cpu/ixp/npe/IxQMgrInit.c deleted file mode 100644 index b00c22d..0000000 --- a/arch/arm/cpu/ixp/npe/IxQMgrInit.c +++ /dev/null @@ -1,233 +0,0 @@ -/** - * @file IxQMgrInit.c - * - * @author Intel Corporation - * @date 30-Oct-2001 - * - * @brief: Provided initialization of the QMgr component and its subcomponents. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * System defined include files. - */ - -/* - * User defined include files. - */ -#include "IxOsal.h" -#include "IxQMgr.h" -#include "IxQMgrQCfg_p.h" -#include "IxQMgrDispatcher_p.h" -#include "IxQMgrLog_p.h" -#include "IxQMgrQAccess_p.h" -#include "IxQMgrDefines_p.h" -#include "IxQMgrAqmIf_p.h" - -/* - * Set to true if initialized - * N.B. global so integration/unit tests can reinitialize - */ -BOOL qMgrIsInitialized = FALSE; - -/* - * Function definitions. - */ -IX_STATUS -ixQMgrInit (void) -{ - if (qMgrIsInitialized) - { - IX_QMGR_LOG0("ixQMgrInit: IxQMgr already initialised\n"); - return IX_FAIL; - } - - /* Initialise the QCfg component */ - ixQMgrQCfgInit (); - - /* Initialise the Dispatcher component */ - ixQMgrDispatcherInit (); - - /* Initialise the Access component */ - ixQMgrQAccessInit (); - - /* Initialization complete */ - qMgrIsInitialized = TRUE; - - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrUnload (void) -{ - if (!qMgrIsInitialized) - { - return IX_FAIL; - } - - /* Uninitialise the QCfg component */ - ixQMgrQCfgUninit (); - - /* Uninitialization complete */ - qMgrIsInitialized = FALSE; - - return IX_SUCCESS; -} - -void -ixQMgrShow (void) -{ - IxQMgrQCfgStats *qCfgStats = NULL; - IxQMgrDispatcherStats *dispatcherStats = NULL; - int i; - UINT32 lowIntRegRead, upIntRegRead; - - qCfgStats = ixQMgrQCfgStatsGet (); - dispatcherStats = ixQMgrDispatcherStatsGet (); - ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUELOW_GROUP, &lowIntRegRead); - ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUEUPP_GROUP, &upIntRegRead); - printf("Generic Stats........\n"); - printf("=====================\n"); - printf("Loop Run Count..........%u\n",dispatcherStats->loopRunCnt); - printf("Watermark set count.....%d\n", qCfgStats->wmSetCnt); - printf("===========================================\n"); - printf("On the fly Interrupt Register Stats........\n"); - printf("===========================================\n"); - printf("Lower Interrupt Register............0x%08x\n",lowIntRegRead); - printf("Upper Interrupt Register............0x%08x\n",upIntRegRead); - printf("==============================================\n"); - printf("Queue Specific Stats........\n"); - printf("============================\n"); - - for (i=0; iqStats[qId].qName); - printf(" Size in words............ %u\n", qCfgStats->qStats[qId].qSizeInWords); - printf(" Entry size in words...... %u\n", qCfgStats->qStats[qId].qEntrySizeInWords); - printf(" Nearly empty watermark... %u\n", qCfgStats->qStats[qId].ne); - printf(" Nearly full watermark.... %u\n", qCfgStats->qStats[qId].nf); - printf(" Number of full entries... %u\n", qCfgStats->qStats[qId].numEntries); - printf(" Sram base address........ 0x%X\n", qCfgStats->qStats[qId].baseAddress); - printf(" Read pointer............. 0x%X\n", qCfgStats->qStats[qId].readPtr); - printf(" Write pointer............ 0x%X\n", qCfgStats->qStats[qId].writePtr); - -#ifndef NDEBUG - if (dispatcherStats->queueStats[qId].notificationEnabled) - { - char *localEvent = "none ????"; - switch (dispatcherStats->queueStats[qId].srcSel) - { - case IX_QMGR_Q_SOURCE_ID_E: - localEvent = "Empty"; - break; - case IX_QMGR_Q_SOURCE_ID_NE: - localEvent = "Nearly Empty"; - break; - case IX_QMGR_Q_SOURCE_ID_NF: - localEvent = "Nearly Full"; - break; - case IX_QMGR_Q_SOURCE_ID_F: - localEvent = "Full"; - break; - case IX_QMGR_Q_SOURCE_ID_NOT_E: - localEvent = "Not Empty"; - break; - case IX_QMGR_Q_SOURCE_ID_NOT_NE: - localEvent = "Not Nearly Empty"; - break; - case IX_QMGR_Q_SOURCE_ID_NOT_NF: - localEvent = "Not Nearly Full"; - break; - case IX_QMGR_Q_SOURCE_ID_NOT_F: - localEvent = "Not Full"; - break; - default : - break; - } - printf(" Notifications localEvent...... %s\n", localEvent); - } - else - { - printf(" Notifications............ not enabled\n"); - } - printf(" IxQMgrDispatcher Stats\n"); - printf(" Callback count................%d\n", - dispatcherStats->queueStats[qId].callbackCnt); - printf(" Priority change count.........%d\n", - dispatcherStats->queueStats[qId].priorityChangeCnt); - printf(" Interrupt no callback count...%d\n", - dispatcherStats->queueStats[qId].intNoCallbackCnt); - printf(" Interrupt lost callback count...%d\n", - dispatcherStats->queueStats[qId].intLostCallbackCnt); -#endif - - return IX_SUCCESS; -} - - - - diff --git a/arch/arm/cpu/ixp/npe/IxQMgrQAccess.c b/arch/arm/cpu/ixp/npe/IxQMgrQAccess.c deleted file mode 100644 index 8885736..0000000 --- a/arch/arm/cpu/ixp/npe/IxQMgrQAccess.c +++ /dev/null @@ -1,796 +0,0 @@ -/** - * @file IxQMgrQAccess.c - * - * @author Intel Corporation - * @date 30-Oct-2001 - * - * @brief This file contains functions for putting entries on a queue and - * removing entries from a queue. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * Inlines are compiled as function when this is defined. - * N.B. Must be placed before #include of "IxQMgr.h" - */ -#ifndef IXQMGR_H -# define IXQMGRQACCESS_C -#else -# error -#endif - -/* - * System defined include files. - */ - -/* - * User defined include files. - */ -#include "IxQMgr.h" -#include "IxQMgrAqmIf_p.h" -#include "IxQMgrQAccess_p.h" -#include "IxQMgrQCfg_p.h" -#include "IxQMgrDefines_p.h" - -/* - * Global variables and extern definitions - */ -extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; - -/* - * Function definitions. - */ -void -ixQMgrQAccessInit (void) -{ -} - -IX_STATUS -ixQMgrQReadWithChecks (IxQMgrQId qId, - UINT32 *entry) -{ - IxQMgrQEntrySizeInWords entrySizeInWords; - IxQMgrQInlinedReadWriteInfo *infoPtr; - - if (NULL == entry) - { - return IX_QMGR_PARAMETER_ERROR; - } - - /* Check QId */ - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - - /* Get the q entry size in words */ - entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId); - - ixQMgrAqmIfQPop (qId, entrySizeInWords, entry); - - /* reset the current read count if the counter wrapped around - * (unsigned arithmetic) - */ - infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; - if (infoPtr->qReadCount-- > infoPtr->qSizeInEntries) - { - infoPtr->qReadCount = 0; - } - - /* Check if underflow occurred on the read */ - if (ixQMgrAqmIfUnderflowCheck (qId)) - { - return IX_QMGR_Q_UNDERFLOW; - } - - return IX_SUCCESS; -} - -/* this function reads the remaining of the q entry - * for queues configured with many words. - * (the first word of the entry is already read - * in the inlined function and the entry pointer already - * incremented - */ -IX_STATUS -ixQMgrQReadMWordsMinus1 (IxQMgrQId qId, - UINT32 *entry) -{ - IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; - UINT32 entrySize = infoPtr->qEntrySizeInWords; - volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; - - while (--entrySize) - { - /* read the entry and accumulate the result */ - *(++entry) = IX_OSAL_READ_LONG(++qAccRegAddr); - } - /* underflow is available for lower queues only */ - if (qId < IX_QMGR_MIN_QUEUPP_QID) - { - /* get the queue status */ - UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); - - /* check the underflow status */ - if (status & infoPtr->qUflowStatBitMask) - { - /* the queue is empty - * clear the underflow status bit if it was set - */ - IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, - status & ~infoPtr->qUflowStatBitMask); - return IX_QMGR_Q_UNDERFLOW; - } - } - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrQWriteWithChecks (IxQMgrQId qId, - UINT32 *entry) -{ - IxQMgrQEntrySizeInWords entrySizeInWords; - IxQMgrQInlinedReadWriteInfo *infoPtr; - - if (NULL == entry) - { - return IX_QMGR_PARAMETER_ERROR; - } - - /* Check QId */ - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - - /* Get the q entry size in words */ - entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId); - - ixQMgrAqmIfQPush (qId, entrySizeInWords, entry); - - /* reset the current read count if the counter wrapped around - * (unsigned arithmetic) - */ - infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; - if (infoPtr->qWriteCount++ >= infoPtr->qSizeInEntries) - { - infoPtr->qWriteCount = infoPtr->qSizeInEntries; - } - - /* Check if overflow occurred on the write*/ - if (ixQMgrAqmIfOverflowCheck (qId)) - { - return IX_QMGR_Q_OVERFLOW; - } - - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrQPeek (IxQMgrQId qId, - unsigned int entryIndex, - UINT32 *entry) -{ - unsigned int numEntries; - -#ifndef NDEBUG - if ((NULL == entry) || (entryIndex >= IX_QMGR_Q_SIZE_INVALID)) - { - return IX_QMGR_PARAMETER_ERROR; - } - - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } -#endif - - if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries)) - { - return IX_FAIL; - } - - if (entryIndex >= numEntries) /* entryIndex starts at 0 */ - { - return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS; - } - - return ixQMgrAqmIfQPeek (qId, entryIndex, entry); -} - -IX_STATUS -ixQMgrQPoke (IxQMgrQId qId, - unsigned entryIndex, - UINT32 *entry) -{ - unsigned int numEntries; - -#ifndef NDEBUG - if ((NULL == entry) || (entryIndex > 128)) - { - return IX_QMGR_PARAMETER_ERROR; - } - - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } -#endif - - if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries)) - { - return IX_FAIL; - } - - if (numEntries < (entryIndex + 1)) /* entryIndex starts at 0 */ - { - return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS; - } - - return ixQMgrAqmIfQPoke (qId, entryIndex, entry); -} - -IX_STATUS -ixQMgrQStatusGetWithChecks (IxQMgrQId qId, - IxQMgrQStatus *qStatus) -{ - if (NULL == qStatus) - { - return IX_QMGR_PARAMETER_ERROR; - } - - if (!ixQMgrQIsConfigured (qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - - ixQMgrAqmIfQueStatRead (qId, qStatus); - - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrQNumEntriesGet (IxQMgrQId qId, - unsigned *numEntriesPtr) -{ - UINT32 qPtrs; - UINT32 qStatus; - unsigned numEntries; - IxQMgrQInlinedReadWriteInfo *infoPtr; - - -#ifndef NDEBUG - if (NULL == numEntriesPtr) - { - return IX_QMGR_PARAMETER_ERROR; - } - - /* Check QId */ - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } -#endif - - /* get fast access data */ - infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; - - /* get snapshot */ - qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr); - - /* Mod subtraction of pointers to get number of words in Q. */ - numEntries = (qPtrs - (qPtrs >> 7)) & 0x7f; - - if (numEntries == 0) - { - /* - * Could mean either full or empty queue - * so look at status - */ - ixQMgrAqmIfQueStatRead (qId, &qStatus); - - if (qId < IX_QMGR_MIN_QUEUPP_QID) - { - if (qStatus & IX_QMGR_Q_STATUS_E_BIT_MASK) - { - /* Empty */ - *numEntriesPtr = 0; - } - else if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK) - { - /* Full */ - *numEntriesPtr = infoPtr->qSizeInEntries; - } - else - { - /* - * Queue status and read/write pointers are volatile. - * The queue state has changed since we took the - * snapshot of the read and write pointers. - * Client can retry if they wish - */ - *numEntriesPtr = 0; - return IX_QMGR_WARNING; - } - } - else /* It is an upper queue which does not have an empty status bit maintained */ - { - if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK) - { - /* The queue is Full at the time of snapshot. */ - *numEntriesPtr = infoPtr->qSizeInEntries; - } - else - { - /* The queue is either empty, either moving, - * Client can retry if they wish - */ - *numEntriesPtr = 0; - return IX_QMGR_WARNING; - } - } - } - else - { - *numEntriesPtr = (numEntries / infoPtr->qEntrySizeInWords) & (infoPtr->qSizeInEntries - 1); - } - - return IX_SUCCESS; -} - -#if defined(__wince) && defined(NO_INLINE_APIS) - -PUBLIC IX_STATUS -ixQMgrQRead (IxQMgrQId qId, - UINT32 *entryPtr) -{ - extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; - IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; - UINT32 entry, entrySize; - - /* get a new entry */ - entrySize = infoPtr->qEntrySizeInWords; - entry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr); - - if (entrySize != IX_QMGR_Q_ENTRY_SIZE1) - { - *entryPtr = entry; - /* process the remaining part of the entry */ - return ixQMgrQReadMWordsMinus1(qId, entryPtr); - } - - /* underflow is available for lower queues only */ - if (qId < IX_QMGR_MIN_QUEUPP_QID) - { - /* the counter of queue entries is decremented. In happy - * day scenario there are many entries in the queue - * and the counter does not reach zero. - */ - if (infoPtr->qReadCount-- == 0) - { - /* There is maybe no entry in the queue - * qReadCount is now negative, but will be corrected before - * the function returns. - */ - UINT32 qPtrs; /* queue internal pointers */ - - /* when a queue is empty, the hw guarantees to return - * a null value. If the value is not null, the queue is - * not empty. - */ - if (entry == 0) - { - /* get the queue status */ - UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); - - /* check the underflow status */ - if (status & infoPtr->qUflowStatBitMask) - { - /* the queue is empty - * clear the underflow status bit if it was set - */ - IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, - status & ~infoPtr->qUflowStatBitMask); - *entryPtr = 0; - infoPtr->qReadCount = 0; - return IX_QMGR_Q_UNDERFLOW; - } - } - /* store the result */ - *entryPtr = entry; - - /* No underflow occured : someone is filling the queue - * or the queue contains null entries. - * The current counter needs to be - * updated from the current number of entries in the queue - */ - - /* get snapshot of queue pointers */ - qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr); - - /* Mod subtraction of pointers to get number of words in Q. */ - qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f; - - if (qPtrs == 0) - { - /* no entry in the queue */ - infoPtr->qReadCount = 0; - } - else - { - /* convert the number of words inside the queue - * to a number of entries - */ - infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1); - } - return IX_SUCCESS; - } - } - *entryPtr = entry; - return IX_SUCCESS; -} - -PUBLIC IX_STATUS -ixQMgrQBurstRead (IxQMgrQId qId, - UINT32 numEntries, - UINT32 *entries) -{ - extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; - IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; - UINT32 nullCheckEntry; - - if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1) - { - volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; - - /* the code is optimized to take care of data dependencies: - * Durig a read, there are a few cycles needed to get the - * read complete. During these cycles, it is poossible to - * do some CPU, e.g. increment pointers and decrement - * counters. - */ - - /* fetch a queue entry */ - nullCheckEntry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr); - - /* iterate the specified number of queue entries */ - while (--numEntries) - { - /* check the result of the previous read */ - if (nullCheckEntry == 0) - { - /* if we read a NULL entry, stop. We have underflowed */ - break; - } - else - { - /* write the entry */ - *entries = nullCheckEntry; - /* fetch next entry */ - nullCheckEntry = IX_OSAL_READ_LONG(qAccRegAddr); - /* increment the write address */ - entries++; - } - } - /* write the pre-fetched entry */ - *entries = nullCheckEntry; - } - else - { - IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords; - /* read the specified number of queue entries */ - nullCheckEntry = 0; - while (numEntries--) - { - int i; - - for (i = 0; i < entrySizeInWords; i++) - { - *entries = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr + i); - nullCheckEntry |= *entries++; - } - - /* if we read a NULL entry, stop. We have underflowed */ - if (nullCheckEntry == 0) - { - break; - } - nullCheckEntry = 0; - } - } - - /* reset the current read count : next access to the read function - * will force a underflow status check - */ - infoPtr->qWriteCount = 0; - - /* Check if underflow occurred on the read */ - if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID) - { - /* get the queue status */ - UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); - - if (status & infoPtr->qUflowStatBitMask) - { - /* clear the underflow status bit if it was set */ - IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, - status & ~infoPtr->qUflowStatBitMask); - return IX_QMGR_Q_UNDERFLOW; - } - } - - return IX_SUCCESS; -} - -PUBLIC IX_STATUS -ixQMgrQWrite (IxQMgrQId qId, - UINT32 *entry) -{ - extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; - IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; - UINT32 entrySize; - - /* write the entry */ - IX_OSAL_WRITE_LONG(infoPtr->qAccRegAddr, *entry); - entrySize = infoPtr->qEntrySizeInWords; - - if (entrySize != IX_QMGR_Q_ENTRY_SIZE1) - { - /* process the remaining part of the entry */ - volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; - while (--entrySize) - { - ++entry; - IX_OSAL_WRITE_LONG(++qAccRegAddr, *entry); - } - entrySize = infoPtr->qEntrySizeInWords; - } - - /* overflow is available for lower queues only */ - if (qId < IX_QMGR_MIN_QUEUPP_QID) - { - UINT32 qSize = infoPtr->qSizeInEntries; - /* increment the current number of entries in the queue - * and check for overflow - */ - if (infoPtr->qWriteCount++ == qSize) - { - /* the queue may have overflow */ - UINT32 qPtrs; /* queue internal pointers */ - - /* get the queue status */ - UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); - - /* read the status twice because the status may - * not be immediately ready after the write operation - */ - if ((status & infoPtr->qOflowStatBitMask) || - ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr)) - & infoPtr->qOflowStatBitMask)) - { - /* the queue is full, clear the overflow status - * bit if it was set - */ - IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, - status & ~infoPtr->qOflowStatBitMask); - infoPtr->qWriteCount = infoPtr->qSizeInEntries; - return IX_QMGR_Q_OVERFLOW; - } - /* No overflow occured : someone is draining the queue - * and the current counter needs to be - * updated from the current number of entries in the queue - */ - - /* get q pointer snapshot */ - qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr); - - /* Mod subtraction of pointers to get number of words in Q. */ - qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f; - - if (qPtrs == 0) - { - /* the queue may be full at the time of the - * snapshot. Next access will check - * the overflow status again. - */ - infoPtr->qWriteCount = qSize; - } - else - { - /* convert the number of words to a number of entries */ - if (entrySize == IX_QMGR_Q_ENTRY_SIZE1) - { - infoPtr->qWriteCount = qPtrs & (qSize - 1); - } - else - { - infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1); - } - } - } - } - return IX_SUCCESS; -} - -PUBLIC IX_STATUS -ixQMgrQBurstWrite (IxQMgrQId qId, - unsigned numEntries, - UINT32 *entries) -{ - extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; - IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; - UINT32 status; - - /* update the current write count */ - infoPtr->qWriteCount += numEntries; - - if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1) - { - volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; - while (numEntries--) - { - IX_OSAL_WRITE_LONG(qAccRegAddr, *entries); - entries++; - } - } - else - { - IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords; - int i; - - /* write each queue entry */ - while (numEntries--) - { - /* write the queueEntrySize number of words for each entry */ - for (i = 0; i < entrySizeInWords; i++) - { - IX_OSAL_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries); - entries++; - } - } - } - - /* check if the write count overflows */ - if (infoPtr->qWriteCount > infoPtr->qSizeInEntries) - { - /* reset the current write count */ - infoPtr->qWriteCount = infoPtr->qSizeInEntries; - } - - /* Check if overflow occurred on the write operation */ - if (qId < IX_QMGR_MIN_QUEUPP_QID) - { - /* get the queue status */ - status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); - - /* read the status twice because the status may - * not be ready at the time of the write - */ - if ((status & infoPtr->qOflowStatBitMask) || - ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr)) - & infoPtr->qOflowStatBitMask)) - { - /* clear the underflow status bit if it was set */ - IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, - status & ~infoPtr->qOflowStatBitMask); - return IX_QMGR_Q_OVERFLOW; - } - } - - return IX_SUCCESS; -} - -PUBLIC IX_STATUS -ixQMgrQStatusGet (IxQMgrQId qId, - IxQMgrQStatus *qStatus) -{ - /* read the status of a queue in the range 0-31 */ - if (qId < IX_QMGR_MIN_QUEUPP_QID) - { - extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[]; - extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[]; - extern UINT32 ixQMgrAqmIfQueLowStatBitsMask; - extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; - IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; - volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId]; - volatile UINT32 *qUOStatRegAddr = infoPtr->qUOStatRegAddr; - - UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId]; - UINT32 lowStatBitsMask = ixQMgrAqmIfQueLowStatBitsMask; - UINT32 underflowBitMask = infoPtr->qUflowStatBitMask; - UINT32 overflowBitMask = infoPtr->qOflowStatBitMask; - - /* read the status register for this queue */ - *qStatus = IX_OSAL_READ_LONG(lowStatRegAddr); - /* mask out the status bits relevant only to this queue */ - *qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask; - - /* Check if the queue has overflowed */ - if (IX_OSAL_READ_LONG(qUOStatRegAddr) & overflowBitMask) - { - /* clear the overflow status bit if it was set */ - IX_OSAL_WRITE_LONG(qUOStatRegAddr, - (IX_OSAL_READ_LONG(qUOStatRegAddr) & - ~overflowBitMask)); - *qStatus |= IX_QMGR_Q_STATUS_OF_BIT_MASK; - } - - /* Check if the queue has underflowed */ - if (IX_OSAL_READ_LONG(qUOStatRegAddr) & underflowBitMask) - { - /* clear the underflow status bit if it was set */ - IX_OSAL_WRITE_LONG(qUOStatRegAddr, - (IX_OSAL_READ_LONG(qUOStatRegAddr) & - ~underflowBitMask)); - *qStatus |= IX_QMGR_Q_STATUS_UF_BIT_MASK; - } - } - else /* read status of a queue in the range 32-63 */ - { - extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr; - extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr; - extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[]; - extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[]; - - volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr; - volatile UINT32 *qFullStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr; - int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID; - UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex]; - UINT32 qFullStatBitMask = ixQMgrAqmIfQueUppStat1BitMask[maskIndex]; - - /* Reset the status bits */ - *qStatus = 0; - - /* Check if the queue is nearly empty */ - if (IX_OSAL_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask) - { - *qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK; - } - - /* Check if the queue is full */ - if (IX_OSAL_READ_LONG(qFullStatRegAddr) & qFullStatBitMask) - { - *qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK; - } - } - return IX_SUCCESS; -} -#endif /* def NO_INLINE_APIS */ diff --git a/arch/arm/cpu/ixp/npe/IxQMgrQCfg.c b/arch/arm/cpu/ixp/npe/IxQMgrQCfg.c deleted file mode 100644 index ec7d837..0000000 --- a/arch/arm/cpu/ixp/npe/IxQMgrQCfg.c +++ /dev/null @@ -1,543 +0,0 @@ -/** - * @file QMgrQCfg.c - * - * @author Intel Corporation - * @date 30-Oct-2001 - * - * @brief This modules provides an interface for setting up the static - * configuration of AQM queues.This file contains the following - * functions: - * - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* - * System defined include files. - */ - -/* - * User defined include files. - */ -#include "IxOsal.h" -#include "IxQMgr.h" -#include "IxQMgrAqmIf_p.h" -#include "IxQMgrQCfg_p.h" -#include "IxQMgrDefines_p.h" - -/* - * #defines and macros used in this file. - */ - -#define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16 - -/* Total size of SRAM */ -#define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000 - -/* - * Check that qId is a valid queue identifier. This is provided to - * make the code easier to read. - */ -#define IX_QMGR_QID_IS_VALID(qId) \ -(((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID))) - -/* - * Typedefs whose scope is limited to this file. - */ - -/* - * This struct describes an AQM queue. - * N.b. bufferSizeInWords and qEntrySizeInWords are stored in the queue - * as these are requested by Access in the data path. sizeInEntries is - * not required by the data path so it can be calculated dynamically. - * - */ -typedef struct -{ - char qName[IX_QMGR_MAX_QNAME_LEN+1]; /* Textual description of a queue*/ - IxQMgrQSizeInWords qSizeInWords; /* The number of words in the queue */ - IxQMgrQEntrySizeInWords qEntrySizeInWords; /* Number of words per queue entry*/ - BOOL isConfigured; /* This flag is TRUE if the queue has - * been configured - */ -} IxQMgrCfgQ; - -/* - * Variable declarations global to this file. Externs are followed by - * statics. - */ - -extern UINT32 * ixQMgrAqmIfQueAccRegAddr[]; - -/* Store data required to inline read and write access - */ -IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES]; - -static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES]; - -/* This pointer holds the starting address of AQM SRAM not used by - * the AQM queues. - */ -static UINT32 freeSramAddress=0; - -/* 4 words of zeroed memory for inline access */ -static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 }; - -static BOOL cfgInitialized = FALSE; - -static IxOsalMutex ixQMgrQCfgMutex; - -/* - * Statistics - */ -static IxQMgrQCfgStats stats; - -/* - * Function declarations - */ -PRIVATE BOOL -watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level); - -PRIVATE BOOL -qSizeInWordsIsOk (IxQMgrQSizeInWords qSize); - -PRIVATE BOOL -qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize); - -/* - * Function definitions. - */ -void -ixQMgrQCfgInit (void) -{ - int loopIndex; - - for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++) - { - /* info for code inlining */ - ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder; - - /* info for code inlining */ - ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0; - ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0; - ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder; - ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder; - ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0; - ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0; - ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0; - ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0; - ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder; - } - - /* Initialise the AqmIf component */ - ixQMgrAqmIfInit (); - - /* Reset all queues to have queue name = NULL, entry size = 0 and - * isConfigured = false - */ - for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++) - { - strcpy (cfgQueueInfo[loopIndex].qName, ""); - cfgQueueInfo[loopIndex].qSizeInWords = 0; - cfgQueueInfo[loopIndex].qEntrySizeInWords = 0; - cfgQueueInfo[loopIndex].isConfigured = FALSE; - - /* Statistics */ - stats.qStats[loopIndex].isConfigured = FALSE; - stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName; - } - - /* Statistics */ - stats.wmSetCnt = 0; - - ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress); - - ixOsalMutexInit(&ixQMgrQCfgMutex); - - cfgInitialized = TRUE; -} - -void -ixQMgrQCfgUninit (void) -{ - cfgInitialized = FALSE; - - /* Uninitialise the AqmIf component */ - ixQMgrAqmIfUninit (); -} - -IX_STATUS -ixQMgrQConfig (char *qName, - IxQMgrQId qId, - IxQMgrQSizeInWords qSizeInWords, - IxQMgrQEntrySizeInWords qEntrySizeInWords) -{ - UINT32 aqmLocalBaseAddress; - - if (!cfgInitialized) - { - return IX_FAIL; - } - - if (!IX_QMGR_QID_IS_VALID(qId)) - { - return IX_QMGR_INVALID_Q_ID; - } - - else if (NULL == qName) - { - return IX_QMGR_PARAMETER_ERROR; - } - - else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN) - { - return IX_QMGR_PARAMETER_ERROR; - } - - else if (!qSizeInWordsIsOk (qSizeInWords)) - { - return IX_QMGR_INVALID_QSIZE; - } - - else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords)) - { - return IX_QMGR_INVALID_Q_ENTRY_SIZE; - } - - else if (cfgQueueInfo[qId].isConfigured) - { - return IX_QMGR_Q_ALREADY_CONFIGURED; - } - - ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER); - - /* Write the config register */ - ixQMgrAqmIfQueCfgWrite (qId, - qSizeInWords, - qEntrySizeInWords, - freeSramAddress); - - - strcpy (cfgQueueInfo[qId].qName, qName); - cfgQueueInfo[qId].qSizeInWords = qSizeInWords; - cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords; - - /* store pre-computed information in the same cache line - * to facilitate inlining of QRead and QWrite functions - * in IxQMgr.h - */ - ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0; - ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0; - ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords; - ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries = - (UINT32)qSizeInWords / (UINT32)qEntrySizeInWords; - - /* Calculate the new freeSramAddress from the size of the queue - * currently being configured. - */ - freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD); - - /* Get the virtual SRAM address */ - ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress); - - IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <= - IX_QMGR_QUE_BUFFER_SPACE_SIZE); - - /* The queue is now configured */ - cfgQueueInfo[qId].isConfigured = TRUE; - - ixOsalMutexUnlock(&ixQMgrQCfgMutex); - -#ifndef NDEBUG - /* Update statistics */ - stats.qStats[qId].isConfigured = TRUE; - stats.qStats[qId].qName = cfgQueueInfo[qId].qName; -#endif - return IX_SUCCESS; -} - -IxQMgrQSizeInWords -ixQMgrQSizeInWordsGet (IxQMgrQId qId) -{ - /* No parameter checking as this is used on the data path */ - return (cfgQueueInfo[qId].qSizeInWords); -} - -IX_STATUS -ixQMgrQSizeInEntriesGet (IxQMgrQId qId, - unsigned *qSizeInEntries) -{ - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - - if(NULL == qSizeInEntries) - { - return IX_QMGR_PARAMETER_ERROR; - } - - *qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) / - (UINT32)cfgQueueInfo[qId].qEntrySizeInWords; - - return IX_SUCCESS; -} - -IxQMgrQEntrySizeInWords -ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId) -{ - /* No parameter checking as this is used on the data path */ - return (cfgQueueInfo[qId].qEntrySizeInWords); -} - -IX_STATUS -ixQMgrWatermarkSet (IxQMgrQId qId, - IxQMgrWMLevel ne, - IxQMgrWMLevel nf) -{ - IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */ - IxQMgrQStatus qStatusOnExit; /* to this function */ - - if (!ixQMgrQIsConfigured(qId)) - { - return IX_QMGR_Q_NOT_CONFIGURED; - } - - if (!watermarkLevelIsOk (qId, ne)) - { - return IX_QMGR_INVALID_Q_WM; - } - - if (!watermarkLevelIsOk (qId, nf)) - { - return IX_QMGR_INVALID_Q_WM; - } - - /* Get the current queue status */ - ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry); - -#ifndef NDEBUG - /* Update statistics */ - stats.wmSetCnt++; -#endif - - ixQMgrAqmIfWatermarkSet (qId, - ne, - nf); - - /* Get the current queue status */ - ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit); - - /* If the status has changed return a warning */ - if (qStatusOnEntry != qStatusOnExit) - { - return IX_QMGR_WARNING; - } - - return IX_SUCCESS; -} - -IX_STATUS -ixQMgrAvailableSramAddressGet (UINT32 *address, - unsigned *sizeOfFreeRam) -{ - UINT32 aqmLocalBaseAddress; - - if ((NULL == address)||(NULL == sizeOfFreeRam)) - { - return IX_QMGR_PARAMETER_ERROR; - } - if (!cfgInitialized) - { - return IX_FAIL; - } - - *address = freeSramAddress; - - /* Get the virtual SRAM address */ - ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress); - - /* - * Calculate the size in bytes of free sram - * i.e. current free SRAM virtual pointer from - * (base + total size) - */ - *sizeOfFreeRam = - (aqmLocalBaseAddress + - IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) - - freeSramAddress; - - if (0 == *sizeOfFreeRam) - { - return IX_QMGR_NO_AVAILABLE_SRAM; - } - - return IX_SUCCESS; -} - -BOOL -ixQMgrQIsConfigured (IxQMgrQId qId) -{ - if (!IX_QMGR_QID_IS_VALID(qId)) - { - return FALSE; - } - - return cfgQueueInfo[qId].isConfigured; -} - -IxQMgrQCfgStats* -ixQMgrQCfgStatsGet (void) -{ - return &stats; -} - -IxQMgrQCfgStats* -ixQMgrQCfgQStatsGet (IxQMgrQId qId) -{ - unsigned int ne; - unsigned int nf; - UINT32 baseAddress; - UINT32 readPtr; - UINT32 writePtr; - - stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords; - stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords; - - if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries)) - { - if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries)) - { - IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId); - } - } - - ixQMgrAqmIfQueCfgRead (qId, - stats.qStats[qId].numEntries, - &baseAddress, - &ne, - &nf, - &readPtr, - &writePtr); - - stats.qStats[qId].baseAddress = baseAddress; - stats.qStats[qId].ne = ne; - stats.qStats[qId].nf = nf; - stats.qStats[qId].readPtr = readPtr; - stats.qStats[qId].writePtr = writePtr; - - return &stats; -} - -/* - * Static function definitions - */ - -PRIVATE BOOL -watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level) -{ - unsigned qSizeInEntries; - - switch (level) - { - case IX_QMGR_Q_WM_LEVEL0: - case IX_QMGR_Q_WM_LEVEL1: - case IX_QMGR_Q_WM_LEVEL2: - case IX_QMGR_Q_WM_LEVEL4: - case IX_QMGR_Q_WM_LEVEL8: - case IX_QMGR_Q_WM_LEVEL16: - case IX_QMGR_Q_WM_LEVEL32: - case IX_QMGR_Q_WM_LEVEL64: - break; - default: - return FALSE; - } - - /* Check watermark is not bigger than the qSizeInEntries */ - ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries); - - if ((unsigned)level > qSizeInEntries) - { - return FALSE; - } - - return TRUE; -} - -PRIVATE BOOL -qSizeInWordsIsOk (IxQMgrQSizeInWords qSize) -{ - BOOL status; - - switch (qSize) - { - case IX_QMGR_Q_SIZE16: - case IX_QMGR_Q_SIZE32: - case IX_QMGR_Q_SIZE64: - case IX_QMGR_Q_SIZE128: - status = TRUE; - break; - default: - status = FALSE; - break; - } - - return status; -} - -PRIVATE BOOL -qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize) -{ - BOOL status; - - switch (entrySize) - { - case IX_QMGR_Q_ENTRY_SIZE1: - case IX_QMGR_Q_ENTRY_SIZE2: - case IX_QMGR_Q_ENTRY_SIZE4: - status = TRUE; - break; - default: - status = FALSE; - break; - } - - return status; -} diff --git a/arch/arm/cpu/ixp/npe/Makefile b/arch/arm/cpu/ixp/npe/Makefile deleted file mode 100644 index 14ab3c7..0000000 --- a/arch/arm/cpu/ixp/npe/Makefile +++ /dev/null @@ -1,99 +0,0 @@ -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB := $(obj)libnpe.o - -LOCAL_CFLAGS += -I$(TOPDIR)/arch/arm/cpu/ixp/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux -CFLAGS += $(LOCAL_CFLAGS) -CPPFLAGS += $(LOCAL_CFLAGS) # needed for depend -HOSTCFLAGS += $(LOCAL_CFLAGS) - -COBJS-$(CONFIG_IXP4XX_NPE) := npe.o \ - miiphy.o \ - IxOsalBufferMgt.o \ - IxOsalIoMem.o \ - IxOsalOsCacheMMU.o \ - IxOsalOsMsgQ.o \ - IxOsalOsSemaphore.o \ - IxOsalOsServices.o \ - IxOsalOsThread.o \ - IxEthAcc.o \ - IxEthAccCommon.o \ - IxEthAccControlInterface.o \ - IxEthAccDataPlane.o \ - IxEthAccMac.o \ - IxEthAccMii.o \ - IxEthDBAPI.o \ - IxEthDBAPISupport.o \ - IxEthDBCore.o \ - IxEthDBEvents.o \ - IxEthDBFeatures.o \ - IxEthDBFirewall.o \ - IxEthDBHashtable.o \ - IxEthDBLearning.o \ - IxEthDBMem.o \ - IxEthDBNPEAdaptor.o \ - IxEthDBPortUpdate.o \ - IxEthDBReports.o \ - IxEthDBSearch.o \ - IxEthDBSpanningTree.o \ - IxEthDBUtil.o \ - IxEthDBVlan.o \ - IxEthDBWiFi.o \ - IxEthMii.o \ - IxQMgrAqmIf.o \ - IxQMgrDispatcher.o \ - IxQMgrInit.o \ - IxQMgrQAccess.o \ - IxQMgrQCfg.o \ - IxFeatureCtrl.o \ - IxNpeDl.o \ - IxNpeDlImageMgr.o \ - IxNpeDlNpeMgr.o \ - IxNpeDlNpeMgrUtils.o \ - IxNpeMh.o \ - IxNpeMhConfig.o \ - IxNpeMhReceive.o \ - IxNpeMhSend.o \ - IxNpeMhSolicitedCbMgr.o \ - IxNpeMhUnsolicitedCbMgr.o - -SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS-y)) -SOBJS := $(addprefix $(obj),$(SOBJS)) - -all: $(LIB) - -$(LIB): $(obj).depend $(OBJS) - $(call cmd_link_o_target, $(OBJS)) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/arch/arm/cpu/ixp/npe/include/IxAssert.h b/arch/arm/cpu/ixp/npe/include/IxAssert.h deleted file mode 100644 index eae8b3f..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxAssert.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file IxAssert.h - * - * @date 21-MAR-2002 (replaced by OSAL) - * - * @brief This file contains assert and ensure macros used by the IXP400 software - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @defgroup IxAssert IXP400 Assertion Macros (IxAssert) API - * - * @brief Assertion support - * - * @{ - */ - -#ifndef IXASSERT_H - -#ifndef __doxygen_HIDE -#define IXASSERT_H -#endif /* __doxygen_HIDE */ - -#include "IxOsalBackward.h" - -#endif /* IXASSERT_H */ - -/** - * @} addtogroup IxAssert - */ - - - diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmSch.h b/arch/arm/cpu/ixp/npe/include/IxAtmSch.h deleted file mode 100644 index 73c3be2..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxAtmSch.h +++ /dev/null @@ -1,504 +0,0 @@ -/** - * @file IxAtmSch.h - * - * @date 23-NOV-2001 - * - * @brief Header file for the IXP400 ATM Traffic Shaper - * - * This component demonstrates an ATM Traffic Shaper implementation. It - * will perform shaping on upto 12 ports and total of 44 VCs accross all ports, - * 32 are intended for AAL0/5 and 12 for OAM (1 per port). - * The supported traffic types are;1 rt-VBR VC where PCR = SCR. - * (Effectively CBR) and Up-to 44 VBR VCs. - * - * This component models the ATM ports and VCs and is capable of producing - * a schedule of ATM cells per port which can be supplied to IxAtmdAcc - * for execution on the data path. - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * - * @sa IxAtmm.h - * - */ - -/** - * @defgroup IxAtmSch IXP400 ATM Transmit Scheduler (IxAtmSch) API - * - * @brief IXP400 ATM scheduler component Public API - * - * @{ - */ - -#ifndef IXATMSCH_H -#define IXATMSCH_H - -#include "IxOsalTypes.h" -#include "IxAtmTypes.h" - -/* - * #defines and macros used in this file. - */ - -/* Return codes */ - -/** - * @ingroup IxAtmSch - * - * @def IX_ATMSCH_RET_NOT_ADMITTED - * @brief Indicates that CAC function has rejected VC registration due - * to insufficient line capacity. -*/ -#define IX_ATMSCH_RET_NOT_ADMITTED 2 - -/** - * @ingroup IxAtmSch - * - * @def IX_ATMSCH_RET_QUEUE_FULL - * @brief Indicates that the VC queue is full, no more demand can be - * queued at this time. - */ -#define IX_ATMSCH_RET_QUEUE_FULL 3 - -/** - * @ingroup IxAtmSch - * - * @def IX_ATMSCH_RET_QUEUE_EMPTY - * @brief Indicates that all VC queues on this port are empty and - * therefore there are no cells to be scheduled at this time. - */ -#define IX_ATMSCH_RET_QUEUE_EMPTY 4 - -/* - * Function declarations - */ - -/** - * @ingroup IxAtmSch - * - * @fn ixAtmSchInit(void) - * - * @brief This function is used to initialize the ixAtmSch component. It - * should be called before any other IxAtmSch API function. - * - * @param None - * - * @return - * - IX_SUCCESS : indicates that - * -# The ATM scheduler component has been successfully initialized. - * -# The scheduler is ready to accept Port modelling requests. - * - IX_FAIL : Some internal error has prevented the scheduler component - * from initialising. - */ -PUBLIC IX_STATUS -ixAtmSchInit(void); - -/** - * @ingroup IxAtmSch - * - * @fn ixAtmSchPortModelInitialize( IxAtmLogicalPort port, - unsigned int portRate, - unsigned int minCellsToSchedule) - * - * @brief This function shall be called first to initialize an ATM port before - * any other ixAtmSch API calls may be made for that port. - * - * @param port @ref IxAtmLogicalPort [in] - The specific port to initialize. Valid - * values range from 0 to IX_UTOPIA_MAX_PORTS - 1, representing a - * maximum of IX_UTOPIA_MAX_PORTS possible ports. - * - * @param portRate unsigned int [in] - Value indicating the upstream capacity - * of the indicated port. The value should be supplied in - * units of ATM (53 bytes) cells per second. - * A port rate of 800Kbits/s is the equivalent - * of 1886 cells per second - * - * @param minCellsToSchedule unsigned int [in] - This parameter specifies the minimum - * number of cells which the scheduler will put in a schedule - * table for this port. This value sets the worst case CDVT for VCs - * on this port i.e. CDVT = 1*minCellsToSchedule/portRate. - * @return - * - IX_SUCCESS : indicates that - * -# The ATM scheduler has been successfully initialized. - * -# The requested port model has been established. - * -# The scheduler is ready to accept VC modelling requests - * on the ATM port. - * - IX_FAIL : indicates the requested port could not be - * initialized. */ -PUBLIC IX_STATUS -ixAtmSchPortModelInitialize( IxAtmLogicalPort port, - unsigned int portRate, - unsigned int minCellsToSchedule); - -/** - * @ingroup IxAtmSch - * - * @fn ixAtmSchPortRateModify( IxAtmLogicalPort port, - unsigned int portRate) - * - * @brief This function is called to modify the portRate on a - * previously initialized port, typically in the event that - * the line condition of the port changes. - * - * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port which is to be - * modified. - * - * @param portRate unsigned int [in] - Value indicating the new upstream - * capacity for this port in cells/second. - * A port rate of 800Kbits/s is the equivalent - * of 1886 cells per second - * - * @return - * - IX_SUCCESS : The port rate has been successfully modified.
- * - IX_FAIL : The port rate could not be modified, either - * because the input data was invalid, or the new port rate is - * insufficient to support established ATM VC contracts on this - * port. - * - * @warning The IxAtmSch component will validate the supplied port - * rate is sufficient to support all established VC - * contracts on the port. If the new port rate is - * insufficient to support all established contracts then - * the request to modify the port rate will be rejected. - * In this event, the user is expected to remove - * established contracts using the ixAtmSchVcModelRemove - * interface and then retry this interface. - * - * @sa ixAtmSchVcModelRemove() */ -PUBLIC IX_STATUS -ixAtmSchPortRateModify( IxAtmLogicalPort port, - unsigned int portRate); - - -/** - * @ingroup IxAtmSch - * - * @fn ixAtmSchVcModelSetup( IxAtmLogicalPort port, - IxAtmTrafficDescriptor *trafficDesc, - IxAtmSchedulerVcId *vcId) - * - * @brief A client calls this interface to set up an upstream - * (transmitting) virtual connection model (VC) on the - * specified ATM port. This function also provides the - * virtual * connection admission control (CAC) service to the - * client. - * - * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the upstream - * VC is to be established. - * - * @param *trafficDesc @ref IxAtmTrafficDescriptor [in] - Pointer to a structure - * describing the requested traffic contract of the VC to be - * established. This structure contains the typical ATM - * traffic descriptor values (e.g. PCR, SCR, MBS, CDVT, etc.) - * defined by the ATM standard. - * - * @param *vcId @ref IxAtmSchedulerVcId [out] - This value will be filled with the - * port-unique identifier for this virtual connection. A - * valid identification is a non-negative number. - * - * @return - * - IX_SUCCESS : The VC has been successfully established on - * this port. The client may begin to submit demand on this VC. - * - IX_ATMSCH_RET_NOT_ADMITTED : The VC cannot be established - * on this port because there is insufficient upstream capacity - * available to support the requested traffic contract descriptor - * - IX_FAIL :Input data are invalid. VC has not been - * established. - */ -PUBLIC IX_STATUS -ixAtmSchVcModelSetup( IxAtmLogicalPort port, - IxAtmTrafficDescriptor *trafficDesc, - IxAtmSchedulerVcId *vcId); - -/** - * @ingroup IxAtmSch - * - * @fn ixAtmSchVcConnIdSet( IxAtmLogicalPort port, - IxAtmSchedulerVcId vcId, - IxAtmConnId vcUserConnId) - * - * @brief A client calls this interface to set the vcUserConnId for a VC on - * the specified ATM port. This vcUserConnId will default to - * IX_ATM_IDLE_CELLS_CONNID if this function is not called for a VC. - * Hence if the client does not call this function for a VC then only idle - * cells will be scheduled for this VC. - * - * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the upstream - * VC is has been established. - * - * @param vcId @ref IxAtmSchedulerVcId [in] - This is the unique identifier for this virtual - * connection. A valid identification is a non-negative number and is - * all ports. - * - * @param vcUserConnId @ref IxAtmConnId [in] - The connId is used to refer to a VC in schedule - * table entries. It is treated as the Id by which the scheduler client - * knows the VC. It is used in any communicatations from the Scheduler - * to the scheduler user e.g. schedule table entries. - * - * @return - * - IX_SUCCESS : The id has successfully been set. - * - IX_FAIL :Input data are invalid. connId id is not established. - */ -PUBLIC IX_STATUS -ixAtmSchVcConnIdSet( IxAtmLogicalPort port, - IxAtmSchedulerVcId vcId, - IxAtmConnId vcUserConnId); - -/** - * @ingroup IxAtmSch - * - * @fn ixAtmSchVcModelRemove( IxAtmLogicalPort port, - IxAtmSchedulerVcId vcId) - * - * @brief Interface called by the client to remove a previously - * established VC on a particular port. - * - * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be - * removed is established. - * - * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be removed. This is the - * value returned by the @ref ixAtmSchVcModelSetup call which - * established the relevant VC. - * - * @return - * - IX_SUCCESS : The VC has been successfully removed from - * this port. It is no longer modelled on this port. - * - IX_FAIL :Input data are invalid. The VC is still being modeled - * by the traffic shaper. - * - * @sa ixAtmSchVcModelSetup() - */ -PUBLIC IX_STATUS -ixAtmSchVcModelRemove( IxAtmLogicalPort port, - IxAtmSchedulerVcId vcId); - -/** - * @ingroup IxAtmSch - * - * @fn ixAtmSchVcQueueUpdate( IxAtmLogicalPort port, - IxAtmSchedulerVcId vcId, - unsigned int numberOfCells) - * - * @brief The client calls this function to notify IxAtmSch that the - * user of a VC has submitted cells for transmission. - * - * This information is stored, aggregated from a number of calls to - * ixAtmSchVcQueueUpdate and eventually used in the call to - * ixAtmSchTableUpdate. - * - * Normally IxAtmSch will update the VC queue by adding the number of - * cells to the current queue length. However, if IxAtmSch - * determines that the user has over-submitted for the VC and - * exceeded its transmission quota the queue request can be rejected. - * The user should resubmit the request later when the queue has been - * depleted. - * - * This implementation of ixAtmSchVcQueueUpdate uses no operating - * system or external facilities, either directly or indirectly. - * This allows clients to call this function form within an interrupt handler. - * - * This interface is structurally compatible with the - * IxAtmdAccSchQueueUpdate callback type definition required for - * IXP400 ATM scheduler interoperability. - * - * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be - * updated is established. - * - * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be updated. This is the - * value returned by the @ref ixAtmSchVcModelSetup call which - * established the relevant VC. - * - * @param numberOfCells unsigned int [in] - Indicates how many ATM cells should - * be added to the queue for this VC. - * - * @return - * - IX_SUCCESS : The VC queue has been successfully updated. - * - IX_ATMSCH_RET_QUEUE_FULL : The VC queue has reached a - * preset limit. This indicates the client has over-submitted - * and exceeded its transmission quota. The request is - * rejected. The VC queue is not updated. The VC user is - * advised to resubmit the request later. - * - IX_FAIL : The input are invalid. No VC queue is updated. - * - * @warning IxAtmSch assumes that the calling software ensures that - * calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and - * ixAtmSchTableUpdate are both self and mutually exclusive - * for the same port. - * - * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */ -PUBLIC IX_STATUS -ixAtmSchVcQueueUpdate( IxAtmLogicalPort port, - IxAtmSchedulerVcId vcId, - unsigned int numberOfCells); - -/** - * @ingroup IxAtmSch - * - * @fn ixAtmSchVcQueueClear( IxAtmLogicalPort port, - IxAtmSchedulerVcId vcId) - * - * @brief The client calls this function to remove all currently - * queued cells from a registered VC. The pending cell count - * for the specified VC is reset to zero. - * - * This interface is structurally compatible with the - * IxAtmdAccSchQueueClear callback type definition required for - * IXP400 ATM scheduler interoperability. - * - * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be - * cleared is established. - * - * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be cleared. This is the - * value returned by the @ref ixAtmSchVcModelSetup call which - * established the relevant VC. - * - * @return - * - IX_SUCCESS : The VC queue has been successfully cleared. - * - IX_FAIL : The input are invalid. No VC queue is modified. - * - * @warning IxAtmSch assumes that the calling software ensures that - * calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and - * ixAtmSchTableUpdate are both self and mutually exclusive - * for the same port. - * - * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */ -PUBLIC IX_STATUS -ixAtmSchVcQueueClear( IxAtmLogicalPort port, - IxAtmSchedulerVcId vcId); - -/** - * @ingroup IxAtmSch - * - * @fn ixAtmSchTableUpdate( IxAtmLogicalPort port, - unsigned int maxCells, - IxAtmScheduleTable **rettable) - * - * @brief The client calls this function to request an update of the - * schedule table for a particular ATM port. - * - * This is called when the client decides it needs a new sequence of - * cells to send (probably because the transmit queue is near to - * empty for this ATM port). The scheduler will use its stored - * information on the cells submitted for transmit (i.e. data - * supplied via @ref ixAtmSchVcQueueUpdate function) with the traffic - * descriptor information of all established VCs on the ATM port to - * decide the sequence of cells to be sent and fill the schedule - * table for a period of time into the future. - * - * IxAtmSch will guarantee a minimum of minCellsToSchedule if there - * is at least one cell ready to send. If there are no cells then - * IX_ATMSCH_RET_QUEUE_EMPTY is returned. - * - * This implementation of ixAtmSchTableUpdate uses no operating - * system or external facilities, either directly or indirectly. - * This allows clients to call this function form within an FIQ - * interrupt handler. - * - * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port for which requested - * schedule table is to be generated. - * - * @param maxCells unsigned [in] - Specifies the maximum number of cells - * that must be scheduled in the supplied table during any - * call to the interface. - * - * @param **table @ref IxAtmScheduleTable [out] - A pointer to an area of - * storage is returned which contains the generated - * schedule table. The client should not modify the - * contents of this table. - * - * @return - * - IX_SUCCESS : The schedule table has been published. - * Currently there is at least one VC queue that is nonempty. - * - IX_ATMSCH_RET_QUEUE_EMPTY : Currently all VC queues on - * this port are empty. The schedule table returned is set to - * NULL. The client is not expected to invoke this function - * again until more cells have been submitted on this port - * through the @ref ixAtmSchVcQueueUpdate function. - * - IX_FAIL : The input are invalid. No action is taken. - * - * @warning IxAtmSch assumes that the calling software ensures that - * calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and - * ixAtmSchTableUpdate are both self and mutually exclusive - * for the same port. - * - * @warning Subsequent calls to this function for the same port will - * overwrite the contents of previously supplied schedule - * tables. The client must be completely finished with the - * previously supplied schedule table before calling this - * function again for the same port. - * - * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */ -PUBLIC IX_STATUS -ixAtmSchTableUpdate( IxAtmLogicalPort port, - unsigned int maxCells, - IxAtmScheduleTable **rettable); - -/** - * @ingroup IxAtmSch - * - * @fn ixAtmSchShow(void) - * - * @brief Utility function which will print statistics on the current - * and accumulated state of VCs and traffic in the ATM - * scheduler component. Output is sent to the default output - * device. - * - * @param none - * @return none - */ -PUBLIC void -ixAtmSchShow(void); - -/** - * @ingroup IxAtmSch - * - * @fn ixAtmSchStatsClear(void) - * - * @brief Utility function which will reset all counter statistics in - * the ATM scheduler to zero. - * - * @param none - * @return none - */ -PUBLIC void -ixAtmSchStatsClear(void); - -#endif -/* IXATMSCH_H */ - -/** @} */ diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmTypes.h b/arch/arm/cpu/ixp/npe/include/IxAtmTypes.h deleted file mode 100644 index 8624c33..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxAtmTypes.h +++ /dev/null @@ -1,409 +0,0 @@ -/** - * @file IxAtmTypes.h - * - * @date 24-MAR-2002 - * - * @brief This file contains Atm types common to a number of Atm components. - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/* ------------------------------------------------------ - Doxygen group definitions - ------------------------------------------------------ */ -/** - * @defgroup IxAtmTypes IXP400 ATM Types (IxAtmTypes) - * - * @brief The common set of types used in many Atm components - * - * @{ */ - -#ifndef IXATMTYPES_H -#define IXATMTYPES_H - -#include "IxNpeA.h" - -/** - * @enum IxAtmLogicalPort - * - * @brief Logical Port Definitions : - * - * Only 1 port is available in SPHY configuration - * 12 ports are enabled in MPHY configuration - * - */ -typedef enum -{ - IX_UTOPIA_PORT_0 = 0, /**< Port 0 */ -#ifdef IX_NPE_MPHYMULTIPORT - IX_UTOPIA_PORT_1, /**< Port 1 */ - IX_UTOPIA_PORT_2, /**< Port 2 */ - IX_UTOPIA_PORT_3, /**< Port 3 */ - IX_UTOPIA_PORT_4, /**< Port 4 */ - IX_UTOPIA_PORT_5, /**< Port 5 */ - IX_UTOPIA_PORT_6, /**< Port 6 */ - IX_UTOPIA_PORT_7, /**< Port 7 */ - IX_UTOPIA_PORT_8, /**< Port 8 */ - IX_UTOPIA_PORT_9, /**< Port 9 */ - IX_UTOPIA_PORT_10, /**< Port 10 */ - IX_UTOPIA_PORT_11, /**< Port 11 */ -#endif /* IX_NPE_MPHY */ - IX_UTOPIA_MAX_PORTS /**< Not a port - just a definition for the - * maximum possible ports - */ -} IxAtmLogicalPort; - -/** - * @def IX_ATM_CELL_PAYLOAD_SIZE - * @brief Size of a ATM cell payload - */ -#define IX_ATM_CELL_PAYLOAD_SIZE (48) - -/** - * @def IX_ATM_CELL_SIZE - * @brief Size of a ATM cell, including header - */ -#define IX_ATM_CELL_SIZE (53) - -/** - * @def IX_ATM_CELL_SIZE_NO_HEC - * @brief Size of a ATM cell, excluding HEC byte - */ -#define IX_ATM_CELL_SIZE_NO_HEC (IX_ATM_CELL_SIZE - 1) - -/** - * @def IX_ATM_OAM_CELL_SIZE_NO_HEC - * @brief Size of a OAM cell, excluding HEC byte - */ -#define IX_ATM_OAM_CELL_SIZE_NO_HEC IX_ATM_CELL_SIZE_NO_HEC - -/** - * @def IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE - * @brief Size of a AAL0 48 Cell payload - */ -#define IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE IX_ATM_CELL_PAYLOAD_SIZE - -/** - * @def IX_ATM_AAL5_CELL_PAYLOAD_SIZE - * @brief Size of a AAL5 Cell payload - */ -#define IX_ATM_AAL5_CELL_PAYLOAD_SIZE IX_ATM_CELL_PAYLOAD_SIZE - -/** - * @def IX_ATM_AAL0_52_CELL_SIZE_NO_HEC - * @brief Size of a AAL0 52 Cell, excluding HEC byte - */ -#define IX_ATM_AAL0_52_CELL_SIZE_NO_HEC IX_ATM_CELL_SIZE_NO_HEC - - -/** - * @def IX_ATM_MAX_VPI - * @brief Maximum value of an ATM VPI - */ -#define IX_ATM_MAX_VPI 255 - -/** - * @def IX_ATM_MAX_VCI - * @brief Maximum value of an ATM VCI - */ -#define IX_ATM_MAX_VCI 65535 - - /** - * @def IX_ATM_MAX_NUM_AAL_VCS - * @brief Maximum number of active AAL5/AAL0 VCs in the system - */ -#define IX_ATM_MAX_NUM_AAL_VCS 32 - -/** - * @def IX_ATM_MAX_NUM_VC - * @brief Maximum number of active AAL5/AAL0 VCs in the system - * The use of this macro is depreciated, it is retained for - * backward compatiblity. For current software release - * and beyond the define IX_ATM_MAX_NUM_AAL_VC should be used. - */ -#define IX_ATM_MAX_NUM_VC IX_ATM_MAX_NUM_AAL_VCS - - - -/** - * @def IX_ATM_MAX_NUM_OAM_TX_VCS - * @brief Maximum number of active OAM Tx VCs in the system, - * 1 OAM VC per port - */ -#define IX_ATM_MAX_NUM_OAM_TX_VCS IX_UTOPIA_MAX_PORTS - -/** - * @def IX_ATM_MAX_NUM_OAM_RX_VCS - * @brief Maximum number of active OAM Rx VCs in the system, - * 1 OAM VC shared accross all ports - */ -#define IX_ATM_MAX_NUM_OAM_RX_VCS 1 - -/** - * @def IX_ATM_MAX_NUM_AAL_OAM_TX_VCS - * @brief Maximum number of active AAL5/AAL0/OAM Tx VCs in the system - */ -#define IX_ATM_MAX_NUM_AAL_OAM_TX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_TX_VCS) - -/** - * @def IX_ATM_MAX_NUM_AAL_OAM_RX_VCS - * @brief Maximum number of active AAL5/AAL0/OAM Rx VCs in the system - */ -#define IX_ATM_MAX_NUM_AAL_OAM_RX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_RX_VCS) - -/** - * @def IX_ATM_IDLE_CELLS_CONNID - * @brief VC Id used to indicate idle cells in the returned schedule table. - */ -#define IX_ATM_IDLE_CELLS_CONNID 0 - - -/** - * @def IX_ATM_CELL_HEADER_VCI_GET - * @brief get the VCI field from a cell header - */ -#define IX_ATM_CELL_HEADER_VCI_GET(cellHeader) \ - (((cellHeader) >> 4) & IX_OAM_VCI_BITS_MASK); - -/** - * @def IX_ATM_CELL_HEADER_VPI_GET - * @brief get the VPI field from a cell header - */ -#define IX_ATM_CELL_HEADER_VPI_GET(cellHeader) \ - (((cellHeader) >> 20) & IX_OAM_VPI_BITS_MASK); - -/** - * @def IX_ATM_CELL_HEADER_PTI_GET - * @brief get the PTI field from a cell header - */ -#define IX_ATM_CELL_HEADER_PTI_GET(cellHeader) \ - ((cellHeader) >> 1) & IX_OAM_PTI_BITS_MASK; - -/** - * @typedef IxAtmCellHeader - * - * @brief ATM Cell Header, does not contain 4 byte HEC, added by NPE-A - */ -typedef unsigned int IxAtmCellHeader; - - -/** - * @enum IxAtmServiceCategory - * - * @brief Enumerated type representing available ATM service categories. - * For more informatoin on these categories, see "Traffic Management - * Specification" v4.1, published by the ATM Forum - - * http://www.atmforum.com - */ -typedef enum -{ - IX_ATM_CBR, /**< Constant Bit Rate */ - IX_ATM_RTVBR, /**< Real Time Variable Bit Rate */ - IX_ATM_VBR, /**< Variable Bit Rate */ - IX_ATM_UBR, /**< Unspecified Bit Rate */ - IX_ATM_ABR /**< Available Bit Rate (not supported) */ - -} IxAtmServiceCategory; - -/** - * - * @enum IxAtmRxQueueId - * - * @brief Rx Queue Type for RX traffic - * - * IxAtmRxQueueId defines the queues involved for receiving data. - * - * There are two queues to facilitate prioritisation handling - * and processing the 2 queues with different algorithms and - * constraints - * - * e.g. : one queue can carry voice (or time-critical traffic), the - * other queue can carry non-voice traffic - * - */ -typedef enum -{ - IX_ATM_RX_A = 0, /**< RX queue A */ - IX_ATM_RX_B, /**< RX queue B */ - IX_ATM_MAX_RX_STREAMS /**< Maximum number of RX streams */ -} IxAtmRxQueueId; - -/** - * @brief Structure describing an ATM traffic contract for a Virtual - * Connection (VC). - * - * Structure is used to specify the requested traffic contract for a - * VC to the IxAtmSch component using the @ref ixAtmSchVcModelSetup - * interface. - * - * These parameters are defined by the ATM forum working group - * (http://www.atmforum.com). - * - * @note Typical values for a voice channel 64 Kbit/s - * - atmService @a IX_ATM_RTVBR - * - pcr 400 (include IP overhead, and AAL5 trailer) - * - cdvt 5000000 (5 ms) - * - scr = pcr - * - * @note Typical values for a data channel 800 Kbit/s - * - atmService @a IX_ATM_UBR - * - pcr 1962 (include IP overhead, and AAL5 trailer) - * - cdvt 5000000 (5 ms) - * - */ -typedef struct -{ - IxAtmServiceCategory atmService; /**< ATM service category */ - unsigned pcr; /**< Peak Cell Rate - cells per second */ - unsigned cdvt; /**< Cell Delay Variation Tolerance - in nanoseconds */ - unsigned scr; /**< Sustained Cell Rate - cells per second */ - unsigned mbs; /**< Max Burst Size - cells */ - unsigned mcr; /**< Minimum Cell Rate - cells per second */ - unsigned mfs; /**< Max Frame Size - cells */ -} IxAtmTrafficDescriptor; - -/** - * @typedef IxAtmConnId - * - * @brief ATM VC data connection identifier. - * - * This is is generated by IxAtmdAcc when a successful connection is - * made on a VC. The is the ID by which IxAtmdAcc knows an active - * VC and should be used in IxAtmdAcc API calls to reference a - * specific VC. - */ -typedef unsigned int IxAtmConnId; - -/** - * @typedef IxAtmSchedulerVcId - * - * @brief ATM VC scheduling connection identifier. - * - * This id is generated and used by ATM Tx controller, generally - * the traffic shaper (e.g. IxAtmSch). The IxAtmdAcc component - * will request one of these Ids whenever a data connection on - * a Tx VC is requested. This ID will be used in callbacks to - * the ATM Transmission Ctrl s/w (e.g. IxAtmm) to reference a - * particular VC. - */ -typedef int IxAtmSchedulerVcId; - -/** - * @typedef IxAtmNpeRxVcId - * - * @brief ATM Rx VC identifier used by the ATM Npe. - * - * This Id is generated by IxAtmdAcc when a successful data connection - * is made on a rx VC. - */ -typedef unsigned int IxAtmNpeRxVcId; - -/** - * @brief ATM Schedule Table entry - * - * This IxAtmScheduleTableEntry is used by an ATM scheduler to inform - * IxAtmdAcc about the data to transmit (in term of cells per VC) - * - * This structure defines - * @li the number of cells to be transmitted (numberOfCells) - * @li the VC connection to be used for transmission (connId). - * - * @note - When the connection Id value is IX_ATM_IDLE_CELLS_CONNID, the - * corresponding number of idle cells will be transmitted to the hardware. - * - */ -typedef struct -{ - IxAtmConnId connId; /**< connection Id - * - * Identifier of VC from which cells are to be transmitted. - * When this valus is IX_ATM_IDLE_CELLS_CONNID, this indicates - * that the system should transmit the specified number - * of idle cells. Unknown connIds result in the transmission - * idle cells. - */ - unsigned int numberOfCells; /**< number of cells to transmit - * - * The number of contiguous cells to schedule from this VC - * at this point. The valid range is from 1 to - * @a IX_ATM_SCHEDULETABLE_MAXCELLS_PER_ENTRY. This - * number can swap over mbufs and pdus. OverSchduling results - * in the transmission of idle cells. - */ -} IxAtmScheduleTableEntry; - -/** - * @brief This structure defines a schedule table which gives details - * on which data (from which VCs) should be transmitted for a - * forthcoming period of time for a particular port and the - * order in which that data should be transmitted. - * - * The schedule table consists of a series of entries each of which - * will schedule one or more cells from a particular registered VC. - * The total number of cells scheduled and the total number of - * entries in the table are also indicated. - * - */ -typedef struct -{ - unsigned tableSize; /**< Number of entries - * - * Indicates the total number of - * entries in the table. - */ - unsigned totalCellSlots; /**< Number of cells - * - * Indicates the total number of ATM - * cells which are scheduled by all the - * entries in the table. - */ - IxAtmScheduleTableEntry *table; /**< Pointer to schedule entries - * - * Pointer to an array - * containing tableSize entries - */ -} IxAtmScheduleTable; - -#endif /* IXATMTYPES_H */ - -/** - * @} defgroup IxAtmTypes - */ - - diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h b/arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h deleted file mode 100644 index ae7b243..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxAtmdAcc.h +++ /dev/null @@ -1,1194 +0,0 @@ - -/** - * @file IxAtmdAcc.h - * - * @date 07-Nov-2001 - * - * @brief IxAtmdAcc Public API - * - * This file contains the public API of IxAtmdAcc, related to the - * data functions of the component - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/* ------------------------------------------------------ - Doxygen group definitions - ------------------------------------------------------ */ - -/** - * - * @defgroup IxAtmdAccAPI IXP400 ATM Driver Access (IxAtmdAcc) API - * - * @brief The public API for the IXP400 Atm Driver Data component - * - * IxAtmdAcc is the low level interface by which AAL0/AAL5 and - * OAM data gets transmitted to,and received from the Utopia bus. - * - * For AAL0/AAL5 services transmit and receive connections may - * be established independantly for unique combinations of - * port,VPI,and VCI. - * - * Two AAL0 services supporting 48 or 52 byte cell data are provided. - * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52). - * AAL0_52 is a raw cell service the client must format - * the PDU with an ATM cell header (excluding HEC) at the start of - * each cell, note that AtmdAcc does not validate the cell headers in - * a submitted PDU. - * - * OAM cells cannot be received over the AAL0 service but instead - * are received over a dedicated OAM service. - * - * For the OAM service an "OAM Tx channel" may be enabled for a port - * by establishing a single dedicated OAM Tx connection on that port. - * A single "OAM Rx channel" for all ports may be enabled by - * establishing a dedicated OAM Rx connection. - * - * The OAM service allows buffers containing 52 byte OAM F4/F5 cells - * to be transmitted and received over the dedicated OAM channels. - * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM - * service offered by AtmdAcc is a raw cell transport service. - * It is assumed that ITU I.610 procedures that make use of this - * service are implemented above AtmdAcc. - * - * Note that the dedicated OAM connections are established on - * reserved VPI,VCI, and (in the case of Rx) port values defined below. - * These values are used purely to descriminate the dedicated OAM channels - * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be - * realised for particluar VPI/VCIs by manipulating the VPI,VCI - * fields of the ATM cell headers of cells in the buffers passed - * to AtmdAcc. Note that AtmdAcc does not validate the cell headers - * in a submitted OAM PDU. - * - * - * - * This part is related to the User datapath processing - * - * @{ - */ - -#ifndef IXATMDACC_H -#define IXATMDACC_H - -#include "IxAtmTypes.h" - -/* ------------------------------------------------------ - AtmdAcc Data Types definition - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_WARNING - * - * @brief Warning return code - * - * This constant is used to tell IxAtmDAcc user about a special case. - * - */ -#define IX_ATMDACC_WARNING 2 - -/** - * - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_BUSY - * - * @brief Busy return code - * - * This constant is used to tell IxAtmDAcc user that the request - * is correct, but cannot be processed because the IxAtmAcc resources - * are already used. The user has to retry its request later - * - */ -#define IX_ATMDACC_BUSY 3 - -/** - * - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_RESOURCES_STILL_ALLOCATED - * - * @brief Disconnect return code - * - * This constant is used to tell IxAtmDAcc user that the disconnect - * functions are not complete because the resources used by the driver - * are not yet released. The user has to retry the disconnect call - * later. - * - */ -#define IX_ATMDACC_RESOURCES_STILL_ALLOCATED 4 - -/** - * - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_DEFAULT_REPLENISH_COUNT - * - * @brief Default resources usage for RxVcFree replenish mechanism - * - * This constant is used to tell IxAtmDAcc to allocate and use - * the minimum of resources for rx free replenish. - * - * @sa ixAtmdAccRxVcConnect - */ -#define IX_ATMDACC_DEFAULT_REPLENISH_COUNT 0 - - -/** - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_OAM_TX_VPI - * - * @brief The reserved value used for the dedicated OAM - * Tx connection. This "well known" value is used by atmdAcc and - * its clients to dsicriminate the OAM channel, and should be chosen so - * that it does not coencide with the VPI value used in an AAL0/AAL5 connection. - * Any attempt to connect a service type other than OAM on this VPI will fail. - * - * - */ -#define IX_ATMDACC_OAM_TX_VPI 0 - -/** - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_OAM_TX_VCI - * - * @brief The reserved value used for the dedicated OAM - * Tx connection. This "well known" value is used by atmdAcc and - * its clients to dsicriminate the OAM channel, and should be chosen so - * that it does not coencide with the VCI value used in an AAL0/AAL5 connection. - * Any attempt to connect a service type other than OAM on this VCI will fail. - */ -#define IX_ATMDACC_OAM_TX_VCI 0 - - - /** - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_OAM_RX_PORT - * - * @brief The reserved dummy PORT used for all dedicated OAM - * Rx connections. Note that this is not a real port but must - * have a value that lies within the valid range of port values. - */ -#define IX_ATMDACC_OAM_RX_PORT IX_UTOPIA_PORT_0 - - /** - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_OAM_RX_VPI - * - * @brief The reserved value value used for the dedicated OAM - * Rx connection. This value should be chosen so that it does not - * coencide with the VPI value used in an AAL0/AAL5 connection. - * Any attempt to connect a service type other than OAM on this VPI will fail. - */ -#define IX_ATMDACC_OAM_RX_VPI 0 - -/** - * @ingroup IxAtmdAccAPI - * - * @def IX_ATMDACC_OAM_RX_VCI - * - * @brief The reserved value value used for the dedicated OAM - * Rx connection. This value should be chosen so that it does not - * coencide with the VCI value used in an AAL0/AAL5 connection. - * Any attempt to connect a service type other than OAM on this VCI will fail. - */ -#define IX_ATMDACC_OAM_RX_VCI 0 - - -/** - * @enum IxAtmdAccPduStatus - * - * @ingroup IxAtmdAccAPI - * - * @brief IxAtmdAcc Pdu status : - * - * IxAtmdAccPduStatus is used during a RX operation to indicate - * the status of the received PDU - * - */ - -typedef enum -{ - IX_ATMDACC_AAL0_VALID = 0, /**< aal0 pdu */ - IX_ATMDACC_OAM_VALID, /**< OAM pdu */ - IX_ATMDACC_AAL2_VALID, /**< aal2 pdu @b reserved for future use */ - IX_ATMDACC_AAL5_VALID, /**< aal5 pdu complete and trailer is valid */ - IX_ATMDACC_AAL5_PARTIAL, /**< aal5 pdu not complete, trailer is missing */ - IX_ATMDACC_AAL5_CRC_ERROR, /**< aal5 pdu not complete, crc error/length error */ - IX_ATMDACC_MBUF_RETURN /**< empty buffer returned to the user */ -} IxAtmdAccPduStatus; - - -/** - * - * @enum IxAtmdAccAalType - * - * @ingroup IxAtmdAccAPI - * - * @brief IxAtmdAcc AAL Service Type : - * - * IxAtmdAccAalType defines the type of traffic to run on this VC - * - */ -typedef enum -{ - IX_ATMDACC_AAL5, /**< ITU-T AAL5 */ - IX_ATMDACC_AAL2, /**< ITU-T AAL2 @b reserved for future use */ - IX_ATMDACC_AAL0_48, /**< AAL0 48 byte payloads (cell header is added by NPE)*/ - IX_ATMDACC_AAL0_52, /**< AAL0 52 byte cell data (HEC is added by NPE) */ - IX_ATMDACC_OAM, /**< OAM cell transport service (HEC is added by NPE)*/ - IX_ATMDACC_MAX_SERVICE_TYPE /**< not a service, used for parameter validation */ -} IxAtmdAccAalType; - -/** - * - * @enum IxAtmdAccClpStatus - * - * @ingroup IxAtmdAccAPI - * - * @brief IxAtmdAcc CLP indication - * - * IxAtmdAccClpStatus defines the CLP status of the current PDU - * - */ -typedef enum -{ - IX_ATMDACC_CLP_NOT_SET = 0, /**< CLP indication is not set */ - IX_ATMDACC_CLP_SET = 1 /**< CLP indication is set */ -} IxAtmdAccClpStatus; - -/** - * @typedef IxAtmdAccUserId - * - * @ingroup IxAtmdAccAPI - * - * @brief User-supplied Id - * - * IxAtmdAccUserId is passed through callbacks and allows the - * IxAtmdAcc user to identify the source of a call back. The range of - * this user-owned Id is [0...2^32-1)]. - * - * The user provides this own Ids on a per-channel basis as a parameter - * in a call to @a ixAtmdAccRxVcConnect() or @a ixAtmdAccRxVcConnect() - * - * @sa ixAtmdAccRxVcConnect - * @sa ixAtmdAccTxVcConnect - * - */ -typedef unsigned int IxAtmdAccUserId; - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to RX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @brief Rx callback prototype - * - * IxAtmdAccRxVcRxCallback is the prototype of the Rx callback user - * function called once per PDU to pass a receive Pdu to a user on a - * partilcular connection. The callback is likely to push the mbufs - * to a protocol layer, and recycle the mbufs for a further use. - * - * @note -This function is called ONLY in the context of - * the @a ixAtmdAccRxDispatch() function - * - * @sa ixAtmdAccRxDispatch - * @sa ixAtmdAccRxVcConnect - * - * @param port @ref IxAtmLogicalPort [in] - the port on which this PDU was received - * a logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call - * to @a ixAtmdAccRxVcConnect() - * @param status @ref IxAtmdAccPduStatus [in] - an indication about the PDU validity. - * In the case of AAL0 the only possibile value is - * AAL0_VALID, in this case the client may optionally determine - * that an rx timeout occured by checking if the mbuf is - * compleletly or only partially filled, the later case - * indicating a timeout. - * In the case of OAM the only possible value is OAM valid. - * The status is set to @a IX_ATMDACC_MBUF_RETURN when - * the mbuf is released during a disconnect process. - * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU. - * For AAL5/AAL0_48 this information - * is set if the clp bit of any rx cell is set - * For AAL0-52/OAM the client may inspect the CLP in individual - * cell headers in the PDU, and this parameter is set to 0. - * @param *mbufPtr @ref IX_OSAL_MBUF [in] - depending on the servive type a pointer to - * an mbuf (AAL5/AAL0/OAM) or mbuf chain (AAL5 only), - * that comprises the complete PDU data. - * - * This parameter is guaranteed not to be a null pointer. - * - */ -typedef void (*IxAtmdAccRxVcRxCallback) (IxAtmLogicalPort port, - IxAtmdAccUserId userId, - IxAtmdAccPduStatus status, - IxAtmdAccClpStatus clp, - IX_OSAL_MBUF * mbufPtr); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @brief Callback prototype for free buffer level is low. - * - * IxAtmdAccRxVcFreeLowCallback is the prototype of the user function - * which get called on a per-VC basis, when more mbufs are needed to - * continue the ATM data reception. This function is likely to supply - * more available mbufs by one or many calls to the replenish function - * @a ixAtmdAccRxVcFreeReplenish() - * - * This function is called when the number of available buffers for - * reception is going under the threshold level as defined - * in @a ixAtmdAccRxVcFreeLowCallbackRegister() - * - * This function is called inside an Qmgr dispatch context. No system - * resource or interrupt-unsafe feature should be used inside this - * callback. - * - * @sa ixAtmdAccRxVcFreeLowCallbackRegister - * @sa IxAtmdAccRxVcFreeLowCallback - * @sa ixAtmdAccRxVcFreeReplenish - * @sa ixAtmdAccRxVcFreeEntriesQuery - * @sa ixAtmdAccRxVcConnect - * - * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call - * to @a ixAtmdAccRxVcConnect() - * - * @return None - * - */ -typedef void (*IxAtmdAccRxVcFreeLowCallback) (IxAtmdAccUserId userId); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to TX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @brief Buffer callback prototype. - * - * This function is called to relinguish ownership of a transmitted - * buffer chain to the user. - * - * @note -In the case of a chained mbuf the AmtdAcc component can - * chain many user buffers together and pass ownership to the user in - * one function call. - * - * @param userId @ref IxAtmdAccUserId [in] - user If provided at registration of this - * callback. - * @param mbufPtr @ref IX_OSAL_MBUF [in] - a pointer to mbufs or chain of mbufs and is - * guaranteed not to be a null pointer. - * - */ -typedef void (*IxAtmdAccTxVcBufferReturnCallback) (IxAtmdAccUserId userId, - IX_OSAL_MBUF * mbufPtr); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to Initialisation - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccInit (void) - * - * @brief Initialise the IxAtmdAcc Component - * - * This function initialise the IxAtmdAcc component. This function shall - * be called before any other function of the API. Its role is to - * initialise all internal resources of the IxAtmdAcc component. - * - * The ixQmgr component needs to be initialized prior the use of - * @a ixAtmdAccInit() - * - * @param none - * - * Failing to initilialize the IxAtmdAcc API before any use of it will - * result in a failed status. - * If the specified component is not present, a success status will still be - * returned, however, a warning indicating the NPE to download to is not - * present will be issued. - * - * @return @li IX_SUCCESS initialisation is complete (in case of component not - * being present, a warning is clearly indicated) - * @return @li IX_FAIL unable to process this request either - * because this IxAtmdAcc is already initialised - * or some unspecified error has occrred. - */ -PUBLIC IX_STATUS ixAtmdAccInit (void); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccShow (void) - * - * @brief Show IxAtmdAcc configuration on a per port basis - * - * @param none - * - * @return none - * - * @note - Display use printf() and are redirected to stdout - */ -PUBLIC void -ixAtmdAccShow (void); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccStatsShow (void) - * - * @brief Show all IxAtmdAcc stats - * - * @param none - * - * @return none - * - * @note - Stats display use printf() and are redirected to stdout - */ -PUBLIC void -ixAtmdAccStatsShow (void); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccStatsReset (void) - * - * @brief Reset all IxAtmdAcc stats - * - * @param none - * - * @return none - * - */ -PUBLIC void -ixAtmdAccStatsReset (void); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to RX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcConnect (IxAtmLogicalPort port, - unsigned int vpi, - unsigned int vci, - IxAtmdAccAalType aalServiceType, - IxAtmRxQueueId rxQueueId, - IxAtmdAccUserId userCallbackId, - IxAtmdAccRxVcRxCallback rxCallback, - unsigned int minimumReplenishCount, - IxAtmConnId * connIdPtr, - IxAtmNpeRxVcId * npeVcIdPtr ) - * - * @brief Connect to a Aal Pdu receive service for a particular - * port/vpi/vci, and service type. - * - * This function allows a user to connect to an Aal5/Aal0/OAM Pdu receive service - * for a particular port/vpi/vci. It registers the callback and allocates - * internal resources and a Connection Id to be used in further API calls - * related to this VCC. - * - * The function will setup VC receive service on the specified rx queue. - * - * This function is blocking and makes use internal locks, and hence - * should not be called from an interrupt context. - * - * On return from @a ixAtmdAccRxVcConnect() with a failure status, the - * connection Id parameter is unspecified. Its value cannot be used. - * A connId is the reference by which IxAtmdAcc refers to a - * connected VC. This identifier is the result of a succesful call - * to a connect function. This identifier is invalid after a - * sucessful call to a disconnect function. - * - * Calling this function for the same combination of Vpi, Vci and more - * than once without calling @a ixAtmdAccRxVcTryDisconnect() will result in a - * failure status. - * - * If this function returns success the user should supply receive - * buffers by calling @a ixAtmdAccRxVcFreeReplenish() and then call - * @a ixAtmdAccRxVcEnable() to begin receiving pdus. - * - * There is a choice of two receive Qs on which the VC pdus could be - * receive. The user must associate the VC with one of these. Essentially - * having two qs allows more flexible system configuration such as have - * high prioriy traffic on one q (e.g. voice) and low priority traffic on - * the other (e.g. data). The high priority Q could be serviced in - * preference to the low priority Q. One queue may be configured to be - * serviced as soon as there is traffic, the other queue may be configured - * to be serviced by a polling mechanism running at idle time. - * - * Two AAL0 services supporting 48 or 52 byte cell data are provided. - * Received AAL0 PDUs will be be a multiple of the cell data size (48/52). - * AAL0_52 is a raw cell service and includes an ATM cell header - * (excluding HEC) at the start of each cell. - * - * A single "OAM Rx channel" for all ports may be enabled by - * establishing a dedicated OAM Rx connection. - * - * The OAM service allows buffers containing 52 byte OAM F4/F5 cells - * to be transmitted and received over the dedicated OAM channels. - * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM - * service offered by AtmdAcc is a raw cell transport service. - * It is assumed that ITU I.610 procedures that make use of this - * service are implemented above AtmdAcc. - * - * Note that the dedicated OAM connections are established on - * reserved VPI,VCI, and (in the case of Rx) port values. - * These values are used purely to descriminate the dedicated OAM channels - * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be - * realised for particluar VPI/VCIs by manipulating the VPI,VCI - * fields of the ATM cell headers of cells in the buffers passed - * to AtmdAcc. - * - * Calling this function prior to enable the port will fail. - * - * @sa ixAtmdAccRxDispatch - * @sa ixAtmdAccRxVcEnable - * @sa ixAtmdAccRxVcDisable - * @sa ixAtmdAccRxVcTryDisconnect - * @sa ixAtmdAccPortEnable - * - * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port - * [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param vpi unsigned int [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI - * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI - * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service: AAL5, AAL0_48, AAL0_52, or OAM - * @param rxQueueId @ref IxAtmRxQueueId [in] - this identifieds which of two Qs the VC - * should use.when icoming traffic is processed - * @param userCallbackId @ref IxAtmdAccUserId [in] - user Id used later as a parameter to - * the supplied rxCallback. - * @param rxCallback [in] @ref IxAtmdAccRxVxRxCallback - function called when mbufs are received. - * This parameter cannot be a null pointer. - * @param bufferFreeCallback [in] - function to be called to return - * ownership of buffers to IxAtmdAcc user. - * @param minimumReplenishCount unsigned int [in] - For AAL5/AAL0 the number of free mbufs - * to be used with this channel. Use a high number when the expected traffic - * rate on this channel is high, or when the user's mbufs are small, or when - * the RxVcFreeLow Notification has to be invoked less often. When this - * value is IX_ATMDACC_DEFAULT_REPLENISH_COUNT, the minimum of - * resources will be used. Depending on traffic rate, pdu - * size and mbuf size, rxfree queue size, polling/interrupt rate, this value may - * require to be replaced by a different value in the range 1-128 - * For OAM the rxFree queue size is fixed by atmdAcc and this parameter is ignored. - * @param connIdPtr @ref IxAtmConnId [out] - pointer to a connection Id - * This parameter cannot be a null pointer. - * @param npeVcIdPtr @ref IxAtmNpeRxVcId [out] - pointer to an npe Vc Id - * This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS successful call to IxAtmdAccRxVcConnect - * @return @li IX_ATMDACC_BUSY cannot process this request : - * no VC is available - * @return @li IX_FAIL - * parameter error, - * VC already in use, - * attempt to connect AAL service on reserved OAM VPI/VCI, - * attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI, - * port is not initialised, - * or some other error occurs during processing. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcConnect (IxAtmLogicalPort port, - unsigned int vpi, - unsigned int vci, - IxAtmdAccAalType aalServiceType, - IxAtmRxQueueId rxQueueId, - IxAtmdAccUserId userCallbackId, - IxAtmdAccRxVcRxCallback rxCallback, - unsigned int minimumReplenishCount, - IxAtmConnId * connIdPtr, - IxAtmNpeRxVcId * npeVcIdPtr ); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId, - IX_OSAL_MBUF * mbufPtr) - * - * @brief Provide free mbufs for data reception on a connection. - * - * This function provides mbufs for data reception by the hardware. This - * function needs to be called by the user on a regular basis to ensure - * no packet loss. Providing free buffers is a connection-based feature; - * each connection can have different requirements in terms of buffer size - * number of buffers, recycling rate. This function could be invoked from - * within the context of a @a IxAtmdAccRxVcFreeLowCallback() callback - * for a particular VC - * - * Mbufs provided through this function call can be chained. They will be - * unchained internally. A call to this function with chained mbufs or - * multiple calls with unchained mbufs are equivalent, but calls with - * unchained mbufs are more efficients. - * - * Mbufs provided to this interface need to be able to hold at least one - * full cell payload (48/52 bytes, depending on service type). - * Chained buffers with a size less than the size supported by the hardware - * will be returned through the rx callback provided during the connect step. - * - * Failing to invoke this function prior to enabling the RX traffic - * can result in packet loss. - * - * This function is not reentrant for the same connId. - * - * This function does not use system resources and can be - * invoked from an interrupt context. - * - * @note - Over replenish is detected, and extra mbufs are returned through - * the rx callback provided during the connect step. - * - * @note - Mbuf provided to the replenish function should have a length greater or - * equal to 48/52 bytes according to service type. - * - * @note - The memory cache of mMbuf payload should be invalidated prior to Mbuf - * submission. Flushing the Mbuf headers is handled by IxAtmdAcc. - * - * @note - When a chained mbuf is provided, this function process the mbufs - * up to the hardware limit and invokes the user-supplied callback - * to release extra buffers. - * - * @sa ixAtmdAccRxVcFreeLowCallbackRegister - * @sa IxAtmdAccRxVcFreeLowCallback - * @sa ixAtmdAccRxVcConnect - * - * @param connId @ref IxAtmConnId [in] - connection Id as returned from a succesfull call to - * @a IxAtmdAccRxVcConnect() - * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a mbuf structure to be used for data - * reception. The mbuf pointed to by this parameter can be chained - * to an other mbuf. - * - * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcFreeReplenish() - * and the mbuf is now ready to use for incoming traffic. - * @return @li IX_ATMDACC_BUSY cannot process this request because - * the max number of outstanding free buffers has been reached - * or the internal resources have exhausted for this VC. - * The user is responsible for retrying this request later. - * @return @li IX_FAIL cannot process this request because of parameter - * errors or some unspecified internal error has occurred. - * - * @note - It is not always guaranteed the replenish step to be as fast as the - * hardware is consuming Rx Free mbufs. There is nothing in IxAtmdAcc to - * guarantee that replenish reaches the rxFree threshold level. If the - * threshold level is not reached, the next rxFree low notification for - * this channel will not be triggered. - * The preferred ways to replenish can be as follows (depending on - * applications and implementations) : - * @li Replenish in a rxFree low notification until the function - * ixAtmdAccRxVcFreeReplenish() returns IX_ATMDACC_BUSY - * @li Query the queue level using @sa ixAtmdAccRxVcFreeEntriesQuery, then - * , replenish using @a ixAtmdAccRxVcFreeReplenish(), then query the queue - * level again, and replenish if the threshold is still not reached. - * @li Trigger replenish from an other event source and use rxFree starvation - * to throttle the Rx traffic. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId, - IX_OSAL_MBUF * mbufPtr); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId, - unsigned int numberOfMbufs, - IxAtmdAccRxVcFreeLowCallback callback) - * - * @brief Configure the RX Free threshold value and register a callback - * to handle threshold notifications. - * - * The function ixAtmdAccRxVcFreeLowCallbackRegister sets the threshold value for - * a particular RX VC. When the number of buffers reaches this threshold - * the callback is invoked. - * - * This function should be called once per VC before RX traffic is - * enabled.This function will fail if the curent level of the free buffers - * is equal or less than the threshold value. - * - * @sa ixAtmdAccRxVcFreeLowCallbackRegister - * @sa IxAtmdAccRxVcFreeLowCallback - * @sa ixAtmdAccRxVcFreeReplenish - * @sa ixAtmdAccRxVcFreeEntriesQuery - * @sa ixAtmdAccRxVcConnect - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call - * to @a IxAtmdAccRxVcConnect() - * @param numberOfMbufs unsigned int [in] - threshold number of buffers. This number - * has to be a power of 2, one of the values 0,1,2,4,8,16,32.... - * The maximum value cannot be more than half of the rxFree queue - * size (which can be retrieved using @a ixAtmdAccRxVcFreeEntriesQuery() - * before any use of the @a ixAtmdAccRxVcFreeReplenish() function) - * @param callback @ref IxAtmdAccRxVcFreeLowCallback [in] - function telling the user that the number of - * free buffers has reduced to the threshold value. - * - * @return @li IX_SUCCESS Threshold set successfully. - * @return @li IX_FAIL parameter error or the current number of free buffers - * is less than or equal to the threshold supplied or some - * unspecified error has occrred. - * - * @note - the callback will be called when the threshold level will drop from - * exactly (numberOfMbufs + 1) to (numberOfMbufs). - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId, - unsigned int numberOfMbufs, - IxAtmdAccRxVcFreeLowCallback callback); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId, - unsigned int *numberOfMbufsPtr) - * - * @brief Get the number of rx mbufs the system can accept to replenish the - * the rx reception mechanism on a particular channel - * - * The ixAtmdAccRxVcFreeEntriesQuery function is used to retrieve the current - * number of available mbuf entries for reception, on a per-VC basis. This - * function can be used to know the number of mbufs which can be provided - * using @a ixAtmdAccRxVcFreeReplenish(). - * - * This function can be used from a timer context, or can be associated - * with a threshold event, or can be used inside an active polling - * mechanism which is under user control. - * - * This function is reentrant and does not use system resources and can - * be invoked from an interrupt context. - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call - * to @a IxAtmdAccRxVcConnect() - * @param numberOfMbufsPtr unsigned int [out] - Pointer to the number of available entries. - * . This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS the current number of mbufs not yet used for incoming traffic - * @return @li IX_FAIL invalid parameter - * - * @sa ixAtmdAccRxVcFreeReplenish - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId, - unsigned int *numberOfMbufsPtr); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcEnable (IxAtmConnId connId) - * - * @brief Start the RX service on a VC. - * - * This functions kicks-off the traffic reception for a particular VC. - * Once invoked, incoming PDUs will be made available by the hardware - * and are eventually directed to the @a IxAtmdAccRxVcRxCallback() callback - * registered for the connection. - * - * If the traffic is already running, this function returns IX_SUCCESS. - * This function can be invoked many times. - * - * IxAtmdAccRxVcFreeLowCallback event will occur only after - * @a ixAtmdAccRxVcEnable() function is invoked. - * - * Before using this function, the @a ixAtmdAccRxVcFreeReplenish() function - * has to be used to replenish the RX Free queue. If not, incoming traffic - * may be discarded.and in the case of interrupt driven reception the - * @a IxAtmdAccRxVcFreeLowCallback() callback may be invoked as a side effect - * during a replenish action. - * - * This function is not reentrant and should not be used inside an - * interrupt context. - * - * For an VC connection this function can be called after a call to - * @a ixAtmdAccRxVcDisable() and should not be called after - * @a ixAtmdAccRxVcTryDisconnect() - * - * @sa ixAtmdAccRxVcDisable - * @sa ixAtmdAccRxVcConnect - * @sa ixAtmdAccRxVcFreeReplenish - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call - * to @a IxAtmdAccRxVcConnect() - * - * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcEnable - * @return @li IX_ATMDACC_WARNING the channel is already enabled - * @return @li IX_FAIL invalid parameters or some unspecified internal - * error occured. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcEnable (IxAtmConnId connId); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcDisable (IxAtmConnId connId) - * - * @brief Stop the RX service on a VC. - * - * This functions stops the traffic reception for a particular VC connection. - * - * Once invoked, incoming Pdus are discarded by the hardware. Any Pdus - * pending will be freed to the user - * - * Hence once this function returns no more receive callbacks will be - * called for that VC. However, buffer free callbacks will be invoked - * until such time as all buffers supplied by the user have been freed - * back to the user - * - * Calling this function doe not invalidate the connId. - * @a ixAtmdAccRxVcEnable() can be invoked to enable Pdu reception again. - * - * If the traffic is already stopped, this function returns IX_SUCCESS. - * - * This function is not reentrant and should not be used inside an - * interrupt context. - * - * @sa ixAtmdAccRxVcConnect - * @sa ixAtmdAccRxVcEnable - * @sa ixAtmdAccRxVcDisable - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to @a - * IxAtmdAccRxVcConnect() - * - * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcDisable(). - * @return @li IX_ATMDACC_WARNING the channel is already disabled - * @return @li IX_FAIL invalid parameters or some unspecified internal error occured - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcDisable (IxAtmConnId connId); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId) - * - * @brief Disconnect a VC from the RX service. - * - * This function deregisters the VC and guarantees that all resources - * associated with this VC are free. After its execution, the connection - * Id is not available. - * - * This function will fail until such time as all resources allocated to - * the VC connection have been freed. The user is responsible to delay and - * call again this function many times until a success status is returned. - * - * This function needs internal locks and should not be called from an - * interrupt context - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to - * @a IxAtmdAccRxVcConnect() - * - * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcDisable - * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources - * associated with the connection have been freed. - * @return @li IX_FAIL cannot process this request because of a parameter - * error - * - */ -PUBLIC IX_STATUS ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to TX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccTxVcConnect (IxAtmLogicalPort port, - unsigned int vpi, - unsigned int vci, - IxAtmdAccAalType aalServiceType, - IxAtmdAccUserId userId, - IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback, - IxAtmConnId * connIdPtr) - * - * @brief Connect to a Aal Pdu transmit service for a particular - * port/vpi/vci and service type. - * - * This function allows a user to connect to an Aal5/Aal0/OAM Pdu transmit service - * for a particular port/vpi/vci. It registers the callback and allocates - * internal resources and a Connection Id to be used in further API calls - * related to this VC. - * - * The function will setup VC transmit service on the specified on the - * specified port. A connId is the reference by which IxAtmdAcc refers to a - * connected VC. This identifier is the result of a succesful call - * to a connect function. This identifier is invalid after a - * sucessful call to a disconnect function. - * - * This function needs internal locks, and hence should not be called - * from an interrupt context. - * - * On return from @a ixAtmdAccTxVcConnect() with a failure status, the - * connection Id parameter is unspecified. Its value cannot be used. - * - * Calling this function for the same combination of port, Vpi, Vci and - * more than once without calling @a ixAtmdAccTxVcTryDisconnect() will result - * in a failure status. - * - * Two AAL0 services supporting 48 or 52 byte cell data are provided. - * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52). - * AAL0_52 is a raw cell service the client must format - * the PDU with an ATM cell header (excluding HEC) at the start of - * each cell, note that AtmdAcc does not validate the cell headers in - * a submitted PDU. - * - * For the OAM service an "OAM Tx channel" may be enabled for a port - * by establishing a single dedicated OAM Tx connection on that port. - * - * The OAM service allows buffers containing 52 byte OAM F4/F5 cells - * to be transmitted and received over the dedicated OAM channels. - * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM - * service offered by AtmdAcc is a raw cell transport service. - * It is assumed that ITU I.610 procedures that make use of this - * service are implemented above AtmdAcc. - * - * Note that the dedicated OAM connections are established on - * reserved VPI,VCI, and (in the case of Rx) port values. - * These values are used purely to descriminate the dedicated OAM channels - * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be - * realised for particluar VPI/VCIs by manipulating the VPI,VCI - * fields of the ATM cell headers of cells in the buffers passed - * to AtmdAcc. - * - * Calling this function before enabling the port will fail. - * - * @sa ixAtmdAccTxVcTryDisconnect - * @sa ixAtmdAccPortTxScheduledModeEnable - * @sa ixAtmdAccPortEnable - * - * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port - * [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param vpi unsigned int [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI - * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI - * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service AAL5, AAL0_48, AAL0_52, or OAM - * @param userId @ref IxAtmdAccUserId [in] - user id to be used later during callbacks related - * to this channel - * @param bufferFreeCallback @ref IxAtmdAccTxVcBufferReturnCallback [in] - function called when mbufs - * transmission is complete. This parameter cannot be a null - * pointer. - * @param connIdPtr @ref IxAtmConnId [out] - Pointer to a connection Id. - * This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS successful call to @a IxAtmdAccRxVcConnect(). - * @return @li IX_ATMDACC_BUSY cannot process this request - * because no VC is available - * @return @li IX_FAIL - * parameter error, - * VC already in use, - * attempt to connect AAL service on reserved OAM VPI/VCI, - * attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI, - * port is not initialised, - * or some other error occurs during processing. - * - * @note - Unscheduled mode is not supported in ixp425 1.0. Therefore, the - * function @a ixAtmdAccPortTxScheduledModeEnable() need to be called - * for this port before any establishing a Tx Connection - */ -PUBLIC IX_STATUS ixAtmdAccTxVcConnect (IxAtmLogicalPort port, - unsigned int vpi, - unsigned int vci, - IxAtmdAccAalType aalServiceType, - IxAtmdAccUserId userId, - IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback, - IxAtmConnId * connIdPtr); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccTxVcPduSubmit (IxAtmConnId connId, - IX_OSAL_MBUF * mbufPtr, - IxAtmdAccClpStatus clp, - unsigned int numberOfCells) - * - * @brief Submit a Pdu for transmission on connection. - * - * A data user calls this function to submit an mbufs containing a Pdu - * to be transmitted. The buffer supplied can be chained and the Pdu it - * contains must be complete. - * - * The transmission behavior of this call depends on the operational mode - * of the port on which the connection is made. - * - * In unscheduled mode the mbuf will be submitted to the hardware - * immediately if sufficent resource is available. Otherwise the function - * will return failure. - * - * In scheduled mode the buffer is queued internally in IxAtmdAcc. The cell - * demand is made known to the traffic shaping entity. Cells from the - * buffers are MUXed onto the port some time later as dictated by the - * traffic shaping entity. The traffic shaping entity does this by sending - * transmit schedules to IxAtmdAcc via @a ixAtmdAccPortTxProcess() function call. - * - * Note that the dedicated OAM channel is scheduled just like any - * other channel. This means that any OAM traffic relating to an - * active AAL0/AAL5 connection will be scheduled independantly of the - * AAL0/AAL5 traffic for that connection. - * - * When transmission is complete, the TX Done mechanism will give the - * owmnership of these buffers back to the customer. The tx done mechanism - * must be in operation before transmission is attempted. - * - * For AAL0/OAM submitted AAL0 PDUs must be a multiple of the cell data - * size (48/52). AAL0_52 and OAM are raw cell services, and the client - * must format the PDU with an ATM cell header (excluding HEC) at the - * start of each cell, note that AtmdAcc does not validate the cell headers in - * a submitted PDU. - * - * - * @sa IxAtmdAccTxVcBufferReturnCallback - * @sa ixAtmdAccTxDoneDispatch - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to - * @a ixAtmdAccTxVcConnect() - * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a chained structure of mbufs to transmit. - * This parameter cannot be a null pointer. - * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU. All cells of this pdu - * will be sent with the clp bit set - * @param numberOfCells unsigned int [in] - number of cells in the PDU. - * - * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcPduSubmit() - * The pdu pointed by the mbufPtr parameter will be - * transmitted - * @return @li IX_ATMDACC_BUSY unable to process this request because - * internal resources are all used. The caller is responsible - * for retrying this request later. - * @return @li IX_FAIL unable to process this request because of error - * in the parameters (wrong connId supplied, - * or wrong mbuf pointer supplied), the total length of all buffers - * in the chain should be a multiple of the cell size - * ( 48/52 depending on the service type ), - * or unspecified error during processing - * - * @note - This function in not re-entrant for the same VC (e.g. : two - * thread cannot send PDUs for the same VC). But two threads can - * safely call this function with a different connection Id - * - * @note - In unscheduled mode, this function is not re-entrant on a per - * port basis. The size of pdus is limited to 8Kb. - * - * @note - 0-length mbufs should be removed from the chain before submission. - * The total length of the pdu (sdu + padding +trailer) has to be - * updated in the header of the first mbuf of a chain of mbufs. - * - * @note - Aal5 trailer information (UUI, CPI, SDU length) has to be supplied - * before submission. - * - * @note - The payload memory cache should be flushed, if needed, prior to - * transmission. Mbuf headers are flushed by IxAtmdAcc - * - * @note - This function does not use system resources and can be used - * inside an interrupt context - */ -PUBLIC IX_STATUS ixAtmdAccTxVcPduSubmit (IxAtmConnId connId, - IX_OSAL_MBUF * mbufPtr, - IxAtmdAccClpStatus clp, - unsigned int numberOfCells); - -/** - * - * @ingroup IxAtmdAccAPI - * - * @fn ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId) - * - * @brief Disconnect from a Aal Pdu transmit service for a particular - * port/vpi/vci. - * - * This function deregisters the VC and guarantees that all resources - * associated with this VC are free. After its execution, the connection - * Id is not available. - * - * This function will fail until such time as all resources allocated to - * the VC connection have been freed. The user is responsible to delay - * and call again this function many times until a success status is - * returned. - * - * After its execution, the connection Id is not available. - * - * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to - * @a ixAtmdAccTxVcConnect() - * - * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcTryDisconnect() - * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources - * associated with the connection have been freed. This condition will - * disappear after Tx and TxDone is complete for this channel. - * @return @li IX_FAIL unable to process this request because of errors - * in the parameters (wrong connId supplied) - * - * @note - This function needs internal locks and should not be called - * from an interrupt context - * - * @note - If the @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED error does not - * clear after a while, this may be linked to a previous problem - * of cell overscheduling. Diabling the port and retry a disconnect - * will free the resources associated with this channel. - * - * @sa ixAtmdAccPortTxProcess - * - */ -PUBLIC IX_STATUS ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId); - -#endif /* IXATMDACC_H */ - -/** - * @} defgroup IxAtmdAccAPI - */ - - diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h b/arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h deleted file mode 100644 index 50ef582..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxAtmdAccCtrl.h +++ /dev/null @@ -1,1958 +0,0 @@ - -/** - * @file IxAtmdAccCtrl.h - * - * @date 20-Mar-2002 - * - * @brief IxAtmdAcc Public API - * - * This file contains the public API of IxAtmdAcc, related to the - * control functions of the component. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/* ------------------------------------------------------ - Doxygen group definitions - ------------------------------------------------------ */ - -/** - * - * @defgroup IxAtmdAccCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Control API - * - * @brief The public API for the IXP400 Atm Driver Control component - * - * IxAtmdAcc is the low level interface by which AAL PDU get transmitted - * to,and received from the Utopia bus - * - * This part is related to the Control configuration - * - * @{ - */ - -#ifndef IXATMDACCCTRL_H -#define IXATMDACCCTRL_H - -#include "IxAtmdAcc.h" - -/* ------------------------------------------------------ - AtmdAccCtrl Data Types definition - ------------------------------------------------------ */ - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @def IX_ATMDACC_PORT_DISABLE_IN_PROGRESS -* -* @brief Port enable return code -* -* This constant is used to tell IxAtmDAcc user that the port disable -* functions are not complete. The user can call ixAtmdAccPortDisableComplete() -* to find out when the disable has finished. The port enable can then proceed. -* -*/ -#define IX_ATMDACC_PORT_DISABLE_IN_PROGRESS 5 - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @def IX_ATMDACC_ALLPDUS -* -* @brief All PDUs -* -* This constant is used to tell IxAtmDAcc to process all PDUs from -* the RX queue or the TX Done -* -* @sa IxAtmdAccRxDispatcher -* @sa IxAtmdAccTxDoneDispatcher -* -*/ -#define IX_ATMDACC_ALLPDUS 0xffffffff - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to RX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @brief Callback prototype for notification of available PDUs for - * an Rx Q. - * - * This a protoype for a function which is called when there is at - * least one Pdu available for processing on a particular Rx Q. - * - * This function should call @a ixAtmdAccRxDispatch() with - * the aprropriate number of parameters to read and process the Rx Q. - * - * @sa ixAtmdAccRxDispatch - * @sa ixAtmdAccRxVcConnect - * @sa ixAtmdAccRxDispatcherRegister - * - * @param rxQueueId @ref IxAtmRxQueueId [in] indicates which RX queue to has Pdus to process. - * @param numberOfPdusToProcess unsigned int [in] indicates the minimum number of - * PDUs available to process all PDUs from the queue. - * @param reservedPtr unsigned int* [out] pointer to a int location which can - * be written to, but does not retain written values. This is - * provided to make this prototype compatible - * with @a ixAtmdAccRxDispatch() - * - * @return @li int - ignored. - * - */ -typedef IX_STATUS (*IxAtmdAccRxDispatcher) (IxAtmRxQueueId rxQueueId, - unsigned int numberOfPdusToProcess, - unsigned int *reservedPtr); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to TX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @brief Callback prototype for transmitted mbuf when threshold level is - * crossed. - * - * IxAtmdAccTxDoneDispatcher is the prototype of the user function - * which get called when pdus are completely transmitted. This function - * is likely to call the @a ixAtmdAccTxDoneDispatch() function. - * - * This function is called when the number of available pdus for - * reception is crossing the threshold level as defined - * in @a ixAtmdAccTxDoneDispatcherRegister() - * - * This function is called inside an Qmgr dispatch context. No system - * resource or interrupt-unsafe feature should be used inside this - * callback. - * - * Transmitted buffers recycling implementation is a sytem-wide mechanism - * and needs to be set before any traffic is started. If this threshold - * mechanism is not used, the user is responsible for polling the - * transmitted buffers with @a ixAtmdAccTxDoneDispatch() - * and @a ixAtmdAccTxDoneLevelQuery() functions. - * - * @sa ixAtmdAccTxDoneDispatcherRegister - * @sa ixAtmdAccTxDoneDispatch - * @sa ixAtmdAccTxDoneLevelQuery - * - * @param numberOfPdusToProcess unsigned int [in] - The current number of pdus currently - * available for recycling - * @param *reservedPtr unsigned int [out] - pointer to a int location which can be - * written to but does not retain written values. This is provided - * to make this prototype compatible - * with @a ixAtmdAccTxDoneDispatch() - * - * @return @li IX_SUCCESS This is provided to make - * this prototype compatible with @a ixAtmdAccTxDoneDispatch() - * @return @li IX_FAIL invalid parameters or some unspecified internal - * error occured. This is provided to make - * this prototype compatible with @a ixAtmdAccTxDoneDispatch() - * - */ -typedef IX_STATUS (*IxAtmdAccTxDoneDispatcher) (unsigned int numberOfPdusToProcess, - unsigned int *reservedPtr); - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @brief Notification that the threshold number of scheduled cells -* remains in a port's transmit Q. -* -* The is the prototype for of the user notification function which -* gets called on a per-port basis, when the number of remaining -* scheduled cells to be transmitted decreases to the threshold level. -* The number of cells passed as a parameter can be used for scheduling -* purposes as the maximum number of cells that can be passed in a -* schedule table to the @a ixAtmdAccPortTxProcess() function. -* -* @sa ixAtmdAccPortTxCallbackRegister -* @sa ixAtmdAccPortTxProcess -* @sa ixAtmdAccPortTxFreeEntriesQuery -* -* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] -* @param numberOfAvailableCells unsigned int [in] - number of available -* cell entries.for the port -* -* @note - This functions shall not use system resources when used -* inside an interrupt context. -* -*/ -typedef void (*IxAtmdAccPortTxLowCallback) (IxAtmLogicalPort port, - unsigned int numberOfAvailableCells); - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @brief Prototype to submit cells for transmission -* -* IxAtmdAccTxVcDemandUpdateCallback is the prototype of the callback -* function used by AtmD to notify an ATM Scheduler that the user of -* a VC has submitted cells for transmission. -* -* @sa IxAtmdAccTxVcDemandUpdateCallback -* @sa IxAtmdAccTxVcDemandClearCallback -* @sa IxAtmdAccTxSchVcIdGetCallback -* @sa ixAtmdAccPortTxScheduledModeEnable -* -* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be updated -* is established -* @param vcId int [in] - Identifies the VC to be updated. This is the value -* returned by the @a IxAtmdAccTxSchVcIdGetCallback() call . -* @param numberOfCells unsigned int [in] - Indicates how many ATM cells should be added -* to the queue for this VC. -* -* @return @li IX_SUCCESS the function is registering the cell demand for -* this VC. -* @return @li IX_FAIL the function cannot register cell for this VC : the -* scheduler maybe overloaded or misconfigured -* -*/ -typedef IX_STATUS (*IxAtmdAccTxVcDemandUpdateCallback) (IxAtmLogicalPort port, - int vcId, - unsigned int numberOfCells); - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @brief prototype to remove all currently queued cells from a -* registered VC -* -* IxAtmdAccTxVcDemandClearCallback is the prototype of the function -* to remove all currently queued cells from a registered VC. The -* pending cell count for the specified VC is reset to zero. After the -* use of this callback, the scheduler shall not schedule more cells -* for this VC. -* -* This callback function is called during a VC disconnection -* @a ixAtmdAccTxVcTryDisconnect() -* -* @sa IxAtmdAccTxVcDemandUpdateCallback -* @sa IxAtmdAccTxVcDemandClearCallback -* @sa IxAtmdAccTxSchVcIdGetCallback -* @sa ixAtmdAccPortTxScheduledModeEnable -* @sa ixAtmdAccTxVcTryDisconnect -* -* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be cleared -* is established -* @param vcId int [in] - Identifies the VC to be cleared. This is the value -* returned by the @a IxAtmdAccTxSchVcIdGetCallback() call . -* -* @return none -* -*/ -typedef void (*IxAtmdAccTxVcDemandClearCallback) (IxAtmLogicalPort port, - int vcId); - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @brief prototype to get a scheduler vc id -* -* IxAtmdAccTxSchVcIdGetCallback is the prototype of the function to get -* a scheduler vcId -* -* @sa IxAtmdAccTxVcDemandUpdateCallback -* @sa IxAtmdAccTxVcDemandClearCallback -* @sa IxAtmdAccTxSchVcIdGetCallback -* @sa ixAtmdAccPortTxScheduledModeEnable -* -* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM logical port on which the VC is -* established -* @param vpi unsigned int [in] - For AAL0/AAL5 specifies the ATM vpi on which the -* VC is established. -* For OAM specifies the dedicated "OAM Tx channel" VPI. -* @param vci unsigned int [in] - For AAL0/AAL5 specifies the ATM vci on which the -* VC is established. -* For OAM specifies the dedicated "OAM Tx channel" VCI. -* @param connId @ref IxAtmConnId [in] - specifies the IxAtmdAcc connection Id already -* associated with this VC -* @param vcId int* [out] - pointer to a vcId -* -* @return @li IX_SUCCESS the function is returning a Scheduler vcId for this -* VC -* @return @li IX_FAIL the function cannot process scheduling for this VC. -* the contents of vcId is unspecified -* -*/ -typedef IX_STATUS (*IxAtmdAccTxSchVcIdGetCallback) (IxAtmLogicalPort port, - unsigned int vpi, - unsigned int vci, - IxAtmConnId connId, - int *vcId); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to RX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccRxDispatcherRegister ( - IxAtmRxQueueId queueId, - IxAtmdAccRxDispatcher callback) - * - * @brief Register a notification callback to be invoked when there is - * at least one entry on a particular Rx queue. - * - * This function registers a callback to be invoked when there is at - * least one entry in a particular queue. The registered callback is - * called every time when the hardware adds one or more pdus to the - * specified Rx queue. - * - * This function cannot be used when a Rx Vc using this queue is - * already existing. - * - * @note -The callback function can be the API function - * @a ixAtmdAccRxDispatch() : every time the threhold level - * of the queue is reached, the ixAtmdAccRxDispatch() is - * invoked to remove all entries from the queue. - * - * @sa ixAtmdAccRxDispatch - * @sa IxAtmdAccRxDispatcher - * - * @param queueId @ref IxAtmRxQueueId [in] RX queue identification - * @param callback @ref IxAtmdAccRxDispatcher [in] function triggering the delivery of incoming - * traffic. This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS Successful call to @a ixAtmdAccRxDispatcherRegister() - * @return @li IX_FAIL error in the parameters, or there is an - * already active RX VC for this queue or some unspecified - * internal error occurred. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxDispatcherRegister ( - IxAtmRxQueueId queueId, - IxAtmdAccRxDispatcher callback); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId, - unsigned int numberOfPdusToProcess, - unsigned int *numberOfPdusProcessedPtr) - * - * - * @brief Control function which executes Rx processing for a particular - * Rx stream. - * - * The @a IxAtmdAccRxDispatch() function is used to process received Pdus - * available from one of the two incoming RX streams. When this function - * is invoked, the incoming traffic (up to the number of PDUs passed as - * a parameter) will be transferred to the IxAtmdAcc users through the - * callback @a IxAtmdAccRxVcRxCallback(), as registered during the - * @a ixAtmdAccRxVcConnect() call. - * - * The user receive callbacks will be executed in the context of this - * function. - * - * Failing to use this function on a regular basis when there is traffic - * will block incoming traffic and can result in Pdus being dropped by - * the hardware. - * - * This should be used to control when received pdus are handed off from - * the hardware to Aal users from a particluar stream. The function can - * be used from a timer context, or can be registered as a callback in - * response to an rx stream threshold event, or can be used inside an - * active polling mechanism which is under user control. - * - * @note - The signature of this function is directly compatible with the - * callback prototype which can be register with @a ixAtmdAccRxDispatcherRegister(). - * - * @sa ixAtmdAccRxDispatcherRegister - * @sa IxAtmdAccRxVcRxCallback - * @sa ixAtmdAccRxVcFreeEntriesQuery - * - * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which RX queue to process. - * @param numberOfPdusToProcess unsigned int [in] - indicates the maxiumum number of PDU to - * remove from the RX queue. A value of IX_ATMDACC_ALLPDUS indicates - * to process all PDUs from the queue. This includes at least the PDUs - * in the queue when the fuction is invoked. Because of real-time - * constraints, there is no guarantee thatthe queue will be empty - * when the function exits. If this parameter is greater than the - * number of entries of the queues, the function will succeed - * and the parameter numberOfPdusProcessedPtr will reflect the exact - * number of PDUs processed. - * @param *numberOfPdusProcessedPtr unsigned int [out] - indicates the actual number of PDU - * processed during this call. This parameter cannot be a null - * pointer. - * - * @return @li IX_SUCCESS the number of PDUs as indicated in - * numberOfPdusProcessedPtr are removed from the RX queue and the VC callback - * are called. - * @return @li IX_FAIL invalid parameters or some unspecified internal - * error occured. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId, - unsigned int numberOfPdusToProcess, - unsigned int *numberOfPdusProcessedPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId, - unsigned int *numberOfPdusPtr) - * - * @brief Query the number of entries in a particular RX queue. - * - * This function is used to retrieve the number of pdus received by - * the hardware and ready for distribution to users. - * - * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query. - * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of available - * PDUs in the RX queue. This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the - * number of incoming pdus waiting in this queue - * @return @li IX_FAIL an error occurs during processing. - * The value in numberOfPdusPtr is unspecified. - * - * @note - This function is reentrant, doesn't use system resources - * and can be used from an interrupt context. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId, - unsigned int *numberOfPdusPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId, - unsigned int *numberOfPdusPtr) - * - * @brief Query the size of a particular RX queue. - * - * This function is used to retrieve the number of pdus the system is - * able to queue when reception is complete. - * - * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query. - * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of pdus - * the system is able to queue in the RX queue. This parameter - * cannot be a null pointer. - * - * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the - * number of pdus the system is able to queue. - * @return @li IX_FAIL an error occurs during processing. - * The value in numberOfPdusPtr is unspecified. - * - * @note - This function is reentrant, doesn't use system resources - * and can be used from an interrupt context. - * - */ -PUBLIC IX_STATUS ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId, - unsigned int *numberOfPdusPtr); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to TX traffic - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port, - unsigned int *numberOfCellsPtr) - * - * @brief Get the number of available cells the system can accept for - * transmission. - * - * The function is used to retrieve the number of cells that can be - * queued for transmission to the hardware. - * - * This number is based on the worst schedule table where one cell - * is stored in one schedule table entry, depending on the pdus size - * and mbuf size and fragmentation. - * - * This function doesn't use system resources and can be used from a - * timer context, or can be associated with a threshold event, or can - * be used inside an active polling mechanism - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param numberOfCellsPtr unsigned int* [out] - number of available cells. - * This parameter cannot be a null pointer. - * - * @sa ixAtmdAccPortTxProcess - * - * @return @li IX_SUCCESS numberOfCellsPtr contains the number of cells that can be scheduled - * for this port. - * @return @li IX_FAIL error in the parameters, or some processing error - * occured. - * - */ -PUBLIC IX_STATUS ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port, - unsigned int *numberOfCellsPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port, - unsigned int numberOfCells, - IxAtmdAccPortTxLowCallback callback) - * - * @brief Configure the Tx port threshold value and register a callback to handle - * threshold notifications. - * - * This function sets the threshold in cells - * - * @sa ixAtmdAccPortTxCallbackRegister - * @sa ixAtmdAccPortTxProcess - * @sa ixAtmdAccPortTxFreeEntriesQuery - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param numberOfCells unsigned int [in] - threshold value which triggers the callback - * invocation, This number has to be one of the - * values 0,1,2,4,8,16,32 .... - * The maximum value cannot be more than half of the txVc queue - * size (which can be retrieved using @a ixAtmdAccPortTxFreeEntriesQuery() - * before any Tx traffic is sent for this port) - * @param callback @ref IxAtmdAccPortTxLowCallback [in] - callback function to invoke when the threshold - * level is reached. - * This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS Successful call to @a ixAtmdAccPortTxCallbackRegister() - * @return @li IX_FAIL error in the parameters, Tx channel already set for this port - * threshold level is not correct or within the range regarding the - * queue size:or unspecified error during processing: - * - * @note - This callback function get called when the threshold level drops from - * (numberOfCells+1) cells to (numberOfCells) cells - * - * @note - This function should be called during system initialisation, - * outside an interrupt context - * - */ -PUBLIC IX_STATUS ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port, - unsigned int numberOfCells, - IxAtmdAccPortTxLowCallback callback); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port, - IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback, - IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback, - IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback) - * - * @brief Put the port into Scheduled Mode - * - * This function puts the specified port into scheduled mode of - * transmission which means an external s/w entity controls the - * transmission of cells on this port. This faciltates traffic shaping on - * the port. - * - * Any buffers submitted on a VC for this port will be queued in IxAtmdAcc. - * The transmission of these buffers to and by the hardware will be driven - * by a transmit schedule submitted regulary in calls to - * @a ixAtmdAccPortTxProcess() by traffic shaping entity. - * - * The transmit schedule is expected to be dynamic in nature based on - * the demand in cells for each VC on the port. Hence the callback - * parameters provided to this function allow IxAtmdAcc to inform the - * shaping entity of demand changes for each VC on the port. - * - * By default a port is in Unscheduled Mode so if this function is not - * called, transmission of data is done without sheduling rules, on a - * first-come, first-out basis. - * - * Once a port is put in scheduled mode it cannot be reverted to - * un-scheduled mode. Note that unscheduled mode is not supported - * in ixp425 1.0 - * - * @note - This function should be called before any VCs have be - * connected on a port. Otherwise this function call will return failure. - * - * @note - This function uses internal locks and should not be called from - * an interrupt context - * - * @sa IxAtmdAccTxVcDemandUpdateCallback - * @sa IxAtmdAccTxVcDemandClearCallback - * @sa IxAtmdAccTxSchVcIdGetCallback - * @sa ixAtmdAccPortTxProcess - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param vcDemandUpdateCallback @ref IxAtmdAccTxVcDemandUpdateCallback [in] - callback function used to update - * the number of outstanding cells for transmission. This parameter - * cannot be a null pointer. - * @param vcDemandClearCallback @ref IxAtmdAccTxVcDemandClearCallback [in] - callback function used to remove all - * clear the number of outstanding cells for a VC. This parameter - * cannot be a null pointer. - * @param vcIdGetCallback @ref IxAtmdAccTxSchVcIdGetCallback [in] - callback function used to exchange vc - * Identifiers between IxAtmdAcc and the entity supplying the - * transmit schedule. This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS scheduler registration is complete and the port - * is now in scheduled mode. - * @return @li IX_FAIL failed (wrong parameters, or traffic is already - * enabled on this port, possibly without ATM shaping) - * - */ -PUBLIC IX_STATUS ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port, - IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback, - IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback, - IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccPortTxProcess (IxAtmLogicalPort port, - IxAtmScheduleTable* scheduleTablePtr) - * - * @brief Transmit queue cells to the H/W based on the supplied schedule - * table. - * - * This function @a ixAtmdAccPortTxProcess() process the schedule - * table provided as a parameter to the function. As a result cells are - * sent to the underlaying hardware for transmission. - * - * The schedule table is executed in its entirety or not at all. So the - * onus is on the caller not to submit a table containing more cells than - * can be transmitted at that point. The maximum numbers that can be - * transmitted is guaranteed to be the number of cells as returned by the - * function @a ixAtmdAccPortTxFreeEntriesQuery(). - * - * When the scheduler is invoked on a threshold level, IxAtmdAcc gives the - * minimum number of cells (to ensure the callback will fire again later) - * and the maximum number of cells that @a ixAtmdAccPortTxProcess() - * will be able to process (assuming the ATM scheduler is able - * to produce the worst-case schedule table, i.e. one entry per cell). - * - * When invoked ouside a threshold level, the overall number of cells of - * the schedule table should be less than the number of cells returned - * by the @a ixAtmdAccPortTxFreeEntriesQuery() function. - * - * After invoking the @a ixAtmdAccPortTxProcess() function, it is the - * user choice to query again the queue level with the function - * @a ixAtmdAccPortTxFreeEntriesQuery() and, depending on a new cell - * number, submit an other schedule table. - * - * IxAtmdAcc will check that the number of cells in the schedule table - * is compatible with the current transmit level. If the - * - * Obsolete or invalid connection Id will be silently discarded. - * - * This function is not reentrant for the same port. - * - * This functions doesn't use system resources and can be used inside an - * interrupt context. - * - * This function is used as a response to the hardware requesting more - * cells to transmit. - * - * @sa ixAtmdAccPortTxScheduledModeEnable - * @sa ixAtmdAccPortTxFreeEntriesQuery - * @sa ixAtmdAccPortTxCallbackRegister - * @sa ixAtmdAccPortEnable - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * @param scheduleTablePtr @ref IxAtmScheduleTable* [in] - pointer to a scheduler update table. The - * content of this table is not modified by this function. This - * parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS the schedule table process is complete - * and cells are transmitted to the hardware - * @return @li IX_ATMDACC_WARNING : Traffic will be dropped: the schedule table exceed - * the hardware capacity If this error is ignored, further traffic - * and schedule will work correctly. - * Overscheduling does not occur when the schedule table does - * not contain more entries that the number of free entries returned - * by @a ixAtmdAccPortTxFreeEntriesQuery(). - * However, Disconnect attempts just after this error will fail permanently - * with the error code @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED, and it is - * necessary to disable the port to make @a ixAtmdAccTxVcTryDisconnect() - * successful. - * @return @li IX_FAIL a wrong parameter is supplied, or the format of - * the schedule table is invalid, or the port is not Enabled, or - * an internal severe error occured. No cells is transmitted to the hardware - * - * @note - If the failure is linked to an overschedule of data cells - * the result is an inconsistency in the output traffic (one or many - * cells may be missing and the traffic contract is not respected). - * - */ -PUBLIC IX_STATUS ixAtmdAccPortTxProcess (IxAtmLogicalPort port, - IxAtmScheduleTable* scheduleTablePtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess, - unsigned int *numberOfPdusProcessedPtr) - * - * @brief Process a number of pending transmit done pdus from the hardware. - * - * As a by-product of Atm transmit operation buffers which transmission - * is complete need to be recycled to users. This function is invoked - * to service the oustanding list of transmitted buffers and pass them - * to VC users. - * - * Users are handed back pdus by invoking the free callback registered - * during the @a ixAtmdAccTxVcConnect() call. - * - * There is a single Tx done stream servicing all active Atm Tx ports - * which can contain a maximum of 64 entries. If this stream fills port - * transmission will stop so this function must be call sufficently - * frequently to ensure no disruption to the transmit operation. - * - * This function can be used from a timer context, or can be associated - * with a TxDone level threshold event (see @a ixAtmdAccTxDoneDispatcherRegister() ), - * or can be used inside an active polling mechanism under user control. - * - * For ease of use the signature of this function is compatible with the - * TxDone threshold event callback prototype. - * - * This functions can be used inside an interrupt context. - * - * @sa ixAtmdAccTxDoneDispatcherRegister - * @sa IxAtmdAccTxVcBufferReturnCallback - * @sa ixAtmdAccTxDoneLevelQuery - * - * @param numberOfPdusToProcess unsigned int [in] - maxiumum number of pdus to remove - * from the TX Done queue - * @param *numberOfPdusProcessedPtr unsigned int [out] - number of pdus removed from - * the TX Done queue. This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS the number of pdus as indicated in - * numberOfPdusToProcess are removed from the TX Done hardware - * and passed to the user through the Tx Done callback registered - * during a call to @a ixAtmdAccTxVcConnect() - * @return @li IX_FAIL invalid parameters or numberOfPdusProcessedPtr is - * a null pointer or some unspecified internal error occured. - * - */ -PUBLIC IX_STATUS -ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess, - unsigned int *numberOfPdusProcessedPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr) - * - * @brief Query the current number of transmit pdus ready for - * recycling. - * - * This function is used to get the number of transmitted pdus which - * the hardware is ready to hand back to user. - * - * This function can be used from a timer context, or can be associated - * with a threshold event, on can be used inside an active polling - * mechanism - * - * @sa ixAtmdAccTxDoneDispatch - * - * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus transmitted - * at the time of this function call, and ready for recycling - * This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS numberOfPdusPtr contains the number of pdus - * ready for recycling at the time of this function call - * - * @return @li IX_FAIL wrong parameter (null pointer as parameter).or - * unspecified rocessing error occurs..The value in numberOfPdusPtr - * is unspecified. - * - */ -PUBLIC IX_STATUS -ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr) - * - * @brief Query the TxDone queue size. - * - * This function is used to get the number of pdus which - * the hardware is able to store after transmission is complete - * - * The returned value can be used to set a threshold and enable - * a callback to be notified when the number of pdus is going over - * the threshold. - * - * @sa ixAtmdAccTxDoneDispatcherRegister - * - * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus the system - * is able to queue after transmission - * - * @return @li IX_SUCCESS numberOfPdusPtr contains the the number of - * pdus the system is able to queue after transmission - * @return @li IX_FAIL wrong parameter (null pointer as parameter).or - * unspecified rocessing error occurs..The value in numberOfPdusPtr - * is unspecified. - * - * @note - This function is reentrant, doesn't use system resources - * and can be used from an interrupt context. - */ -PUBLIC IX_STATUS -ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus, - IxAtmdAccTxDoneDispatcher notificationCallback) - * - * @brief Configure the Tx Done stream threshold value and register a - * callback to handle threshold notifications. - * - * This function sets the threshold level in term of number of pdus at - * which the supplied notification function should be called. - * - * The higher the threshold value is, the less events will be necessary - * to process transmitted buffers. - * - * Transmitted buffers recycling implementation is a sytem-wide mechanism - * and needs to be set prior any traffic is started. If this threshold - * mechanism is not used, the user is responsible for polling the - * transmitted buffers thanks to @a ixAtmdAccTxDoneDispatch() and - * @a ixAtmdAccTxDoneLevelQuery() functions. - * - * This function should be called during system initialisation outside - * an interrupt context - * - * @sa ixAtmdAccTxDoneDispatcherRegister - * @sa ixAtmdAccTxDoneDispatch - * @sa ixAtmdAccTxDoneLevelQuery - * - * @param numberOfPdus unsigned int [in] - The number of TxDone pdus which triggers the - * callback invocation This number has to be a power of 2, one of the - * values 0,1,2,4,8,16,32 ... - * The maximum value cannot be more than half of the txDone queue - * size (which can be retrieved using @a ixAtmdAccTxDoneQueueSizeQuery()) - * @param notificationCallback @ref IxAtmdAccTxDoneDispatcher [in] - The function to invoke. (This - * parameter can be @a ixAtmdAccTxDoneDispatch()).This - * parameter ust not be a null pointer. - * - * @return @li IX_SUCCESS Successful call to ixAtmdAccTxDoneDispatcherRegister - * @return @li IX_FAIL error in the parameters: - * - * @note - The notificationCallback will be called exactly when the threshold level - * will increase from (numberOfPdus) to (numberOfPdus+1) - * - * @note - If there is no Tx traffic, there is no guarantee that TxDone Pdus will - * be released to the user (when txDone level is permanently under the threshold - * level. One of the preffered way to return resources to the user is to use - * a mix of txDone notifications, used together with a slow - * rate timer and an exclusion mechanism protecting from re-entrancy - * - * @note - The TxDone threshold will only hand back buffers when the threshold level is - * crossed. Setting this threshold to a great number reduce the interrupt rate - * and the cpu load, but also increase the number of outstanding mbufs and has - * a system wide impact when these mbufs are needed by other components. - * - */ -PUBLIC IX_STATUS ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus, - IxAtmdAccTxDoneDispatcher notificationCallback); - -/* ------------------------------------------------------ - Part of the IxAtmdAcc interface related to Utopia config - ------------------------------------------------------ */ - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @defgroup IxAtmdAccUtopiaCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Utopia Control API - * - * @brief The public API for the IXP400 Atm Driver Control component - * - * IxAtmdAcc is the low level interface by which AAL PDU get - * transmitted to,and received from the Utopia bus - * - * This part is related to the UTOPIA configuration. - * - * @{ - */ - -/** - * - * @brief Utopia configuration - * - * This structure is used to set the Utopia parameters - * @li contains the values of Utopia registers, to be set during initialisation - * @li contains debug commands for NPE, to be used during development steps - * - * @note - the exact description of all parameters is done in the Utopia reference - * documents. - * - */ -typedef struct -{ - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxConfig_ - * @brief Utopia Tx Config Register - */ - struct UtTxConfig_ - { - - unsigned int reserved_1:1; /**< [31] These bits are always 0.*/ - unsigned int txInterface:1; /**< [30] Utopia Transmit Interface. The following encoding - * is used to set the Utopia Transmit interface as ATM master - * or PHY slave: - * @li 1 - PHY - * @li 0 - ATM - */ - unsigned int txMode:1; /**< [29] Utopia Transmit Mode. The following encoding is used - * to set the Utopia Transmit mode to SPHY or MPHY: - * @li 1 - SPHY - * @li 0 - MPHY - */ - unsigned int txOctet:1; /**< [28] Utopia Transmit cell transfer protocol. Used to set - * the Utopia cell transfer protocol to Octet-level handshaking. - * Note this is only applicable in SPHY mode. - * @li 1 - Octet-handshaking enabled - * @li 0 - Cell-handshaking enabled - */ - unsigned int txParity:1; /**< [27] Utopia Transmit parity enabled when set. TxEvenParity - * defines the parity format odd/even. - * @li 1 - Enable Parity generation. - * @li 0 - ut_op_prty held low. - */ - unsigned int txEvenParity:1; /**< [26] Utopia Transmit Parity Mode - * @li 1 - Even Parity Generated. - * @li 0 - Odd Parity Generated. - */ - unsigned int txHEC:1; /**< [25] Header Error Check Insertion Mode. Specifies if the transmit - * cell header check byte is calculated and inserted when set. - * @li 1 - Generate HEC. - * @li 0 - Disable HEC generation. - */ - unsigned int txCOSET:1; /**< [24] If enabled the HEC is Exclusive-OR'ed with the value 0x55 before - * being presented on the Utopia bus. - * @li 1 - Enable HEC ExOR with value 0x55 - * @li 0 - Use generated HEC value. - */ - - unsigned int reserved_2:1; /**< [23] These bits are always 0 - */ - unsigned int txCellSize:7; /**< [22:16] Transmit expected cell size. Configures the cell size - * for the transmit module: Values between 52-64 are valid. - */ - unsigned int reserved_3:3; /**< [15:13] These bits are always 0 */ - unsigned int txAddrRange:5; /**< [12:8] When configured as an ATM master in MPHY mode this - * register specifies the upper limit of the PHY polling logical - * range. The number of active PHYs are TxAddrRange + 1. - */ - unsigned int reserved_4:3; /**< [7:5] These bits are always 0 */ - unsigned int txPHYAddr:5; /**< [4:0] When configured as a slave in an MPHY system this register - * specifies the physical address of the PHY. - */ - } - - utTxConfig; /**< Tx config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxStatsConfig_ - * @brief Utopia Tx stats Register - */ - struct UtTxStatsConfig_ - { - - unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] - @li Note: if VCStatsTxGFC is set to 0 the GFC field is ignored in test. */ - - unsigned int vci:16; /**< [19:4] ATM VCI [15:0] or PHY Address[4] */ - - unsigned int pti:3; /**< [3:1] ATM PTI [2:0] or PHY Address[3:1] - @li Note: if VCStatsTxPTI is set to 0 the PTI field is ignored in test. - @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port - address as defined by this register is used for ATM statistics [4:0]. */ - - unsigned int clp:1; /**< [0] ATM CLP or PHY Address [0] - @li Note: if VCStatsTxCLP is set to 0 the CLP field is ignored in test. - @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port - address as defined by this register is used for ATM statistics [4:0]. */ - } - - utTxStatsConfig; /**< Tx stats config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxDefineIdle_ - * @brief Utopia Tx idle cells Register - */ - struct UtTxDefineIdle_ - { - - unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] - @li Note: if VCIdleTxGFC is set to 0 the GFC field is ignored in test. */ - - unsigned int vci:16; /**< [19:4] ATM VCI [15:0] */ - - unsigned int pti:3; /**< [3:1] ATM PTI PTI [2:0] - @li Note: if VCIdleTxPTI is set to 0 the PTI field is ignored in test.*/ - - unsigned int clp:1; /**< [0] ATM CLP [0] - @li Note: if VCIdleTxCLP is set to 0 the CLP field is ignored in test.*/ - } - - utTxDefineIdle; /**< Tx idle cell config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxEnableFields_ - * @brief Utopia Tx ienable fields Register - */ - struct UtTxEnableFields_ - { - - unsigned int defineTxIdleGFC:1; /**< [31] This register is used to include or exclude the GFC - field of the ATM header when testing for Idle cells. - @li 1 - GFC field is valid. - @li 0 - GFC field ignored.*/ - - unsigned int defineTxIdlePTI:1; /**< [30] This register is used to include or exclude the PTI - field of the ATM header when testing for Idle cells. - @li 1 - PTI field is valid - @li 0 - PTI field ignored.*/ - - unsigned int defineTxIdleCLP:1; /**< [29] This register is used to include or - exclude the CLP field of the ATM header when testing for Idle cells. - @li 1 - CLP field is valid. - @li 0 - CLP field ignored. */ - - unsigned int phyStatsTxEnb:1; /**< [28] This register is used to enable or disable ATM - statistics gathering based on the specified PHY address as defined - in TxStatsConfig register. - @li 1 - Enable statistics for specified transmit PHY address. - @li 0 - Disable statistics for specified transmit PHY address. */ - - unsigned int vcStatsTxEnb:1; /**< [27] This register is used to change the ATM - statistics-gathering mode from the specified logical PHY address - to a specific VPI/VCI address. - @li 1 - Enable statistics for specified VPI/VCI address. - @li 0 - Disable statistics for specified VPI/VCI address */ - - unsigned int vcStatsTxGFC:1; /**< [26] This register is used to include or exclude the GFC - field of the ATM header when ATM VPI/VCI statistics are enabled. - GFC is only available at the UNI and uses the first 4-bits of - the VPI field. - @li 1 - GFC field is valid - @li 0 - GFC field ignored.*/ - - unsigned int vcStatsTxPTI:1; /**< [25] This register is used to include or exclude the PTI - field of the ATM header when ATM VPI/VCI statistics are enabled. - @li 1 - PTI field is valid - @li 0 - PTI field ignored.*/ - - unsigned int vcStatsTxCLP:1; /**< [24] This register is used to include or exclude the CLP - field of the ATM header when ATM VPI/VCI statistics are enabled. - @li 1 - CLP field is valid - @li 0 - CLP field ignored. */ - - unsigned int reserved_1:3; /**< [23-21] These bits are always 0 */ - - unsigned int txPollStsInt:1; /**< [20] Enable the assertion of the ucp_tx_poll_sts condition - where there is a change in polling status. - @li 1 - ucp_tx_poll_sts asserted whenever there is a change in status - @li 0 - ucp_tx_poll_sts asserted if ANY transmit PHY is available - */ - unsigned int txCellOvrInt:1; /**< [19] Enable TxCellCount overflow CBI Transmit Status condition - assertion. - @li 1 - If TxCellCountOvr is set assert the Transmit Status Condition. - @li 0 - No CBI Transmit Status condition assertion */ - - unsigned int txIdleCellOvrInt:1; /**< [18] Enable TxIdleCellCount overflow Transmit Status Condition - @li 1 - If TxIdleCellCountOvr is set assert the Transmit Status Condition - @li 0 - No CBI Transmit Status condition assertion..*/ - - unsigned int enbIdleCellCnt:1; /**< [17] Enable Transmit Idle Cell Count. - @li 1 - Enable count of Idle cells transmitted. - @li 0 - No count is maintained. */ - - unsigned int enbTxCellCnt:1; /**< [16] Enable Transmit Valid Cell Count of non-idle/non-error cells - @li 1 - Enable count of valid cells transmitted- non-idle/non-error - @li 0 - No count is maintained.*/ - - unsigned int reserved_2:16; /**< [15:0] These bits are always 0 */ - } utTxEnableFields; /**< Tx enable Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable0_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable0_ - { - - unsigned int phy0:5; /**< [31-27] Tx Mapping value of logical phy 0 */ - - unsigned int phy1:5; /**< [26-22] Tx Mapping value of logical phy 1 */ - - unsigned int phy2:5; /**< [21-17] Tx Mapping value of logical phy 2 */ - - unsigned int reserved_1:1; /**< [16] These bits are always 0.*/ - - unsigned int phy3:5; /**< [15-11] Tx Mapping value of logical phy 3 */ - - unsigned int phy4:5; /**< [10-6] Tx Mapping value of logical phy 4 */ - - unsigned int phy5:5; /**< [5-1] Tx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utTxTransTable0; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable1_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable1_ - { - - unsigned int phy6:5; /**< [31-27] Tx Mapping value of logical phy 6 */ - - unsigned int phy7:5; /**< [26-22] Tx Mapping value of logical phy 7 */ - - unsigned int phy8:5; /**< [21-17] Tx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy9:5; /**< [15-11] Tx Mapping value of logical phy 3 */ - - unsigned int phy10:5; /**< [10-6] Tx Mapping value of logical phy 4 */ - - unsigned int phy11:5; /**< [5-1] Tx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utTxTransTable1; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable2_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable2_ - { - - unsigned int phy12:5; /**< [31-27] Tx Mapping value of logical phy 6 */ - - unsigned int phy13:5; /**< [26-22] Tx Mapping value of logical phy 7 */ - - unsigned int phy14:5; /**< [21-17] Tx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy15:5; /**< [15-11] Tx Mapping value of logical phy 3 */ - - unsigned int phy16:5; /**< [10-6] Tx Mapping value of logical phy 4 */ - - unsigned int phy17:5; /**< [5-1] Tx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utTxTransTable2; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable3_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable3_ - { - - unsigned int phy18:5; /**< [31-27] Tx Mapping value of logical phy 6 */ - - unsigned int phy19:5; /**< [26-22] Tx Mapping value of logical phy 7 */ - - unsigned int phy20:5; /**< [21-17] Tx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy21:5; /**< [15-11] Tx Mapping value of logical phy 3 */ - - unsigned int phy22:5; /**< [10-6] Tx Mapping value of logical phy 4 */ - - unsigned int phy23:5; /**< [5-1] Tx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utTxTransTable3; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable4_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable4_ - { - - unsigned int phy24:5; /**< [31-27] Tx Mapping value of logical phy 6 */ - - unsigned int phy25:5; /**< [26-22] Tx Mapping value of logical phy 7 */ - - unsigned int phy26:5; /**< [21-17] Tx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy27:5; /**< [15-11] Tx Mapping value of logical phy 3 */ - - unsigned int phy28:5; /**< [10-6] Tx Mapping value of logical phy 4 */ - - unsigned int phy29:5; /**< [5-1] Tx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utTxTransTable4; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxTransTable5_ - * @brief Utopia Tx translation table Register - */ - struct UtTxTransTable5_ - { - - unsigned int phy30:5; /**< [31-27] Tx Mapping value of logical phy 6 */ - - unsigned int reserved_1:27; /**< [26-0] These bits are always 0 */ - - } utTxTransTable5; /**< Tx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxConfig_ - * @brief Utopia Rx config Register - */ - struct UtRxConfig_ - { - - unsigned int rxInterface:1; /**< [31] Utopia Receive Interface. The following encoding is used - to set the Utopia Receive interface as ATM master or PHY slave: - @li 1 - PHY - @li 0 - ATM */ - - unsigned int rxMode:1; /**< [30] Utopia Receive Mode. The following encoding is used to set - the Utopia Receive mode to SPHY or MPHY: - @li 1 - SPHY - @li 0 - MPHY */ - - unsigned int rxOctet:1; /**< [29] Utopia Receive cell transfer protocol. Used to set the Utopia - cell transfer protocol to Octet-level handshaking. Note this is only - applicable in SPHY mode. - @li 1 - Octet-handshaking enabled - @li 0 - Cell-handshaking enabled */ - - unsigned int rxParity:1; /**< [28] Utopia Receive Parity Checking enable. - @li 1 - Parity checking enabled - @li 0 - Parity checking disabled */ - - unsigned int rxEvenParity:1;/**< [27] Utopia Receive Parity Mode - @li 1 - Check for Even Parity - @li 0 - Check for Odd Parity.*/ - - unsigned int rxHEC:1; /**< [26] RxHEC Header Error Check Mode. Enables/disables cell header - error checking on the received cell header. - @li 1 - HEC checking enabled - @li 0 - HEC checking disabled */ - - unsigned int rxCOSET:1; /**< [25] If enabled the HEC is Exclusive-OR'ed with the value 0x55 - before being tested with the received HEC. - @li 1 - Enable HEC ExOR with value 0x55. - @li 0 - Use generated HEC value.*/ - - unsigned int rxHECpass:1; /**< [24] Specifies if the incoming cell HEC byte should be transferred - after optional processing to the NPE2 Coprocessor Bus Interface or - if it should be discarded. - @li 1 - HEC maintained 53-byte/UDC cell sent to NPE2. - @li 0 - HEC discarded 52-byte/UDC cell sent to NPE2 coprocessor.*/ - - unsigned int reserved_1:1; /**< [23] These bits are always 0 */ - - unsigned int rxCellSize:7; /**< [22:16] Receive cell size. Configures the receive cell size. - Values between 52-64 are valid */ - - unsigned int rxHashEnbGFC:1; /**< [15] Specifies if the VPI field [11:8]/GFC field should be - included in the Hash data input or if the bits should be padded - with 1'b0. - @li 1 - VPI [11:8]/GFC field valid and used in Hash residue calculation. - @li 0 - VPI [11:8]/GFC field padded with 1'b0 */ - - unsigned int rxPreHash:1; /**< [14] Enable Pre-hash value generation. Specifies if the - incoming cell data should be pre-hashed to allow VPI/VCI header look-up - in a hash table. - @li 1 - Pre-hashing enabled - @li 0 - Pre-hashing disabled */ - - unsigned int reserved_2:1; /**< [13] These bits are always 0 */ - - unsigned int rxAddrRange:5; /**< [12:8] In ATM master, MPHY mode, - * this register specifies the upper - * limit of the PHY polling logical range. The number of active PHYs are - * RxAddrRange + 1. - */ - unsigned int reserved_3:3; /**< [7-5] These bits are always 0 .*/ - unsigned int rxPHYAddr:5; /**< [4:0] When configured as a slave in an MPHY system this register - * specifies the physical address of the PHY. - */ - } utRxConfig; /**< Rx config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxStatsConfig_ - * @brief Utopia Rx stats config Register - */ - struct UtRxStatsConfig_ - { - - unsigned int vpi:12; /**< [31:20] ATM VPI VPI [11:0] OR GFC [3:0] and VPI [7:0] - @li Note: if VCStatsRxGFC is set to 0 the GFC field is ignored in test. */ - - unsigned int vci:16; /**< [19:4] VCI [15:0] or PHY Address [4] */ - - unsigned int pti:3; /**< [3:1] PTI [2:0] or or PHY Address [3:1] - @li Note: if VCStatsRxPTI is set to 0 the PTI field is ignored in test. - @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used - for statistics gathering.. */ - - unsigned int clp:1; /**< [0] CLP [0] or PHY Address [0] - @li Note: if VCStatsRxCLP is set to 0 the CLP field is ignored in test. - @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used - for statistics gathering.. */ - } utRxStatsConfig; /**< Rx stats config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxDefineIdle_ - * @brief Utopia Rx idle cells config Register - */ - struct UtRxDefineIdle_ - { - - unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] - @li Note: if VCIdleRxGFC is set to 0 the GFC field is ignored in test. */ - - unsigned int vci:16; /**< [19:4] ATM VCI [15:0] */ - - unsigned int pti:3; /**< [3:1] ATM PTI PTI [2:0] - @li Note: if VCIdleRxPTI is set to 0 the PTI field is ignored in test.*/ - - unsigned int clp:1; /**< [0] ATM CLP [0] - @li Note: if VCIdleRxCLP is set to 0 the CLP field is ignored in test.*/ - } utRxDefineIdle; /**< Rx idle cell config Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxEnableFields_ - * @brief Utopia Rx enable Register - */ - struct UtRxEnableFields_ - { - - unsigned int defineRxIdleGFC:1;/**< [31] This register is used to include or exclude the GFC - field of the ATM header when testing for Idle cells. - @li 1 - GFC field is valid. - @li 0 - GFC field ignored.*/ - - unsigned int defineRxIdlePTI:1;/**< [30] This register is used to include or exclude the PTI - field of the ATM header when testing for Idle cells. - @li 1 - PTI field is valid. - @li 0 - PTI field ignored.*/ - - unsigned int defineRxIdleCLP:1;/**< [29] This register is used to include or exclude the CLP - field of the ATM header when testing for Idle cells. - @li 1 - CLP field is valid. - @li 0 - CLP field ignored.*/ - - unsigned int phyStatsRxEnb:1;/**< [28] This register is used to enable or disable ATM statistics - gathering based on the specified PHY address as defined in RxStatsConfig - register. - @li 1 - Enable statistics for specified receive PHY address. - @li 0 - Disable statistics for specified receive PHY address.*/ - - unsigned int vcStatsRxEnb:1;/**< [27] This register is used to enable or disable ATM statistics - gathering based on a specific VPI/VCI address. - @li 1 - Enable statistics for specified VPI/VCI address. - @li 0 - Disable statistics for specified VPI/VCI address.*/ - - unsigned int vcStatsRxGFC:1;/**< [26] This register is used to include or exclude the GFC field - of the ATM header when ATM VPI/VCI statistics are enabled. GFC is only - available at the UNI and uses the first 4-bits of the VPI field. - @li 1 - GFC field is valid. - @li 0 - GFC field ignored. */ - - unsigned int vcStatsRxPTI:1;/**< [25] This register is used to include or exclude the PTI field - of the ATM header when ATM VPI/VCI statistics are enabled. - @li 1 - PTI field is valid. - @li 0 - PTI field ignored.*/ - - unsigned int vcStatsRxCLP:1;/**< [24] This register is used to include or exclude the CLP field - of the ATM header when ATM VPI/VCI statistics are enabled. - @li 1 - CLP field is valid. - @li 0 - CLP field ignored. */ - - unsigned int discardHecErr:1;/**< [23] Discard cells with an invalid HEC. - @li 1 - Discard cells with HEC errors - @li 0 - Cells with HEC errors are passed */ - - unsigned int discardParErr:1;/**< [22] Discard cells containing parity errors. - @li 1 - Discard cells with parity errors - @li 0 - Cells with parity errors are passed */ - - unsigned int discardIdle:1; /**< [21] Discard Idle Cells based on DefineIdle register values - @li 1 - Discard IDLE cells - @li 0 - IDLE cells passed */ - - unsigned int enbHecErrCnt:1;/**< [20] Enable Receive HEC Error Count. - @li 1 - Enable count of received cells containing HEC errors - @li 0 - No count is maintained. */ - - unsigned int enbParErrCnt:1;/**< [19] Enable Parity Error Count - @li 1 - Enable count of received cells containing Parity errors - @li 0 - No count is maintained. */ - - unsigned int enbIdleCellCnt:1;/**< [18] Enable Receive Idle Cell Count. - @li 1 - Enable count of Idle cells received. - @li 0 - No count is maintained.*/ - - unsigned int enbSizeErrCnt:1;/**< [17] Enable Receive Size Error Count. - @li 1 - Enable count of received cells of incorrect size - @li 0 - No count is maintained. */ - - unsigned int enbRxCellCnt:1;/**< [16] Enable Receive Valid Cell Count of non-idle/non-error cells. - @li 1 - Enable count of valid cells received - non-idle/non-error - @li 0 - No count is maintained. */ - - unsigned int reserved_1:3; /**< [15:13] These bits are always 0 */ - - unsigned int rxCellOvrInt:1; /**< [12] Enable CBI Utopia Receive Status Condition if the RxCellCount - register overflows. - @li 1 - CBI Receive Status asserted. - @li 0 - No CBI Receive Status asserted.*/ - - unsigned int invalidHecOvrInt:1; /**< [11] Enable CBI Receive Status Condition if the InvalidHecCount - register overflows. - @li 1 - CBI Receive Condition asserted. - @li 0 - No CBI Receive Condition asserted */ - - unsigned int invalidParOvrInt:1; /**< [10] Enable CBI Receive Status Condition if the InvalidParCount - register overflows - @li 1 - CBI Receive Condition asserted. - @li 0 - No CBI Receive Condition asserted */ - - unsigned int invalidSizeOvrInt:1; /**< [9] Enable CBI Receive Status Condition if the InvalidSizeCount - register overflows. - @li 1 - CBI Receive Status Condition asserted. - @li 0 - No CBI Receive Status asserted */ - - unsigned int rxIdleOvrInt:1; /**< [8] Enable CBI Receive Status Condition if the RxIdleCount overflows. - @li 1 - CBI Receive Condition asserted. - @li 0 - No CBI Receive Condition asserted */ - - unsigned int reserved_2:3; /**< [7:5] These bits are always 0 */ - - unsigned int rxAddrMask:5; /**< [4:0] This register is used as a mask to allow the user to increase - the PHY receive address range. The register should be programmed with - the address-range limit, i.e. if set to 0x3 the address range increases - to a maximum of 4 addresses. */ - } utRxEnableFields; /**< Rx enable Utopia register */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable0_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable0_ - { - - unsigned int phy0:5; /**< [31-27] Rx Mapping value of logical phy 0 */ - - unsigned int phy1:5; /**< [26-22] Rx Mapping value of logical phy 1 */ - - unsigned int phy2:5; /**< [21-17] Rx Mapping value of logical phy 2 */ - - unsigned int reserved_1:1; /**< [16] These bits are always 0 */ - - unsigned int phy3:5; /**< [15-11] Rx Mapping value of logical phy 3 */ - - unsigned int phy4:5; /**< [10-6] Rx Mapping value of logical phy 4 */ - - unsigned int phy5:5; /**< [5-1] Rx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } - - utRxTransTable0; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable1_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable1_ - { - - unsigned int phy6:5; /**< [31-27] Rx Mapping value of logical phy 6 */ - - unsigned int phy7:5; /**< [26-22] Rx Mapping value of logical phy 7 */ - - unsigned int phy8:5; /**< [21-17] Rx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy9:5; /**< [15-11] Rx Mapping value of logical phy 3 */ - - unsigned int phy10:5; /**< [10-6] Rx Mapping value of logical phy 4 */ - - unsigned int phy11:5; /**< [5-1] Rx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } - - utRxTransTable1; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable2_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable2_ - { - - unsigned int phy12:5; /**< [31-27] Rx Mapping value of logical phy 6 */ - - unsigned int phy13:5; /**< [26-22] Rx Mapping value of logical phy 7 */ - - unsigned int phy14:5; /**< [21-17] Rx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy15:5; /**< [15-11] Rx Mapping value of logical phy 3 */ - - unsigned int phy16:5; /**< [10-6] Rx Mapping value of logical phy 4 */ - - unsigned int phy17:5; /**< [5-1] Rx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utRxTransTable2; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable3_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable3_ - { - - unsigned int phy18:5; /**< [31-27] Rx Mapping value of logical phy 6 */ - - unsigned int phy19:5; /**< [26-22] Rx Mapping value of logical phy 7 */ - - unsigned int phy20:5; /**< [21-17] Rx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy21:5; /**< [15-11] Rx Mapping value of logical phy 3 */ - - unsigned int phy22:5; /**< [10-6] Rx Mapping value of logical phy 4 */ - - unsigned int phy23:5; /**< [5-1] Rx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utRxTransTable3; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable4_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable4_ - { - - unsigned int phy24:5; /**< [31-27] Rx Mapping value of logical phy 6 */ - - unsigned int phy25:5; /**< [26-22] Rx Mapping value of logical phy 7 */ - - unsigned int phy26:5; /**< [21-17] Rx Mapping value of logical phy 8 */ - - unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ - - unsigned int phy27:5; /**< [15-11] Rx Mapping value of logical phy 3 */ - - unsigned int phy28:5; /**< [10-6] Rx Mapping value of logical phy 4 */ - - unsigned int phy29:5; /**< [5-1] Rx Mapping value of logical phy 5 */ - - unsigned int reserved_2:1; /**< [0] These bits are always 0 */ - } utRxTransTable4; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxTransTable5_ - * @brief Utopia Rx translation table Register - */ - struct UtRxTransTable5_ - { - - unsigned int phy30:5; /**< [31-27] Rx Mapping value of logical phy 6 */ - - unsigned int reserved_1:27; /**< [26-0] These bits are always 0 */ - - } utRxTransTable5; /**< Rx translation table */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtSysConfig_ - * @brief NPE setup Register - */ - struct UtSysConfig_ - { - - unsigned int reserved_1:2; /**< [31-30] These bits are always 0 */ - unsigned int txEnbFSM:1; /**< [29] Enables the operation ofthe Utopia Transmit FSM - * @li 1 - FSM enabled - * @li 0 - FSM inactive - */ - unsigned int rxEnbFSM:1; /**< [28] Enables the operation ofthe Utopia Revieve FSM - * @li 1 - FSM enabled - * @li 0 - FSM inactive - */ - unsigned int disablePins:1; /**< [27] Disable Utopia interface I/O pins forcing the signals to an - * inactive state. Note that this bit is set on reset and must be - * de-asserted - * @li 0 - Normal data transfer - * @li 1 - Utopia interface pins are forced inactive - */ - unsigned int tstLoop:1; /**< [26] Test Loop Back Enable. - * @li Note: For loop back to function RxMode and Tx Mode must both be set - * to single PHY mode. - * @li 0 - Loop back - * @li 1 - Normal operating mode - */ - - unsigned int txReset:1; /**< [25] Resets the Utopia Coprocessor transmit module to a known state. - * @li Note: All transmit configuration and status registers will be reset - * to their reset values. - * @li 0 - Normal operating mode - * @li 1 - Reset transmit modules - */ - - unsigned int rxReset:1; /**< [24] Resets the Utopia Coprocessor receive module to a known state. - * @li Note: All receive configuration and status registers will be reset - * to their reset values. - * @li 0 - Normal operating mode - * @li 1 - Reset receive modules - */ - - unsigned int reserved_2:24; /**< [23-0] These bits are always 0 */ - } utSysConfig; /**< NPE debug config */ - -} -IxAtmdAccUtopiaConfig; - -/** -* -* @brief Utopia status -* -* This structure is used to set/get the Utopia status parameters -* @li contains debug cell counters, to be accessed during a read operation -* -* @note - the exact description of all parameters is done in the Utopia reference -* documents. -* -*/ -typedef struct -{ - - unsigned int utTxCellCount; /**< count of cells transmitted */ - - unsigned int utTxIdleCellCount; /**< count of idle cells transmitted */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtTxCellConditionStatus_ - * @brief Utopia Tx Status Register - */ - struct UtTxCellConditionStatus_ - { - - unsigned int reserved_1:2; /**< [31:30] These bits are always 0 */ - unsigned int txFIFO2Underflow:1; /**< [29] This bit is set if 64-byte - * Transmit FIFO2 indicates a FIFO underflow - * error condition. - */ - unsigned int txFIFO1Underflow:1; /**< [28] This bit is set if - * 64-byte Transmit FIFO1 indicates a FIFO - * underflow error condition. - */ - unsigned int txFIFO2Overflow:1; /**< [27] This bit is set if 64-byte - * Transmit FIFO2 indicates a FIFO overflow - * error condition. - */ - unsigned int txFIFO1Overflow:1; /**< [26] This bit is set if 64-byte - * Transmit FIFO1 indicates a FIFO overflow - * error condition. - */ - unsigned int txIdleCellCountOvr:1; /**< [25] This bit is set if the - * TxIdleCellCount register overflows. - */ - unsigned int txCellCountOvr:1; /**< [24] This bit is set if the - * TxCellCount register overflows - */ - unsigned int reserved_2:24; /**< [23:0] These bits are always 0 */ - } utTxCellConditionStatus; /**< Tx cells condition status */ - - unsigned int utRxCellCount; /**< count of cell received */ - unsigned int utRxIdleCellCount; /**< count of idle cell received */ - unsigned int utRxInvalidHECount; /**< count of invalid cell - * received because of HEC errors - */ - unsigned int utRxInvalidParCount; /**< count of invalid cell received - * because of parity errors - */ - unsigned int utRxInvalidSizeCount; /**< count of invalid cell - * received because of cell - * size errors - */ - - /** - * @ingroup IxAtmdAccUtopiaCtrlAPI - * @struct UtRxCellConditionStatus_ - * @brief Utopia Rx Status Register - */ - struct UtRxCellConditionStatus_ - { - - unsigned int reserved_1:3; /**< [31:29] These bits are always 0.*/ - unsigned int rxCellCountOvr:1; /**< [28] This bit is set if the RxCellCount register overflows. */ - unsigned int invalidHecCountOvr:1; /**< [27] This bit is set if the InvalidHecCount register overflows.*/ - unsigned int invalidParCountOvr:1; /**< [26] This bit is set if the InvalidParCount register overflows.*/ - unsigned int invalidSizeCountOvr:1; /**< [25] This bit is set if the InvalidSizeCount register overflows.*/ - unsigned int rxIdleCountOvr:1; /**< [24] This bit is set if the RxIdleCount register overflows.*/ - unsigned int reserved_2:4; /**< [23:20] These bits are always 0 */ - unsigned int rxFIFO2Underflow:1; /**< [19] This bit is set if 64-byte Receive FIFO2 - * indicates a FIFO underflow error condition. - */ - unsigned int rxFIFO1Underflow:1; /**< [18] This bit is set if 64-byte Receive - * FIFO1 indicates a FIFO underflow error condition - . */ - unsigned int rxFIFO2Overflow:1; /**< [17] This bit is set if 64-byte Receive FIFO2 - * indicates a FIFO overflow error condition. - */ - unsigned int rxFIFO1Overflow:1; /**< [16] This bit is set if 64-byte Receive FIFO1 - * indicates a FIFO overflow error condition. - */ - unsigned int reserved_3:16; /**< [15:0] These bits are always 0. */ - } utRxCellConditionStatus; /**< Rx cells condition status */ - -} IxAtmdAccUtopiaStatus; - -/** - * @} defgroup IxAtmdAccUtopiaCtrlAPI - */ - - /** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig * - ixAtmdAccUtopiaConfigPtr) - * - * @brief Send the configuration structure to the Utopia interface - * - * This function downloads the @a IxAtmdAccUtopiaConfig structure to - * the Utopia and has the following effects - * @li setup the Utopia interface - * @li initialise the NPE - * @li reset the Utopia cell counters and status registers to known values - * - * This action has to be done once at initialisation. A lock is preventing - * the concurrent use of @a ixAtmdAccUtopiaStatusGet() and - * @A ixAtmdAccUtopiaConfigSet() - * - * @param *ixAtmdAccNPEConfigPtr @ref IxAtmdAccUtopiaConfig [in] - pointer to a structure to download to - * Utopia. This parameter cannot be a null pointer. - * - * @return @li IX_SUCCESS successful download - * @return @li IX_FAIL error in the parameters, or configuration is not - * complete or failed - * - * @sa ixAtmdAccUtopiaStatusGet - * - */ -PUBLIC IX_STATUS ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig * - ixAtmdAccUtopiaConfigPtr); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus * - ixAtmdAccUtopiaStatus) - * - * @brief Get the Utopia interface configuration. - * - * This function reads the Utopia registers and the Cell counts - * and fills the @a IxAtmdAccUtopiaStatus structure - * - * A lock is preventing the concurrent - * use of @a ixAtmdAccUtopiaStatusGet() and @A ixAtmdAccUtopiaConfigSet() - * - * @param ixAtmdAccUtopiaStatus @ref IxAtmdAccUtopiaStatus [out] - pointer to structure to be updated from internal - * hardware counters. This parameter cannot be a NULL pointer. - * - * @return @li IX_SUCCESS successful read - * @return @li IX_FAIL error in the parameters null pointer, or - * configuration read is not complete or failed - * - * @sa ixAtmdAccUtopiaConfigSet - * - */ -PUBLIC IX_STATUS ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus * - ixAtmdAccUtopiaStatus); - -/** - * - * @ingroup IxAtmdAcc - * - * @fn ixAtmdAccPortEnable (IxAtmLogicalPort port) - * - * @brief enable a PHY logical port - * - * This function enables the transmission over one port. It should be - * called before accessing any resource from this port and before the - * establishment of a VC. - * - * When a port is enabled, the cell transmission to the Utopia interface - * is started. If there is no traffic already running, idle cells are - * sent over the interface. - * - * This function can be called multiple times. - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * - * @return @li IX_SUCCESS enable is complete - * @return @li IX_ATMDACC_WARNING port already enabled - * @return @li IX_FAIL enable failed, wrong parameter, or cannot - * initialise this port (the port is maybe already in use, - * or there is a hardware issue) - * - * @note - This function needs internal locks and should not be - * called from an interrupt context - * - * @sa ixAtmdAccPortDisable - * - */ -PUBLIC IX_STATUS ixAtmdAccPortEnable (IxAtmLogicalPort port); - -/** - * - * @ingroup IxAtmdAccCtrlAPI - * - * @fn ixAtmdAccPortDisable (IxAtmLogicalPort port) - * - * @brief disable a PHY logical port - * - * This function disable the transmission over one port. - * - * When a port is disabled, the cell transmission to the Utopia interface - * is stopped. - * - * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] - * - * @return @li IX_SUCCESS disable is complete - * @return @li IX_ATMDACC_WARNING port already disabled - * @return @li IX_FAIL disable failed, wrong parameter . - * - * @note - This function needs internal locks and should not be called - * from an interrupt context - * - * @note - The response from hardware is done through the txDone mechanism - * to ensure the synchrnisation with tx resources. Therefore, the - * txDone mechanism needs to be serviced to make a PortDisable complete. - * - * @sa ixAtmdAccPortEnable - * @sa ixAtmdAccPortDisableComplete - * @sa ixAtmdAccTxDoneDispatch - * - */ -PUBLIC IX_STATUS ixAtmdAccPortDisable (IxAtmLogicalPort port); - -/** -* -* @ingroup IxAtmdAccCtrlAPI -* -* @fn ixAtmdAccPortDisableComplete (IxAtmLogicalPort port) -* -* @brief disable a PHY logical port -* -* This function indicates if the port disable for a port has completed. This -* function will return TRUE if the port has never been enabled. -* -* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] -* -* @return @li TRUE disable is complete -* @return @li FALSE disable failed, wrong parameter . -* -* @note - This function needs internal locks and should not be called -* from an interrupt context -* -* @sa ixAtmdAccPortEnable -* @sa ixAtmdAccPortDisable -* -*/ -PUBLIC BOOL ixAtmdAccPortDisableComplete (IxAtmLogicalPort port); - -#endif /* IXATMDACCCTRL_H */ - -/** - * @} defgroup IxAtmdAccCtrlAPI - */ - - diff --git a/arch/arm/cpu/ixp/npe/include/IxAtmm.h b/arch/arm/cpu/ixp/npe/include/IxAtmm.h deleted file mode 100644 index fcf523f..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxAtmm.h +++ /dev/null @@ -1,795 +0,0 @@ -/** - * @file IxAtmm.h - * - * @date 3-DEC-2001 - * - * @brief Header file for the IXP400 ATM Manager component (IxAtmm) - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - - -/** - * @defgroup IxAtmm IXP400 ATM Manager (IxAtmm) API - * - * @brief IXP400 ATM Manager component Public API - * - * @{ - */ - -#ifndef IXATMM_H -#define IXATMM_H - -/* - * Put the user defined include files required - */ -#include "IxAtmSch.h" -#include "IxOsalTypes.h" - -/* - * #defines and macros used in this file. - */ - -/** - * @def IX_ATMM_RET_ALREADY_INITIALIZED - * - * @brief Component has already been initialized - */ -#define IX_ATMM_RET_ALREADY_INITIALIZED 2 - -/** - * @def IX_ATMM_RET_INVALID_PORT - * - * @brief Specified port does not exist or is out of range */ -#define IX_ATMM_RET_INVALID_PORT 3 - -/** - * @def IX_ATMM_RET_INVALID_VC_DESCRIPTOR - * - * @brief The VC description does not adhere to ATM standards */ -#define IX_ATMM_RET_INVALID_VC_DESCRIPTOR 4 - -/** - * @def IX_ATMM_RET_VC_CONFLICT - * - * @brief The VPI/VCI values supplied are either reserved, or they - * conflict with a previously registered VC on this port */ -#define IX_ATMM_RET_VC_CONFLICT 5 - -/** - * @def IX_ATMM_RET_PORT_CAPACITY_IS_FULL - * - * @brief The virtual connection cannot be established on the port - * because the remaining port capacity is not sufficient to - * support it */ -#define IX_ATMM_RET_PORT_CAPACITY_IS_FULL 6 - -/** - * @def IX_ATMM_RET_NO_SUCH_VC - * - * @brief No registered VC, as described by the supplied VCI/VPI or - * VC identifier values, exists on this port */ -#define IX_ATMM_RET_NO_SUCH_VC 7 - -/** - * @def IX_ATMM_RET_INVALID_VC_ID - * - * @brief The specified VC identifier is out of range. */ -#define IX_ATMM_RET_INVALID_VC_ID 8 - -/** - * @def IX_ATMM_RET_INVALID_PARAM_PTR - * - * @brief A pointer parameter was NULL. */ -#define IX_ATMM_RET_INVALID_PARAM_PTR 9 - -/** - * @def IX_ATMM_UTOPIA_SPHY_ADDR - * - * @brief The phy address when in SPHY mode */ -#define IX_ATMM_UTOPIA_SPHY_ADDR 31 - -/** - * @def IX_ATMM_THREAD_PRI_HIGH - * - * @brief The value of high priority thread */ -#define IX_ATMM_THREAD_PRI_HIGH 90 - -/* - * Typedefs whose scope is limited to this file. - */ - -/** @brief Definition for use in the @ref IxAtmmVc structure. - * Indicates the direction of a VC */ -typedef enum -{ - IX_ATMM_VC_DIRECTION_TX=0, /**< Atmm Vc direction transmit*/ - IX_ATMM_VC_DIRECTION_RX, /**< Atmm Vc direction receive*/ - IX_ATMM_VC_DIRECTION_INVALID /**< Atmm Vc direction invalid*/ -} IxAtmmVcDirection; - -/** @brief Definition for use with @ref IxAtmmVcChangeCallback - * callback. Indicates that the event type represented by the - * callback for this VC. */ -typedef enum -{ - IX_ATMM_VC_CHANGE_EVENT_REGISTER=0, /**< Atmm Vc event register*/ - IX_ATMM_VC_CHANGE_EVENT_DEREGISTER, /**< Atmm Vc event de-register*/ - IX_ATMM_VC_CHANGE_EVENT_INVALID /**< Atmm Vc event invalid*/ -} IxAtmmVcChangeEvent; - -/** @brief Definitions for use with @ref ixAtmmUTOPIAInit interface to - * indicate that UTOPIA loopback should be enabled or disabled - * on initialisation. */ -typedef enum -{ - IX_ATMM_UTOPIA_LOOPBACK_DISABLED=0, /**< Atmm Utopia loopback mode disabled*/ - IX_ATMM_UTOPIA_LOOPBACK_ENABLED, /**< Atmm Utopia loopback mode enabled*/ - IX_ATMM_UTOPIA_LOOPBACK_INVALID /**< Atmm Utopia loopback mode invalid*/ -} IxAtmmUtopiaLoopbackMode; - -/** @brief This structure describes the required attributes of a - * virtual connection. -*/ -typedef struct { - unsigned vpi; /**< VPI value of this virtual connection */ - unsigned vci; /**< VCI value of this virtual connection. */ - IxAtmmVcDirection direction; /**< VC direction */ - - /** Traffic descriptor of this virtual connection. This structure - * is defined by the @ref IxAtmSch component. */ - IxAtmTrafficDescriptor trafficDesc; -} IxAtmmVc; - - -/** @brief Definitions for use with @ref ixAtmmUtopiaInit interface to - * indicate that UTOPIA multi-phy/single-phy mode is used. - */ -typedef enum -{ - IX_ATMM_MPHY_MODE = 0, /**< Atmm phy mode mphy*/ - IX_ATMM_SPHY_MODE, /**< Atmm phy mode sphy*/ - IX_ATMM_PHY_MODE_INVALID /**< Atmm phy mode invalid*/ -} IxAtmmPhyMode; - - -/** @brief Structure contains port-specific information required to - * initialize IxAtmm, and specifically, the IXP400 UTOPIA - * Level-2 device. */ -typedef struct { - unsigned reserved_1:11; /**< [31:21] Should be zero */ - unsigned UtopiaTxPhyAddr:5; /**< [20:16] Address of the - * transmit (Tx) PHY for this - * port on the 5-bit UTOPIA - * Level-2 address bus */ - unsigned reserved_2:11; /**< [15:5] Should be zero */ - unsigned UtopiaRxPhyAddr:5; /**< [4:0] Address of the receive - * (Rx) PHY for this port on the - * 5-bit UTOPIA Level-2 - * address bus */ -} IxAtmmPortCfg; - -/** @brief Callback type used with @ref ixAtmmVcChangeCallbackRegister interface - * Defines a callback type which will be used to notify registered - * users of registration/deregistration events on a particular port - * - * @param eventType @ref IxAtmmVcChangeEvent [in] - Event indicating - * whether the VC supplied has been added or - * removed - * - * @param port @ref IxAtmLogicalPort [in] - Specifies the port on which the event has - * occurred - * - * @param vcChanged @ref IxAtmmVc* [in] - Pointer to a structure which gives - * details of the VC which has been added - * or removed on the port - */ -typedef void (*IxAtmmVcChangeCallback) (IxAtmmVcChangeEvent eventType, - IxAtmLogicalPort port, - const IxAtmmVc* vcChanged); - -/* - * Variable declarations global to this file only. Externs are followed by - * static variables. - */ - -/* - * Extern function prototypes - */ - -/* - * Function declarations - */ - - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmInit (void) - * - * @brief Interface to initialize the IxAtmm software component. Can - * be called once only. - * - * Must be called before any other IxAtmm API is called. - * - * @param "none" - * - * @return @li IX_SUCCESS : IxAtmm has been successfully initialized. - * Calls to other IxAtmm interfaces may now be performed. - * @return @li IX_FAIL : IxAtmm has already been initialized. - */ -PUBLIC IX_STATUS -ixAtmmInit (void); - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmUtopiaInit (unsigned numPorts, - IxAtmmPhyMode phyMode, - IxAtmmPortCfg portCfgs[], - IxAtmmUtopiaLoopbackMode loopbackMode) - * - * @brief Interface to initialize the UTOPIA Level-2 ATM coprocessor - * for the specified number of physical ports. The function - * must be called before the ixAtmmPortInitialize interface - * can operate successfully. - * - * @param numPorts unsigned [in] - Indicates the total number of logical - * ports that are active on the device. Up to 12 ports are - * supported. - * - * @param phyMode @ref IxAtmmPhyMode [in] - Put the Utopia coprocessor in SPHY - * or MPHY mode. - * - * @param portCfgs[] @ref IxAtmmPortCfg [in] - Pointer to an array of elements - * detailing the UTOPIA specific port characteristics. The - * length of the array must be equal to the number of ports - * activated. ATM ports are referred to by the relevant - * offset in this array in all subsequent IxAtmm interface - * calls. - * - * @param loopbackMode @ref IxAtmmUtopiaLoopbackMode [in] - Value must be one of - * @ref IX_ATMM_UTOPIA_LOOPBACK_ENABLED or @ref - * IX_ATMM_UTOPIA_LOOPBACK_DISABLED indicating whether - * loopback should be enabled on the device. Loopback can - * only be supported on a single PHY, therefore the numPorts - * parameter must be 1 if loopback is enabled. - * - * @return @li IX_SUCCESS : Indicates that the UTOPIA device has been - * successfully initialized for the supplied ports. - * @return @li IX_ATMM_RET_ALREADY_INITIALIZED : The UTOPIA device has - * already been initialized. - * @return @li IX_FAIL : The supplied parameters are invalid or have been - * rejected by the UTOPIA-NPE device. - * - * @warning - * This interface may only be called once. - * Port identifiers are assumed to range from 0 to (numPorts - 1) in all - * instances. - * In all subsequent calls to interfaces supplied by IxAtmm, the specified - * port value is expected to represent the offset in the portCfgs array - * specified in this interface. i.e. The first port in this array will - * subsequently be represented as port 0, the second port as port 1, - * and so on.*/ -PUBLIC IX_STATUS -ixAtmmUtopiaInit (unsigned numPorts, - IxAtmmPhyMode phyMode, - IxAtmmPortCfg portCfgs[], - IxAtmmUtopiaLoopbackMode loopbackMode); - - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmPortInitialize (IxAtmLogicalPort port, - unsigned txPortRate, - unsigned rxPortRate) - * - * @brief The interface is called following @ref ixAtmmUtopiaInit () - * and before calls to any other IxAtmm interface. It serves - * to activate the registered ATM port with IxAtmm. - * - * The transmit and receive port rates are specified in bits per - * second. This translates to ATM cells per second according to the - * following formula: CellsPerSecond = portRate / (53*8) The - * IXP400 device supports only 53 byte cells. The client shall make - * sure that the off-chip physical layer device has already been - * initialized. - * - * IxAtmm will configure IxAtmdAcc and IxAtmSch to enable scheduling - * on the port. - * - * This interface must be called once for each active port in the - * system. The first time the interface is invoked, it will configure - * the mechanism by which the handling of transmit, transmit-done and - * receive are driven with the IxAtmdAcc component. - * - * This function is reentrant. - * - * @note The minimum tx rate that will be accepted is 424 bit/s which equates - * to 1 cell (53 bytes) per second. - * - * @param port @ref IxAtmLogicalPort [in] - Identifies the port which is to be - * initialized. - * - * @param txPortRate unsigned [in] - Value specifies the - * transmit port rate for this port in - * bits/second. This value is used by the ATM Scheduler - * component is evaluating VC access requests for the port. - * - * @param rxPortRate unsigned [in] - Value specifies the - * receive port rate for this port in bits/second. - * - * @return @li IX_SUCCESS : The specificed ATM port has been successfully - * initialized. IxAtmm is ready to accept VC registrations on - * this port. - * - * @return @li IX_ATMM_RET_ALREADY_INITIALIZED : ixAtmmPortInitialize has - * already been called successfully on this port. The current - * call is rejected. - * - * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the - * input is not valid. The request is rejected. - * - * @return @li IX_FAIL : IxAtmm could not initialize the port because the - * inputs are not understood. - * - * @sa ixAtmmPortEnable, ixAtmmPortDisable - * - */ -PUBLIC IX_STATUS -ixAtmmPortInitialize (IxAtmLogicalPort port, - unsigned txPortRate, - unsigned rxPortRate); - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmPortModify (IxAtmLogicalPort port, - unsigned txPortRate, - unsigned rxPortRate) - * - * @brief A client may call this interface to change the existing - * port rate (expressed in bits/second) on an established ATM - * port. - * - * @param port @ref IxAtmLogicalPort [in] - Identifies the port which is to be - * initialized. - * - * @param txPortRate unsigned [in] - Value specifies the`` - * transmit port rate for this port in - * bits/second. This value is used by the ATM Scheduler - * component is evaluating VC access requests for the port. - * - * @param rxPortRate unsigned [in] - Value specifies the - * receive port rate for this port in - * bits/second. - * - * @return @li IX_SUCCESS : The indicated ATM port rates have been - * successfully modified. - * - * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the - * input is not valid. The request is rejected. - * - * @return @li IX_FAIL : IxAtmm could not update the port because the - * inputs are not understood, or the interface was called before - * the port was initialized. */ -PUBLIC IX_STATUS -ixAtmmPortModify (IxAtmLogicalPort port, - unsigned txPortRate, - unsigned rxPortRate); - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmPortQuery (IxAtmLogicalPort port, - unsigned *txPortRate, - unsigned *rxPortRate); - - * - * @brief The client may call this interface to request details on - * currently registered transmit and receive rates for an ATM - * port. - * - * @param port @ref IxAtmLogicalPort [in] - Value identifies the port from which the - * rate details are requested. - * - * @param *txPortRate unsigned [out] - Pointer to a value - * which will be filled with the value of the transmit port - * rate specified in bits/second. - * - * @param *rxPortRate unsigned [out] - Pointer to a value - * which will be filled with the value of the receive port - * rate specified in bits/second. - * - * @return @li IX_SUCCESS : The information requested on the specified - * port has been successfully supplied in the output. - * - * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the - * input is not valid. The request is rejected. - * - * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was - * NULL. - * - * @return @li IX_FAIL : IxAtmm could not update the port because the - * inputs are not understood, or the interface was called before - * the port was initialized. */ -PUBLIC IX_STATUS -ixAtmmPortQuery (IxAtmLogicalPort port, - unsigned *txPortRate, - unsigned *rxPortRate); - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmPortEnable(IxAtmLogicalPort port) - * - * @brief The client call this interface to enable transmit for an ATM - * port. At initialisation, all the ports are disabled. - * - * @param port @ref IxAtmLogicalPort [in] - Value identifies the port - * - * @return @li IX_SUCCESS : Transmission over this port is started. - * - * @return @li IX_FAIL : The port parameter is not valid, or the - * port is already enabled - * - * @note - When a port is disabled, Rx and Tx VC Connect requests will fail - * - * @note - This function uses system resources and should not be used - * inside an interrupt context. - * - * @sa ixAtmmPortDisable */ -PUBLIC IX_STATUS -ixAtmmPortEnable(IxAtmLogicalPort port); - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmPortDisable(IxAtmLogicalPort port) - * - * @brief The client call this interface to disable transmit for an ATM - * port. At initialisation, all the ports are disabled. - * - * @param port @ref IxAtmLogicalPort [in] - Value identifies the port - * - * @return @li IX_SUCCESS : Transmission over this port is stopped. - * - * @return @li IX_FAIL : The port parameter is not valid, or the - * port is already disabled - * - * @note - When a port is disabled, Rx and Tx VC Connect requests will fail - * - * @note - This function call does not stop RX traffic. It is supposed - * that this function is invoked when a serious problem - * is detected (e.g. physical layer broken). Then, the RX traffic - * is not passing. - * - * @note - This function is blocking until the hw acknowledge that the - * transmission is stopped. - * - * @note - This function uses system resources and should not be used - * inside an interrupt context. - * - * @sa ixAtmmPortEnable */ -PUBLIC IX_STATUS -ixAtmmPortDisable(IxAtmLogicalPort port); - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmVcRegister (IxAtmLogicalPort port, - IxAtmmVc *vcToAdd, - IxAtmSchedulerVcId *vcId) - * - * @brief This interface is used to register an ATM Virtual - * Connection on the specified ATM port. - * - * Each call to this interface registers a unidirectional virtual - * connection with the parameters specified. If a bi-directional VC - * is needed, the function should be called twice (once for each - * direction, Tx & Rx) where the VPI and VCI and port parameters in - * each call are identical. - * - * With the addition of each new VC to a port, a series of - * callback functions are invoked by the IxAtmm component to notify - * possible external components of the change. The callback functions - * are registered using the @ref ixAtmmVcChangeCallbackRegister interface. - * - * The IxAtmSch component is notified of the registration of transmit - * VCs. - * - * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the specified VC is - * to be registered. - * - * @param *vcToAdd @ref IxAtmmVc [in] - Pointer to an @ref IxAtmmVc structure - * containing a description of the VC to be registered. The - * client shall fill the vpi, vci and direction and relevant - * trafficDesc members of this structure before calling this - * function. - * - * @param *vcId @ref IxAtmSchedulerVcId [out] - Pointer to an integer value which is filled - * with the per-port unique identifier value for this VC. - * This identifier will be required when a request is - * made to deregister or change this VC. VC identifiers - * for transmit VCs will have a value between 0-43, - * i.e. 32 data Tx VCs + 12 OAM Tx Port VCs. - * Receive VCs will have a value between 44-66, - * i.e. 32 data Rx VCs + 1 OAM Rx VC. - * - * @return @li IX_SUCCESS : The VC has been successfully registered on - * this port. The VC is ready for a client to configure IxAtmdAcc - * for receive and transmit operations on the VC. - * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the - * input is not valid or has not been initialized. The request - * is rejected. - * @return @li IX_ATMM_RET_INVALID_VC_DESCRIPTOR : The descriptor - * pointed to by vcToAdd is invalid. The registration request - * is rejected. - * @return @li IX_ATMM_RET_VC_CONFLICT : The VC requested conflicts with - * reserved VPI and/or VCI values or with another VC already activated - * on this port. - * @return @li IX_ATMM_RET_PORT_CAPACITY_IS_FULL : The VC cannot be - * registered in the port becuase the port capacity is - * insufficient to support the requested ATM traffic contract. - * The registration request is rejected. - * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was - * NULL. - * - * @warning IxAtmm has no capability of signaling or negotiating a virtual - * connection. Negotiation of the admission of the VC to the network - * is beyond the scope of this function. This is assumed to be - * performed by the calling client, if appropriate, - * before or after this function is called. - */ -PUBLIC IX_STATUS -ixAtmmVcRegister (IxAtmLogicalPort port, - IxAtmmVc *vcToAdd, - IxAtmSchedulerVcId *vcId); - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmVcDeregister (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId) - * - * @brief Function called by a client to deregister a VC from the - * system. - * - * With the removal of each new VC from a port, a series of - * registered callback functions are invoked by the IxAtmm component - * to notify possible external components of the change. The callback - * functions are registered using the @ref ixAtmmVcChangeCallbackRegister. - * - * The IxAtmSch component is notified of the removal of transmit VCs. - * - * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be - * removed is currently registered. - * - * @param vcId @ref IxAtmSchedulerVcId [in] - VC identifier value of the VC to - * be deregistered. This value was supplied to the client when - the VC was originally registered. This value can also be - queried from the IxAtmm component through the @ref ixAtmmVcQuery - * interface. - * - * @return @li IX_SUCCESS : The specified VC has been successfully - * removed from this port. - * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the - * input is not valid or has not been initialized. The request - * is rejected. - * @return @li IX_FAIL : There is no registered VC associated with the - * supplied identifier registered on this port. */ -PUBLIC IX_STATUS -ixAtmmVcDeregister (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId); - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmVcQuery (IxAtmLogicalPort port, - unsigned vpi, - unsigned vci, - IxAtmmVcDirection direction, - IxAtmSchedulerVcId *vcId, - IxAtmmVc *vcDesc) - * - * @brief This interface supplies information about an active VC on a - * particular port when supplied with the VPI, VCI and - * direction of that VC. - * - * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be - * queried is currently registered. - * - * @param vpi unsigned [in] - ATM VPI value of the requested VC. - * - * @param vci unsigned [in] - ATM VCI value of the requested VC. - * - * @param direction @ref IxAtmmVcDirection [in] - One of @ref - * IX_ATMM_VC_DIRECTION_TX or @ref IX_ATMM_VC_DIRECTION_RX - * indicating the direction (Tx or Rx) of the requested VC. - * - * @param *vcId @ref IxAtmSchedulerVcId [out] - Pointer to an integer value which will be - * filled with the VC identifier value for the requested - * VC (as returned by @ref ixAtmmVcRegister), if it - * exists on this port. - * - * @param *vcDesc @ref IxAtmmVc [out] - Pointer to an @ref IxAtmmVc structure - * which will be filled with the specific details of the - * requested VC, if it exists on this port. - * - * @return @li IX_SUCCESS : The specified VC has been found on this port - * and the requested details have been returned. - * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the - * input is not valid or has not been initialized. The request - * is rejected. - * @return @li IX_ATMM_RET_NO_SUCH_VC : No VC exists on the specified - * port which matches the search criteria (VPI, VCI, direction) - * given. No data is returned. - * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was - * NULL. - * - */ -PUBLIC IX_STATUS -ixAtmmVcQuery (IxAtmLogicalPort port, - unsigned vpi, - unsigned vci, - IxAtmmVcDirection direction, - IxAtmSchedulerVcId *vcId, - IxAtmmVc *vcDesc); - - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmVcIdQuery (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, IxAtmmVc *vcDesc) - * - * @brief This interface supplies information about an active VC on a - * particular port when supplied with a vcId for that VC. - * - * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be - * queried is currently registered. - * - * @param vcId @ref IxAtmSchedulerVcId [in] - Value returned by @ref ixAtmmVcRegister which - * uniquely identifies the requested VC on this port. - * - * @param *vcDesc @ref IxAtmmVc [out] - Pointer to an @ref IxAtmmVc structure - * which will be filled with the specific details of the - * requested VC, if it exists on this port. - * - * @return @li IX_SUCCESS : The specified VC has been found on this port - * and the requested details have been returned. - * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the - * input is not valid or has not been initialized. The request - * is rejected. - * @return @li IX_ATMM_RET_NO_SUCH_VC : No VC exists on the specified - * port which matches the supplied identifier. No data is - * returned. - * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was - * NULL. - */ -PUBLIC IX_STATUS -ixAtmmVcIdQuery (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, IxAtmmVc *vcDesc); - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmVcChangeCallbackRegister (IxAtmmVcChangeCallback callback) - * - * @brief This interface is invoked to supply a function to IxAtmm - * which will be called to notify the client if a new VC is - * registered with IxAtmm or an existing VC is removed. - * - * The callback, when invoked, will run within the context of the call - * to @ref ixAtmmVcRegister or @ref ixAtmmVcDeregister which caused - * the change of state. - * - * A maximum of 32 calbacks may be registered in with IxAtmm. - * - * @param callback @ref IxAtmmVcChangeCallback [in] - Callback which complies - * with the @ref IxAtmmVcChangeCallback definition. This - * function will be invoked by IxAtmm with the appropiate - * parameters for the relevant VC when any VC has been - * registered or deregistered with IxAtmm. - * - * @return @li IX_SUCCESS : The specified callback has been registered - * successfully with IxAtmm and will be invoked when appropriate. - * @return @li IX_FAIL : Either the supplied callback is invalid, or - * IxAtmm has already registered 32 and connot accommodate - * any further registrations of this type. The request is - * rejected. - * - * @warning The client must not call either the @ref - * ixAtmmVcRegister or @ref ixAtmmVcDeregister interfaces - * from within the supplied callback function. */ -PUBLIC IX_STATUS ixAtmmVcChangeCallbackRegister (IxAtmmVcChangeCallback callback); - - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmVcChangeCallbackDeregister (IxAtmmVcChangeCallback callback) - * - * @brief This interface is invoked to deregister a previously supplied - * callback function. - * - * @param callback @ref IxAtmmVcChangeCallback [in] - Callback which complies - * with the @ref IxAtmmVcChangeCallback definition. This - * function will removed from the table of callbacks. - * - * @return @li IX_SUCCESS : The specified callback has been deregistered - * successfully from IxAtmm. - * @return @li IX_FAIL : Either the supplied callback is invalid, or - * is not currently registered with IxAtmm. - */ -PUBLIC IX_STATUS -ixAtmmVcChangeCallbackDeregister (IxAtmmVcChangeCallback callback); - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmUtopiaStatusShow (void) - * - * @brief Display utopia status counters - * - * @param "none" - * - * @return @li IX_SUCCESS : Show function was successful - * @return @li IX_FAIL : Internal failure - */ -PUBLIC IX_STATUS -ixAtmmUtopiaStatusShow (void); - -/** - * @ingroup IxAtmm - * - * @fn ixAtmmUtopiaCfgShow (void) - * - * @brief Display utopia information(config registers and status registers) - * - * @param "none" - * - * @return @li IX_SUCCESS : Show function was successful - * @return @li IX_FAIL : Internal failure - */ -PUBLIC IX_STATUS -ixAtmmUtopiaCfgShow (void); - -#endif -/* IXATMM_H */ - -/** @} */ diff --git a/arch/arm/cpu/ixp/npe/include/IxDmaAcc.h b/arch/arm/cpu/ixp/npe/include/IxDmaAcc.h deleted file mode 100644 index 45c7527..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxDmaAcc.h +++ /dev/null @@ -1,260 +0,0 @@ -/** - * @file IxDmaAcc.h - * - * @date 15 October 2002 - * - * @brief API of the IXP400 DMA Access Driver Component (IxDma) - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/*--------------------------------------------------------------------- - Doxygen group definitions - ---------------------------------------------------------------------*/ - -#ifndef IXDMAACC_H -#define IXDMAACC_H - -#include "IxOsal.h" -#include "IxNpeDl.h" -/** - * @defgroup IxDmaTypes IXP400 DMA Types (IxDmaTypes) - * @brief The common set of types used in the DMA component - * @{ - */ - -/** - * @ingroup IxDmaTypes - * @enum IxDmaReturnStatus - * @brief Dma return status definitions - */ -typedef enum -{ - IX_DMA_SUCCESS = IX_SUCCESS, /**< DMA Transfer Success */ - IX_DMA_FAIL = IX_FAIL, /**< DMA Transfer Fail */ - IX_DMA_INVALID_TRANSFER_WIDTH, /**< Invalid transfer width */ - IX_DMA_INVALID_TRANSFER_LENGTH, /**< Invalid transfer length */ - IX_DMA_INVALID_TRANSFER_MODE, /**< Invalid transfer mode */ - IX_DMA_INVALID_ADDRESS_MODE, /**< Invalid address mode */ - IX_DMA_REQUEST_FIFO_FULL /**< DMA request queue is full */ -} IxDmaReturnStatus; - -/** - * @ingroup IxDmaTypes - * @enum IxDmaTransferMode - * @brief Dma transfer mode definitions - * @note Copy and byte swap, and copy and reverse modes only support multiples of word data length. - */ -typedef enum -{ - IX_DMA_COPY_CLEAR = 0, /**< copy and clear source*/ - IX_DMA_COPY, /**< copy */ - IX_DMA_COPY_BYTE_SWAP, /**< copy and byte swap (endian) */ - IX_DMA_COPY_REVERSE, /**< copy and reverse */ - IX_DMA_TRANSFER_MODE_INVALID /**< Invalid transfer mode */ -} IxDmaTransferMode; - -/** - * @ingroup IxDmaTypes - * @enum IxDmaAddressingMode - * @brief Dma addressing mode definitions - * @note Fixed source address to fixed destination address addressing mode is not supported. - */ -typedef enum -{ - IX_DMA_INC_SRC_INC_DST = 0, /**< Incremental source address to incremental destination address */ - IX_DMA_INC_SRC_FIX_DST, /**< Incremental source address to incremental destination address */ - IX_DMA_FIX_SRC_INC_DST, /**< Incremental source address to incremental destination address */ - IX_DMA_FIX_SRC_FIX_DST, /**< Incremental source address to incremental destination address */ - IX_DMA_ADDRESSING_MODE_INVALID /**< Invalid Addressing Mode */ -} IxDmaAddressingMode; - -/** - * @ingroup IxDmaTypes - * @enum IxDmaTransferWidth - * @brief Dma transfer width definitions - * @Note Fixed addresses (either source or destination) do not support burst transfer width. - */ -typedef enum -{ - IX_DMA_32_SRC_32_DST = 0, /**< 32-bit src to 32-bit dst */ - IX_DMA_32_SRC_16_DST, /**< 32-bit src to 16-bit dst */ - IX_DMA_32_SRC_8_DST, /**< 32-bit src to 8-bit dst */ - IX_DMA_16_SRC_32_DST, /**< 16-bit src to 32-bit dst */ - IX_DMA_16_SRC_16_DST, /**< 16-bit src to 16-bit dst */ - IX_DMA_16_SRC_8_DST, /**< 16-bit src to 8-bit dst */ - IX_DMA_8_SRC_32_DST, /**< 8-bit src to 32-bit dst */ - IX_DMA_8_SRC_16_DST, /**< 8-bit src to 16-bit dst */ - IX_DMA_8_SRC_8_DST, /**< 8-bit src to 8-bit dst */ - IX_DMA_8_SRC_BURST_DST, /**< 8-bit src to burst dst - Not supported for fixed destination address */ - IX_DMA_16_SRC_BURST_DST, /**< 16-bit src to burst dst - Not supported for fixed destination address */ - IX_DMA_32_SRC_BURST_DST, /**< 32-bit src to burst dst - Not supported for fixed destination address */ - IX_DMA_BURST_SRC_8_DST, /**< burst src to 8-bit dst - Not supported for fixed source address */ - IX_DMA_BURST_SRC_16_DST, /**< burst src to 16-bit dst - Not supported for fixed source address */ - IX_DMA_BURST_SRC_32_DST, /**< burst src to 32-bit dst - Not supported for fixed source address*/ - IX_DMA_BURST_SRC_BURST_DST, /**< burst src to burst dst - Not supported for fixed source and destination address -*/ - IX_DMA_TRANSFER_WIDTH_INVALID /**< Invalid transfer width */ -} IxDmaTransferWidth; - -/** - * @ingroup IxDmaTypes - * @enum IxDmaNpeId - * @brief NpeId numbers to identify NPE A, B or C - */ -typedef enum -{ - IX_DMA_NPEID_NPEA = 0, /**< Identifies NPE A */ - IX_DMA_NPEID_NPEB, /**< Identifies NPE B */ - IX_DMA_NPEID_NPEC, /**< Identifies NPE C */ - IX_DMA_NPEID_MAX /**< Total Number of NPEs */ -} IxDmaNpeId; -/* @} */ -/** - * @defgroup IxDmaAcc IXP400 DMA Access Driver (IxDmaAcc) API - * - * @brief The public API for the IXP400 IxDmaAcc component - * - * @{ - */ - -/** - * @ingroup IxDmaAcc - * @brief DMA Request Id type - */ -typedef UINT32 IxDmaAccRequestId; - -/** - * @ingroup IxDmaAcc - * @def IX_DMA_REQUEST_FULL - * @brief DMA request queue is full - * This constant is a return value used to tell the user that the IxDmaAcc - * queue is full. - * - */ -#define IX_DMA_REQUEST_FULL 16 - -/** - * @ingroup IxDmaAcc - * @brief DMA completion notification - * This function is called to notify a client that the DMA has been completed - * @param status @ref IxDmaReturnStatus [out] - reporting to client - * - */ -typedef void (*IxDmaAccDmaCompleteCallback) (IxDmaReturnStatus status); - -/** - * @ingroup IxDmaAcc - * - * @fn ixDmaAccInit(IxNpeDlNpeId npeId) - * - * @brief Initialise the DMA Access component - * This function will initialise the DMA Access component internals - * @param npeId @ref IxNpeDlNpeId [in] - NPE to use for Dma Transfer - * @return @li IX_SUCCESS succesfully initialised the component - * @return @li IX_FAIL Initialisation failed for some unspecified - * internal reason. - */ -PUBLIC IX_STATUS -ixDmaAccInit(IxNpeDlNpeId npeId); - -/** - * @ingroup IxDmaAcc - * - * @fn ixDmaAccDmaTransfer( - IxDmaAccDmaCompleteCallback callback, - UINT32 SourceAddr, - UINT32 DestinationAddr, - UINT16 TransferLength, - IxDmaTransferMode TransferMode, - IxDmaAddressingMode AddressingMode, - IxDmaTransferWidth TransferWidth) - * - * @brief Perform DMA transfer - * This function will perform DMA transfer between devices within the - * IXP400 memory map. - * @note The following are restrictions for IxDmaAccDmaTransfer: - * @li The function is non re-entrant. - * @li The function assumes host devices are operating in big-endian mode. - * @li Fixed address does not suport burst transfer width - * @li Fixed source address to fixed destinatiom address mode is not suported - * @li The incrementing source address for expansion bus will not support a burst transfer width and copy and clear mode - * - * @param callback @ref IxDmaAccDmaCompleteCallback [in] - function pointer to be stored and called when the DMA transfer is completed. This cannot be NULL. - * @param SourceAddr UINT32 [in] - Starting address of DMA source. Must be a valid IXP400 memory map address. - * @param DestinationAddr UINT32 [in] - Starting address of DMA destination. Must be a valid IXP400 memory map address. - * @param TransferLength UINT16 [in] - The size of DMA data transfer. The range must be from 1-64Kbyte - * @param TransferMode @ref IxDmaTransferMode [in] - The DMA transfer mode - * @param AddressingMode @ref IxDmaAddressingMode [in] - The DMA addressing mode - * @param TransferWidth @ref IxDmaTransferWidth [in] - The DMA transfer width - * - * @return @li IX_DMA_SUCCESS Notification that the DMA request is succesful - * @return @li IX_DMA_FAIL IxDmaAcc not yet initialised or some internal error has occured - * @return @li IX_DMA_INVALID_TRANSFER_WIDTH Transfer width is nit valid - * @return @li IX_DMA_INVALID_TRANSFER_LENGTH Transfer length outside of valid range - * @return @li IX_DMA_INVALID_TRANSFER_MODE Transfer Mode not valid - * @return @li IX_DMA_REQUEST_FIFO_FULL IxDmaAcc request queue is full - */ -PUBLIC IxDmaReturnStatus -ixDmaAccDmaTransfer( - IxDmaAccDmaCompleteCallback callback, - UINT32 SourceAddr, - UINT32 DestinationAddr, - UINT16 TransferLength, - IxDmaTransferMode TransferMode, - IxDmaAddressingMode AddressingMode, - IxDmaTransferWidth TransferWidth); -/** - * @ingroup IxDmaAcc - * - * @fn ixDmaAccShow(void) - * - * @brief Display some component information for debug purposes - * Show some internal operation information relating to the DMA service. - * At a minimum the following will show. - * - the number of the DMA pend (in queue) - * @param None - * @return @li None - */ -PUBLIC IX_STATUS -ixDmaAccShow(void); - -#endif /* IXDMAACC_H */ - diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAcc.h b/arch/arm/cpu/ixp/npe/include/IxEthAcc.h deleted file mode 100644 index ff706c4..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthAcc.h +++ /dev/null @@ -1,2512 +0,0 @@ -/** @file IxEthAcc.h - * - * @brief this file contains the public API of @ref IxEthAcc component - * - * Design notes: - * The IX_OSAL_MBUF address is to be specified on bits [31-5] and must - * be cache aligned (bits[4-0] cleared) - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * - */ - -#ifndef IxEthAcc_H -#define IxEthAcc_H - -#include -#include - -/** - * @defgroup IxEthAcc IXP400 Ethernet Access (IxEthAcc) API - * - * @brief ethAcc is a library that does provides access to the internal IXP400 10/100Bt Ethernet MACs. - * - *@{ - */ - -/** - * @ingroup IxEthAcc - * @brief Definition of the Ethernet Access status - */ -typedef enum /* IxEthAccStatus */ -{ - IX_ETH_ACC_SUCCESS = IX_SUCCESS, /**< return success*/ - IX_ETH_ACC_FAIL = IX_FAIL, /**< return fail*/ - IX_ETH_ACC_INVALID_PORT, /**< return invalid port*/ - IX_ETH_ACC_PORT_UNINITIALIZED, /**< return uninitialized*/ - IX_ETH_ACC_MAC_UNINITIALIZED, /**< return MAC uninitialized*/ - IX_ETH_ACC_INVALID_ARG, /**< return invalid arg*/ - IX_ETH_TX_Q_FULL, /**< return tx queue is full*/ - IX_ETH_ACC_NO_SUCH_ADDR /**< return no such address*/ -} IxEthAccStatus; - -/** - * @ingroup IxEthAcc - * @enum IxEthAccPortId - * @brief Definition of the IXP400 Mac Ethernet device. - */ -typedef enum -{ - IX_ETH_PORT_1 = 0, /**< Ethernet Port 1 */ - IX_ETH_PORT_2 = 1 /**< Ethernet port 2 */ - ,IX_ETH_PORT_3 = 2 /**< Ethernet port 3 */ -} IxEthAccPortId; - -/** - * @ingroup IxEthAcc - * - * @def IX_ETH_ACC_NUMBER_OF_PORTS - * - * @brief Definition of the number of ports - * - */ -#ifdef __ixp46X -#define IX_ETH_ACC_NUMBER_OF_PORTS (3) -#else -#define IX_ETH_ACC_NUMBER_OF_PORTS (2) -#endif - -/** - * @ingroup IxEthAcc - * - * @def IX_IEEE803_MAC_ADDRESS_SIZE - * - * @brief Definition of the size of the MAC address - * - */ -#define IX_IEEE803_MAC_ADDRESS_SIZE (6) - - -/** - * - * @brief Definition of the IEEE 802.3 Ethernet MAC address structure. - * - * The data should be packed with bytes xx:xx:xx:xx:xx:xx - * @note - * The data must be packed in network byte order. - */ -typedef struct -{ - UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< MAC address */ -} IxEthAccMacAddr; - -/** - * @ingroup IxEthAcc - * @def IX_ETH_ACC_NUM_TX_PRIORITIES - * @brief Definition of the number of transmit priorities - * - */ -#define IX_ETH_ACC_NUM_TX_PRIORITIES (8) - -/** - * @ingroup IxEthAcc - * @enum IxEthAccTxPriority - * @brief Definition of the relative priority used to transmit a frame - * - */ -typedef enum -{ - IX_ETH_ACC_TX_PRIORITY_0 = 0, /** STA */ - IX_ETHACC_RX_APTYPE = 0x30 /**< 802.11, AP <=> AP */ -} IxEthAccRxFrameType; - -/** - * @ingroup IxEthAcc - * @enum IxEthAccDuplexMode - * @brief Definition to provision the duplex mode of the MAC. - * - */ -typedef enum -{ - IX_ETH_ACC_FULL_DUPLEX, /**< Full duplex operation of the MAC */ - IX_ETH_ACC_HALF_DUPLEX /**< Half duplex operation of the MAC */ -} IxEthAccDuplexMode; - - -/** - * @ingroup IxEthAcc - * @struct IxEthAccNe - * @brief Definition of service-specific informations. - * - * This structure defines the Ethernet service-specific informations - * and enable QoS and VLAN features. - */ -typedef struct -{ - UINT32 ixReserved_next; /**< reserved for chaining */ - UINT32 ixReserved_lengths; /**< reserved for buffer lengths */ - UINT32 ixReserved_data; /**< reserved for buffer pointer */ - UINT8 ixDestinationPortId; /**< Destination portId for this packet, if known by NPE */ - UINT8 ixSourcePortId; /**< Source portId for this packet */ - UINT16 ixFlags; /**< BitField of option for this frame */ - UINT8 ixQoS; /**< QoS class of the frame */ - UINT8 ixReserved; /**< reserved */ - UINT16 ixVlanTCI; /**< Vlan TCI */ - UINT8 ixDestMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Destination MAC address */ - UINT8 ixSourceMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Source MAC address */ -} IxEthAccNe; - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_PORT_UNKNOWN - * - * @brief Contents of the field @a IX_ETHACC_NE_DESTPORTID when no - * destination port can be found by the NPE for this frame. - * - */ -#define IX_ETHACC_NE_PORT_UNKNOWN (0xff) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_DESTMAC - * - * @brief The location of the destination MAC address in the Mbuf header. - * - */ -#define IX_ETHACC_NE_DESTMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestMac - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_SOURCEMAC - * - * @brief The location of the source MAC address in the Mbuf header. - * - */ -#define IX_ETHACC_NE_SOURCEMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourceMac - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_VLANTCI - * - * @brief The VLAN Tag Control Information associated with this frame - * - * The VLAN Tag Control Information associated with this frame. On Rx - * path, this field is extracted from the packet header. - * On Tx path, the value of this field is inserted in the frame when - * the port is configured to insert or replace vlan tags in the - * egress frames. - * - * @sa IX_ETHACC_NE_FLAGS - */ -#define IX_ETHACC_NE_VLANTCI(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixVlanTCI - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_SOURCEPORTID - * - * @brief The port where this frame came from. - * - * The port where this frame came from. This field is set on receive - * with the port information. This field is ignored on Transmit path. - */ -#define IX_ETHACC_NE_SOURCEPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourcePortId - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_DESTPORTID - * - * @brief The destination port where this frame should be sent. - * - * The destination port where this frame should be sent. - * - * @li In the transmit direction, this field contains the destination port - * and is ignored unless @a IX_ETHACC_NE_FLAG_DST is set. - * - * @li In the receive direction, this field contains the port where the - * destination MAC addresses has been learned. If the destination - * MAC address is unknown, then this value is set to the reserved value - * @a IX_ETHACC_NE_PORT_UNKNOWN - * - */ -#define IX_ETHACC_NE_DESTPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestinationPortId - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_QOS - * - * @brief QualityOfService class (QoS) for this received frame. - * - */ -#define IX_ETHACC_NE_QOS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixQoS - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_FLAGS - * - * @brief Bit Mask of the different flags associated with a frame - * - * The flags are the bit-oring combination - * of the following different fields : - * - * @li IP flag (Rx @a IX_ETHACC_NE_IPMASK) - * @li Spanning Tree flag (Rx @a IX_ETHACC_NE_STMASK) - * @li Link layer type (Rx and Tx @a IX_ETHACC_NE_LINKMASK) - * @li VLAN Tagged Frame (Rx @a IX_ETHACC_NE_VLANMASK) - * @li New source MAC address (Rx @a IX_ETHACC_NE_NEWSRCMASK) - * @li Multicast flag (Rx @a IX_ETHACC_NE_MCASTMASK) - * @li Broadcast flag (Rx @a IX_ETHACC_NE_BCASTMASK) - * @li Destination port flag (Tx @a IX_ETHACC_NE_PORTMASK) - * @li Tag/Untag Tx frame (Tx @a IX_ETHACC_NE_TAGMODEMASK) - * @li Overwrite destination port (Tx @a IX_ETHACC_NE_PORTOVERMASK) - * @li Filtered frame (Rx @a IX_ETHACC_NE_STMASK) - * @li VLAN Enabled (Rx and Tx @a IX_ETHACC_NE_VLANENABLEMASK) - */ -#define IX_ETHACC_NE_FLAGS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixFlags - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_BCASTMASK - * - * @brief This mask defines if a received frame is a broadcast frame. - * - * This mask defines if a received frame is a broadcast frame. - * The BCAST flag is set when the destination MAC address of - * a frame is broadcast. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_BCASTMASK (0x1) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_MCASTMASK - * - * @brief This mask defines if a received frame is a multicast frame. - * - * This mask defines if a received frame is a multicast frame. - * The MCAST flag is set when the destination MAC address of - * a frame is multicast. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_MCASTMASK (0x1 << 1) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_IPMASK - * - * @brief This mask defines if a received frame is a IP frame. - * - * This mask applies to @a IX_ETHACC_NE_FLAGS and defines if a received - * frame is a IP frame. The IP flag is set on Rx direction, depending on - * the frame contents. The flag is set when the length/type field of a - * received frame is 0x8000. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_IPMASK (0x1 << 2) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_VLANMASK - * - * @brief This mask defines if a received frame is VLAN tagged. - * - * This mask defines if a received frame is VLAN tagged. - * When set, the Rx frame is VLAN-tagged and the tag value - * is available thru @a IX_ETHACC_NE_VLANID. - * Note that when sending frames which are already tagged - * this flag should be set, to avoid inserting another VLAN tag. - * - * @sa IX_ETHACC_NE_FLAGS - * @sa IX_ETHACC_NE_VLANID - * - */ -#define IX_ETHACC_NE_VLANMASK (0x1 << 3) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_LINKMASK - * - * @brief This mask is the link layer protocol indicator - * - * This mask applies to @a IX_ETHACC_NE_FLAGS. - * It reflects the state of a frame as it exits an NPE on the Rx path - * or enters an NPE on the Tx path. Its values are as follows: - * @li 0x00 - IEEE802.3 - 8802 (Rx) / IEEE802.3 - 8802 (Tx) - * @li 0x01 - IEEE802.3 - Ethernet (Rx) / IEEE802.3 - Ethernet (Tx) - * @li 0x02 - IEEE802.11 AP -> STA (Rx) / IEEE802.11 STA -> AP (Tx) - * @li 0x03 - IEEE802.11 AP -> AP (Rx) / IEEE802.11 AP->AP (Tx) - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_LINKMASK (0x3 << 4) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_STMASK - * - * @brief This mask defines if a received frame is a Spanning Tree frame. - * - * This mask applies to @a IX_ETHACC_NE_FLAGS. - * On rx direction, it defines if a received if frame is a Spanning Tree frame. - * Setting this fkag on transmit direction overrides the port settings - * regarding the VLAN options and - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_STMASK (0x1 << 6) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_FILTERMASK - * - * @brief This bit indicates whether a frame has been filtered by the Rx service. - * - * This mask applies to @a IX_ETHACC_NE_FLAGS. - * Certain frames, which should normally be fully filtered by the NPE to due - * the destination MAC address being on the same segment as the Rx port are - * still forwarded to the XScale (although the payload is invalid) in order - * to learn the MAC address of the transmitting station, if this is unknown. - * Normally EthAcc will filter and recycle these framess internally and no - * frames with the FILTER bit set will be received by the client. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_FILTERMASK (0x1 << 7) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_PORTMASK - * - * @brief This mask defines the rule to transmit a frame - * - * This mask defines the rule to transmit a frame. When set, a frame - * is transmitted to the destination port as set by the macro - * @a IX_ETHACC_NE_DESTPORTID. If not set, the destination port - * is searched using the destination MAC address. - * - * @note This flag is meaningful only for multiport Network Engines. - * - * @sa IX_ETHACC_NE_FLAGS - * @sa IX_ETHACC_NE_DESTPORTID - * - */ -#define IX_ETHACC_NE_PORTOVERMASK (0x1 << 8) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_TAGMODEMASK - * - * @brief This mask defines the tagging rules to apply to a transmit frame. - * - * This mask defines the tagging rules to apply to a transmit frame - * regardless of the default setting for a port. When used together - * with @a IX_ETHACC_NE_TAGOVERMASK and when set, the - * frame will be tagged prior to transmission. When not set, - * the frame will be untagged prior to transmission. This is accomplished - * irrespective of the Egress tagging rules, constituting a per-frame override. - * - * @sa IX_ETHACC_NE_FLAGS - * @sa IX_ETHACC_NE_TAGOVERMASK - * - */ -#define IX_ETHACC_NE_TAGMODEMASK (0x1 << 9) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_TAGOVERMASK - * - * @brief This mask defines the rule to transmit a frame - * - * This mask defines the rule to transmit a frame. When set, the - * default transmit rules of a port are overriden. - * When not set, the default rules as set by @ref IxEthDB should apply. - * - * @sa IX_ETHACC_NE_FLAGS - * @sa IX_ETHACC_NE_TAGMODEMASK - * - */ -#define IX_ETHACC_NE_TAGOVERMASK (0x1 << 10) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_VLANENABLEMASK - * - * @brief This mask defines if a frame is a VLAN frame or not - * - * When set, frames undergo normal VLAN processing on the Tx path - * (membership filtering, tagging, tag removal etc). If this flag is - * not set, the frame is considered to be a regular non-VLAN frame - * and no VLAN processing will be performed. - * - * Note that VLAN-enabled NPE images will always set this flag in all - * Rx frames, and images which are not VLAN enabled will clear this - * flag for all received frames. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_VLANENABLEMASK (0x1 << 14) - -/** - * @ingroup IxEthAcc - * - * @def IX_ETHACC_NE_NEWSRCMASK - * - * @brief This mask defines if a received frame has been learned. - * - * This mask defines if the source MAC address of a frame is - * already known. If the bit is set, the source MAC address was - * unknown to the NPE at the time the frame was received. - * - * @sa IX_ETHACC_NE_FLAGS - * - */ -#define IX_ETHACC_NE_NEWSRCMASK (0x1 << 15) - -/** - * @ingroup IxEthAcc - * - * @brief This defines the recommanded minimum size of MBUF's submitted - * to the frame receive service. - * - */ -#define IX_ETHACC_RX_MBUF_MIN_SIZE (2048) - -/** - * @ingroup IxEthAcc - * - * @brief This defines the highest MII address of any attached PHYs - * - * The maximum number for PHY address is 31, add on for range checking. - * - */ -#define IXP425_ETH_ACC_MII_MAX_ADDR 32 - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccInit(void) - * - * @brief Initializes the IXP400 Ethernet Access Service. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * This should be called once per module initialization. - * @pre - * The NPE must first be downloaded with the required microcode which supports all - * required features. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Service has failed to initialize. - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccInit(void); - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccUnload(void) - * - * @brief Unload the Ethernet Access Service. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @return void - * - *
- */ -PUBLIC void ixEthAccUnload(void); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortInit( IxEthAccPortId portId) - * - * @brief Initializes an NPE/Ethernet MAC Port. - * - * The NPE/Ethernet port initialisation includes the following steps - * @li Initialize the NPE/Ethernet MAC hardware. - * @li Verify NPE downloaded and operational. - * @li The NPE shall be available for usage once this API returns. - * @li Verify that the Ethernet port is present before initializing - * - * @li Reentrant - no - * @li ISR Callable - no - * - * This should be called once per mac device. - * The NPE/MAC shall be in disabled state after init. - * - * @pre - * The component must be initialized via @a ixEthAccInit - * The NPE must first be downloaded with the required microcode which supports all - * required features. - * - * Dependant on Services: (Must be initialized before using this service may be initialized) - * ixNPEmh - NPE Message handling service. - * ixQmgr - Queue Manager component. - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS: if the ethernet port is not present, a warning is issued. - * @li @a IX_ETH_ACC_FAIL : The NPE processor has failed to initialize. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortInit(IxEthAccPortId portId); - - -/************************************************************************* - - ##### ## ##### ## ##### ## ##### # # - # # # # # # # # # # # # # # - # # # # # # # # # # # # ###### - # # ###### # ###### ##### ###### # # # - # # # # # # # # # # # # # - ##### # # # # # # # # # # # - -*************************************************************************/ - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxFrameSubmit( - IxEthAccPortId portId, - IX_OSAL_MBUF *buffer, - IxEthAccTxPriority priority) - * - * @brief This function shall be used to submit MBUFs buffers for transmission on a particular MAC device. - * - * When the frame is transmitted, the buffer shall be returned thru the - * callback @a IxEthAccPortTxDoneCallback. - * - * In case of over-submitting, the order of the frames on the - * network may be modified. - * - * Buffers shall be not queued for transmission if the port is disabled. - * The port can be enabled using @a ixEthAccPortEnable - * - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * - * @pre - * @a ixEthAccPortTxDoneCallbackRegister must be called to register a function to allow this service to - * return the buffer to the calling service. - * - * @note - * If the buffer submit fails for any reason the user has retained ownership of the buffer. - * - * @param portId @ref IxEthAccPortId [in] - MAC port ID to transmit Ethernet frame on. - * @param buffer @ref IX_OSAL_MBUF [in] - pointer to an MBUF formatted buffer. Chained buffers are supported for transmission. - * Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is ignored. - * @param priority @ref IxEthAccTxPriority [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Failed to queue frame for transmission. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ - -PUBLIC IxEthAccStatus ixEthAccPortTxFrameSubmit( - IxEthAccPortId portId, - IX_OSAL_MBUF *buffer, - IxEthAccTxPriority priority); - -/** - * @ingroup IxEthAcc - * - * @brief Function prototype for Ethernet Tx Buffer Done callback. Registered - * via @a ixEthAccTxBufferDoneCallbackRegister - * - * This function is called once the previously submitted buffer is no longer required by this service. - * It may be returned upon successful transmission of the frame or during the shutdown of - * the port prior to the transmission of a queued frame. - * The calling of this registered function is not a guarantee of successful transmission of the buffer. - * - * - * @li Reentrant - yes , The user provided function should be reentrant. - * @li ISR Callable - yes , The user provided function must be callable from an ISR. - * - * - * Calling Context : - * @par - * This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun - * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. - * The decision is system specific. - * - * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC - * via @a ixEthAccPortTxDoneCallbackRegister. It allows the same callback to be used for multiple MACs. - * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Tx mbuf descriptor. - * - * @return void - * - * @note - * The field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified by the access layer and reset to NULL. - * - *
- */ -typedef void (*IxEthAccPortTxDoneCallback) ( UINT32 callbackTag, IX_OSAL_MBUF *buffer ); - - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxDoneCallbackRegister( IxEthAccPortId portId, - IxEthAccPortTxDoneCallback txCallbackFn, - UINT32 callbackTag) - * - * @brief Register a callback function to allow - * the transmitted buffers to return to the user. - * - * This function registers the transmit buffer done function callback for a particular port. - * - * The registered callback function is called once the previously submitted buffer is no longer required by this service. - * It may be returned upon successful transmission of the frame or shutdown of port prior to submission. - * The calling of this registered function is not a guarantee of successful transmission of the buffer. - * - * If called several times the latest callback shall be registered for a particular port. - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * @pre - * The port must be initialized via @a ixEthAccPortInit - * - * - * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device. - * @param txCallbackFn @ref IxEthAccPortTxDoneCallback [in] - Function to be called to return transmit buffers to the user. - * @param callbackTag UINT32 [in] - This tag shall be provided to the callback function. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId, - IxEthAccPortTxDoneCallback txCallbackFn, - UINT32 callbackTag); - - - -/** - * @ingroup IxEthAcc - * - * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortRxCallbackRegister - * - * It is the responsibility of the user function to free any MBUF's which it receives. - * - * @li Reentrant - yes , The user provided function should be reentrant. - * @li ISR Callable - yes , The user provided function must be callable from an ISR. - * @par - * - * This function dispatches frames to the user level - * via the provided function. The invocation shall be made for each - * frame dequeued from the Ethernet QM queue. The user is required to free any MBUF's - * supplied via this callback. In addition the registered callback must free up MBUF's - * from the receive free queue when the port is disabled - * - * If called several times the latest callback shall be registered for a particular port. - * - * Calling Context : - * @par - * This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun - * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. - * The decision is system specific. - * - * - * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC - * via @a ixEthAccPortRxCallbackRegister. It allows the same callback to be used for multiple MACs. - * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Rx mbuf header. Mbufs may be chained if - * the frame length is greater than the supplied mbuf length. - * @param reserved [in] - deprecated parameter The information is passed - * thru the IxEthAccNe header destination port ID field - * (@sa IX_ETHACC_NE_DESTPORTID). For backward - * compatibility,the value is equal to IX_ETH_DB_UNKNOWN_PORT (0xff). - * - * @return void - * - * @note - * Buffers may not be filled up to the length supplied in - * @a ixEthAccPortRxFreeReplenish(). The firmware fills - * them to the previous 64 bytes boundary. The user has to be aware - * that the length of the received mbufs may be smaller than the length - * of the supplied mbufs. - * The mbuf header contains the following modified field - * @li @a IX_OSAL_MBUF_PKT_LEN is set in the header of the first mbuf and indicates - * the total frame size - * @li @a IX_OSAL_MBUF_MLEN is set each mbuf header and indicates the payload length - * @li @a IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR contains a pointer to the next - * mbuf, or NULL at the end of a chain. - * @li @a IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified. Its value is reset to NULL - * @li @a IX_OSAL_MBUF_FLAGS contains the bit 4 set for a broadcast packet and the bit 5 - * set for a multicast packet. Other bits are unmodified. - * - *
- */ -typedef void (*IxEthAccPortRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF *buffer, UINT32 reserved); - -/** - * @ingroup IxEthAcc - * - * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortMultiBufferRxCallbackRegister - * - * It is the responsibility of the user function to free any MBUF's which it receives. - * - * @li Reentrant - yes , The user provided function should be reentrant. - * @li ISR Callable - yes , The user provided function must be callable from an ISR. - * @par - * - * This function dispatches many frames to the user level - * via the provided function. The invocation shall be made for multiple frames - * dequeued from the Ethernet QM queue. The user is required to free any MBUF's - * supplied via this callback. In addition the registered callback must free up MBUF's - * from the receive free queue when the port is disabled - * - * If called several times the latest callback shall be registered for a particular port. - * - * Calling Context : - * @par - * This callback is called in the context of the queue manager dispatch loop @a ixQmgrDispatcherLoopRun - * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. - * The decision is system specific. - * - * - * @param callbackTag - This tag is that provided when the callback was registered for a particular MAC - * via @a ixEthAccPortMultiBufferRxCallbackRegister. It allows the same callback to be used for multiple MACs. - * @param mbuf - Pointer to an array of Rx mbuf headers. Mbufs - * may be chained if - * the frame length is greater than the supplied mbuf length. - * The end of the array contains a zeroed entry (NULL pointer). - * - * @return void - * - * @note The mbufs passed to this callback have the same structure than the - * buffers passed to @a IxEthAccPortRxCallback interfac. - * - * @note The usage of this callback is exclusive with the usage of - * @a ixEthAccPortRxCallbackRegister and @a IxEthAccPortRxCallback - * - * @sa ixEthAccPortMultiBufferRxCallbackRegister - * @sa IxEthAccPortMultiBufferRxCallback - * @sa ixEthAccPortRxCallbackRegister - * @sa IxEthAccPortRxCallback - *
- */ - -typedef void (*IxEthAccPortMultiBufferRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF **buffer); - - - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortRxCallback rxCallbackFn, UINT32 callbackTag) - * - * @brief Register a callback function to allow - * the reception of frames. - * - * The registered callback function is called once a frame is received by this service. - * - * If called several times the latest callback shall be registered for a particular port. - * - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * - * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device. - * @param rxCallbackFn @ref IxEthAccPortRxCallback [in] - Function to be called when Ethernet frames are availble. - * @param callbackTag UINT32 [in] - This tag shall be provided to the callback function. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxCallbackRegister(IxEthAccPortId portId, - IxEthAccPortRxCallback rxCallbackFn, - UINT32 callbackTag); - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMultiBufferRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortMultiBufferRxCallback rxCallbackFn, UINT32 callbackTag) - * - * @brief Register a callback function to allow - * the reception of frames. - * - * The registered callback function is called once a frame is - * received by this service. If many frames are already received, - * the function is called once. - * - * If called several times the latest callback shall be registered for a particular port. - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * - * @param portId - Register callback for a particular MAC device. - * @param rxCallbackFn - @a IxEthAccMultiBufferRxCallbackFn - Function to be called when Ethernet frames are availble. - * @param callbackTag - This tag shall be provided to the callback function. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. - * - * @sa ixEthAccPortMultiBufferRxCallbackRegister - * @sa IxEthAccPortMultiBufferRxCallback - * @sa ixEthAccPortRxCallbackRegister - * @sa IxEthAccPortRxCallback - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMultiBufferRxCallbackRegister(IxEthAccPortId portId, - IxEthAccPortMultiBufferRxCallback rxCallbackFn, - UINT32 callbackTag); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer) - * - * @brief This function provides buffers for the Ethernet receive path. - * - * This component does not have a buffer management mechanisms built in. All Rx buffers must be supplied to it - * via this interface. - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * @param portId @ref IxEthAccPortId [in] - Provide buffers only to specific Rx MAC. - * @param buffer @ref IX_OSAL_MBUF [in] - Provide an MBUF to the Ethernet receive mechanism. - * Buffers size smaller than IX_ETHACC_RX_MBUF_MIN_SIZE may result in poor - * performances and excessive buffer chaining. Buffers - * larger than this size may be suitable for jumbo frames. - * Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR must be NULL. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Buffer has was not able to queue the - * buffer in the receive service. - * @li @a IX_ETH_ACC_FAIL : Buffer size is less than IX_ETHACC_RX_MBUF_MIN_SIZE - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - * @note - * If the buffer replenish operation fails it is the responsibility - * of the user to free the buffer. - * - * @note - * Sufficient buffers must be supplied to the component to maintain - * receive throughput and avoid rx buffer underflow conditions. - * To meet this goal, It is expected that the user preload the - * component with a sufficent number of buffers prior to enabling the - * NPE Ethernet receive path. The recommended minimum number of - * buffers is 8. - * - * @note - * For maximum performances, the mbuf size should be greater - * than the maximum frame size (Ethernet header, payload and FCS) + 64. - * Supplying smaller mbufs to the service results in mbuf - * chaining and degraded performances. The recommended size - * is @a IX_ETHACC_RX_MBUF_MIN_SIZE, which is - * enough to take care of 802.3 frames and "baby jumbo" frames without - * chaining, and "jumbo" frame within chaining. - * - * @note - * Buffers may not be filled up to their length. The firware fills - * them up to the previous 64 bytes boundary. The user has to be aware - * that the length of the received mbufs may be smaller than the length - * of the supplied mbufs. - * - * @warning This function checks the parameters if the NDEBUG - * flag is not defined. Turning on the argument checking (disabled by - * default) results in a lower EthAcc performance as this function - * is part of the data path. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer); - - - -/*************************************************************** - - #### #### # # ##### ##### #### # - # # # # ## # # # # # # # - # # # # # # # # # # # # - # # # # # # # ##### # # # - # # # # # ## # # # # # # - #### #### # # # # # #### ###### - - - ##### # ## # # ###### - # # # # # ## # # - # # # # # # # # ##### - ##### # ###### # # # # - # # # # # ## # - # ###### # # # # ###### - -***************************************************************/ - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortEnable(IxEthAccPortId portId) - * - * @brief This enables an Ethernet port for both Tx and Rx. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre The port must first be initialized via @a ixEthAccPortInit and the MAC address - * must be set using @a ixEthAccUnicastMacAddressSet before enabling it - * The rx and Tx Done callbacks registration via @a - * ixEthAccPortTxDoneCallbackRegister amd @a ixEthAccPortRxCallbackRegister - * has to be done before enabling the traffic. - * - * @param portId @ref IxEthAccPortId [in] - Port id to act upon. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized - * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortDisable(IxEthAccPortId portId) - * - * @brief This disables an Ethernet port for both Tx and Rx. - * - * Free MBufs are returned to the user via the registered callback when the port is disabled - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre The port must be enabled with @a ixEthAccPortEnable, otherwise this - * function has no effect - * - * @param portId @ref IxEthAccPortId [in] - Port id to act upon. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized - * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled) - * - * @brief Get the enabled state of a port. - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * @pre The port must first be initialized via @a ixEthAccPortInit - * - * @param portId @ref IxEthAccPortId [in] - Port id to act upon. - * @param enabled BOOL [out] - location to store the state of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId) - * - * @brief Put the Ethernet MAC device in non-promiscuous mode. - * - * In non-promiscuous mode the MAC filters all frames other than - * destination MAC address which matches the following criteria: - * @li Unicast address provisioned via @a ixEthAccUnicastMacAddressSet - * @li All broadcast frames. - * @li Multicast addresses provisioned via @a ixEthAccMulticastAddressJoin - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @sa ixEthAccPortPromiscuousModeSet - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId); - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId) - * - * @brief Put the MAC device in promiscuous mode. - * - * If the device is in promiscuous mode then all all received frames shall be forwared - * to the NPE for processing. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @sa ixEthAccPortPromiscuousModeClear - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortUnicastMacAddressSet( IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) - * - * @brief Configure unicast MAC address for a particular port - * - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortUnicastMacAddressGet( IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) - * - * @brief Get unicast MAC address for a particular MAC port - * - * @pre - * The MAC address must first be set via @a ixEthAccMacPromiscuousModeSet - * If the MAC address has not been set, the function returns a - * IX_ETH_ACC_MAC_UNINITIALIZED status - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * @param *macAddr @ref IxEthAccMacAddr [out] - Ethernet MAC address. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized. - * @li @a IX_ETH_ACC_FAIL : macAddr is invalid. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - - - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMulticastAddressJoin( IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) - * - * @brief Add a multicast address to the MAC address table. - * - * @note - * Due to the operation of the Ethernet MAC multicast filtering mechanism, frames which do not - * have a multicast destination address which were provisioned via this API may be forwarded - * to the NPE's. This is a result of the hardware comparison algorithm used in the destination mac address logic - * within the Ethernet MAC. - * - * See Also: IXP425 hardware development manual. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Error writing to the MAC registers - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMulticastAddressJoinAll( IxEthAccPortId portId) - * - * @brief Filter all frames with multicast dest. - * - * This function clears the MAC address table, and then sets - * the MAC to forward ALL multicast frames to the NPE. - * Specifically, it forwards all frames whose destination address - * has the LSB of the highest byte set (01:00:00:00:00:00). This - * bit is commonly referred to as the "multicast bit". - * Broadcast frames will still be forwarded. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMulticastAddressLeave( IxEthAccPortId portId, - IxEthAccMacAddr *macAddr) - * - * @brief Remove a multicast address from the MAC address table. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_NO_SUCH_ADDR : Failed if MAC address was not in the table. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId, - IxEthAccMacAddr *macAddr); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMulticastAddressLeaveAll( IxEthAccPortId portId) - * - * @brief This function unconfigures the multicast filtering settings - * - * This function first clears the MAC address table, and then sets - * the MAC as configured by the promiscuous mode current settings. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortUnicastAddressShow(IxEthAccPortId portId) - * - * @brief Displays unicast MAC address - * - * Displays unicast address which is configured using - * @a ixEthAccUnicastMacAddressSet. This function also displays the MAC filter used - * to filter multicast frames. - * - * Other functions modify the MAC filtering - * - * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast - * frames are forwarded to the application - * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the - * effects of @a ixEthAccPortMulticastAddressJoinAll() - * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new - * filtering address - * @li @a ixEthAccPortMulticastAddressJoin() - provision a new - * filtering address - * @li @a ixEthAccPortPromiscuousModeSet() - all frames are - * forwarded to the application regardless of the multicast - * address provisioned - * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded - * to the application following the multicast address provisioned - * - * In all cases, unicast and broadcast addresses are forwarded to - * the application. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return void - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShow(IxEthAccPortId portId); - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortMulticastAddressShow( IxEthAccPortId portId) - * - * @brief Displays multicast MAC address - * - * Displays multicast address which have been configured using @a ixEthAccMulticastAddressJoin - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - Ethernet port id. - * - * @return void - * - *
- */ -PUBLIC void ixEthAccPortMulticastAddressShow( IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortDuplexModeSet( IxEthAccPortId portId, IxEthAccDuplexMode mode ) - * - * @brief Set the duplex mode for the MAC. - * - * Configure the IXP400 MAC to either full or half duplex. - * - * @note - * The configuration should match that provisioned on the PHY. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * @param mode @ref IxEthAccDuplexMode [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortDuplexModeSet(IxEthAccPortId portId,IxEthAccDuplexMode mode); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortDuplexModeGet( IxEthAccPortId portId, IxEthAccDuplexMode *mode ) - * - * @brief Get the duplex mode for the MAC. - * - * return the duplex configuration of the IXP400 MAC. - * - * @note - * The configuration should match that provisioned on the PHY. - * See @a ixEthAccDuplexModeSet - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * @param *mode @ref IxEthAccDuplexMode [out] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- * - */ -PUBLIC IxEthAccStatus -ixEthAccPortDuplexModeGet(IxEthAccPortId portId,IxEthAccDuplexMode *mode ); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxFrameAppendPaddingEnable( IxEthAccPortId portId) - * - * @brief Enable padding bytes to be appended to runt frames submitted to - * this port - * - * Enable up to 60 null-bytes padding bytes to be appended to runt frames - * submitted to this port. This is the default behavior of the access - * component. - * - * @warning Do not change this behaviour while the port is enabled. - * - * @note When Tx padding is enabled, Tx FCS generation is turned on - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @sa ixEthAccPortTxFrameAppendFCSDusable - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxFrameAppendPaddingDisable( IxEthAccPortId portId) - * - * @brief Disable padding bytes to be appended to runt frames submitted to - * this port - * - * Disable padding bytes to be appended to runt frames - * submitted to this port. This is not the default behavior of the access - * component. - * - * @warning Do not change this behaviour while the port is enabled. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxFrameAppendFCSEnable( IxEthAccPortId portId) - * - * @brief Enable the appending of Ethernet FCS to all frames submitted to this port - * - * When enabled, the FCS is added to the submitted frames. This is the default - * behavior of the access component. - * Do not change this behaviour while the port is enabled. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortTxFrameAppendFCSDisable( IxEthAccPortId portId) - * - * @brief Disable the appending of Ethernet FCS to all frames submitted to this port. - * - * When disabled, the Ethernet FCS is not added to the submitted frames. - * This is not the default - * behavior of the access component. - * - * @note Since the FCS is not appended to the frame it is expected that the frame submitted to the - * component includes a valid FCS at the end of the data, although this will not be validated. - * - * The component shall forward the frame to the Ethernet MAC WITHOUT modification. - * - * Do not change this behaviour while the port is enabled. - * - * @note Tx FCS append is not disabled while Tx padding is enabled. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @sa ixEthAccPortTxFrameAppendPaddingEnable - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortRxFrameAppendFCSEnable( IxEthAccPortId portId) - * - * @brief Forward frames with FCS included in the receive buffer. - * - * The FCS is not striped from the receive buffer. - * The received frame length includes the FCS size (4 bytes). ie. - * A minimum sized ethernet frame shall have a length of 64bytes. - * - * Frame FCS validity checks are still carried out on all received frames. - * - * This is not the default - * behavior of the access component. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccPortRxFrameAppendFCSDisable( IxEthAccPortId portId) - * - * @brief Do not forward the FCS portion of the received Ethernet frame to the user. - * The FCS is striped from the receive buffer. - * The received frame length does not include the FCS size (4 bytes). - * Frame FCS validity checks are still carried out on all received frames. - * - * This is the default behavior of the component. - * Do not change this behaviour while the port is enabled. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId); - - - - -/** - * @ingroup IxEthAcc - * - * @enum IxEthAccSchedulerDiscipline - * - * @brief Definition for the port scheduling discipline - * - * Select the port scheduling discipline on receive and transmit path - * @li FIFO : No Priority : In this configuration all frames are processed - * in the access component in the strict order in which - * the component received them. - * @li FIFO : Priority : This shall be a very simple priority mechanism. - * Higher prior-ity frames shall be forwarded - * before lower priority frames. There shall be no - * fairness mechanisms applied across different - * priorities. Higher priority frames could starve - * lower priority frames indefinitely. - */ -typedef enum -{ - FIFO_NO_PRIORITY, /** - */ -PUBLIC IxEthAccStatus -ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, - IxEthAccSchedulerDiscipline sched); - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched) - * - * @brief Set the Rx scheduling to one of @a IxEthAccSchedulerDiscipline - * - * The default behavior of the component is @a FIFO_NO_PRIORITY. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @param sched : @a IxEthAccSchedulerDiscipline - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : Set appropriate discipline. - * @li @a IX_ETH_ACC_FAIL : Invalid/unsupported discipline. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccNpeLoopbackEnable(IxEthAccPortId portId) - * - * @brief Enable NPE loopback - * - * When this loopback mode is enabled all the transmitted frames are - * received on the same port, without payload. - * - * This function is recommended for power-up diagnostic checks and - * should never be used under normal Ethernet traffic operations. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @param portId : ID of the port - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : NPE loopback mode enabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId) - * - * @brief Disable NPE loopback - * - * This function is used to disable the NPE loopback if previously - * enabled using ixEthAccNpeLoopbackEnable. - * - * This function is recommended for power-up diagnostic checks and - * should never be used under normal Ethernet traffic operations. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : NPE loopback successfully disabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortTxEnable(IxEthAccPortId portId) - * - * @brief Enable Tx on the port - * - * This function is the complement of ixEthAccPortTxDisable and should - * be used only after Tx was disabled. A MAC core reset is required before - * this function is called (see @a ixEthAccPortMacReset). - * - * This function is the recommended usage scenario for emergency security - * shutdown and hardware failure recovery and should never be used for throttling - * traffic. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : Tx successfully enabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortTxDisable(IxEthAccPortId portId) - * - * @brief Disable Tx on the port - * - * This function can be used to disable Tx in the MAC core. - * Tx can be re-enabled, although this is not guaranteed, by performing - * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortTxEnable. - * Note that using this function is not recommended, except for shutting - * down Tx for emergency reasons. For proper port shutdown and re-enabling - * see ixEthAccPortEnable and ixEthAccPortDisable. - * - * This function is the recommended usage scenario for emergency security - * shutdown and hardware failure recovery and should never be used for throttling - * traffic. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @pre - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : Tx successfully disabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortTxDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortRxEnable(IxEthAccPortId portId) - * - * @brief Enable Rx on the port - * - * This function is the complement of ixEthAccPortRxDisable and should - * be used only after Rx was disabled. - * - * This function is the recommended usage scenario for emergency security - * shutdown and hardware failure recovery and should never be used for throttling - * traffic. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @pre - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : Rx successfully enabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxEnable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortRxDisable(IxEthAccPortId portId) - * - * @brief Disable Rx on the port - * - * This function can be used to disable Rx in the MAC core. - * Rx can be re-enabled, although this is not guaranteed, by performing - * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortRxEnable. - * Note that using this function is not recommended, except for shutting - * down Rx for emergency reasons. For proper port shutdown and re-enabling - * see ixEthAccPortEnable and ixEthAccPortDisable. - * - * This function is the recommended usage scenario for emergency security - * shutdown and hardware failure recovery and should never be used for throttling - * traffic. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : Rx successfully disabled - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortRxDisable(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn IxEthAccStatus ixEthAccPortMacReset(IxEthAccPortId portId) - * - * @brief Reset MAC core on the port - * - * This function will perform a MAC core reset (NPE Ethernet coprocessor). - * This function is inherently unsafe and the NPE recovery is not guaranteed - * after this function is called. The proper manner of performing port disable - * and enable (which will reset the MAC as well) is ixEthAccPortEnable/ixEthAccPortDisable. - * - * This function is the recommended usage scenario for hardware failure recovery - * and should never be used for throttling traffic. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is - * guaranteed to restore correct Ethernet Tx/Rx operation. - * - * @param portId : ID of the port - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS : MAC core reset - * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccPortMacReset(IxEthAccPortId portId); - -/********************************************************************************* - #### ##### ## ##### # #### ##### # #### #### - # # # # # # # # # # # # - #### # # # # # #### # # # #### - # # ###### # # # # # # # - # # # # # # # # # # # # # # # - #### # # # # # #### # # #### #### -**********************************************************************************/ - - -/** - * - * @brief This struct defines the statistics returned by this component. - * - * The component returns MIB2 EthObj variables which are obtained from the - * hardware or maintained by this component. - * - * - */ -typedef struct -{ - UINT32 dot3StatsAlignmentErrors; /**< link error count (rx) */ - UINT32 dot3StatsFCSErrors; /**< link error count (rx) */ - UINT32 dot3StatsInternalMacReceiveErrors; /**< link error count (rx) */ - UINT32 RxOverrunDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxLearnedEntryDiscards; /**< NPE: discarded frames count(rx) */ - UINT32 RxLargeFramesDiscards; /**< NPE: discarded frames count(rx) */ - UINT32 RxSTPBlockedDiscards; /**< NPE: discarded frames count(rx) */ - UINT32 RxVLANTypeFilterDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxVLANIdFilterDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxInvalidSourceDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxBlackListDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxWhiteListDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 RxUnderflowEntryDiscards; /**< NPE: discarded frames count (rx) */ - UINT32 dot3StatsSingleCollisionFrames; /**< link error count (tx) */ - UINT32 dot3StatsMultipleCollisionFrames; /**< link error count (tx) */ - UINT32 dot3StatsDeferredTransmissions; /**< link error count (tx) */ - UINT32 dot3StatsLateCollisions; /**< link error count (tx) */ - UINT32 dot3StatsExcessiveCollsions; /**< link error count (tx) */ - UINT32 dot3StatsInternalMacTransmitErrors; /**< link error count (tx) */ - UINT32 dot3StatsCarrierSenseErrors; /**< link error count (tx) */ - UINT32 TxLargeFrameDiscards; /**< NPE: discarded frames count (tx) */ - UINT32 TxVLANIdFilterDiscards; /**< NPE: discarded frames count (tx) */ - -}IxEthEthObjStats; - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMibIIStatsGet(IxEthAccPortId portId ,IxEthEthObjStats *retStats ) - * - * @brief Returns the statistics maintained for a port. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * - * @param portId @ref IxEthAccPortId [in] - * @param retStats @ref IxEthEthObjStats [out] - * @note Please note the user is responsible for cache coheriency of the retStat - * buffer. The data is actually populated via the NPE's. As such cache safe - * memory should be used in the retStats argument. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Invalid arguments. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccMibIIStatsGet(IxEthAccPortId portId, IxEthEthObjStats *retStats ); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats) - * - * @brief Returns and clears the statistics maintained for a port. - * - * @li Reentrant - yes - * @li ISR Callable - yes - * - * @pre - * - * @param portId @ref IxEthAccPortId [in] - * @param retStats @ref IxEthEthObjStats [out] - * @note Please note the user is responsible for cache coheriency of the retStats - * buffer. The data is actually populated via the NPE's. As such cache safe - * memory should be used in the retStats argument. - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : invalid arguments. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMibIIStatsClear(IxEthAccPortId portId) - * - * @brief Clears the statistics maintained for a port. - * - * @li Reentrant - yes - * @li ISR Callable - no - * - * @pre - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : Invalid arguments. - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccMibIIStatsClear(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMacInit(IxEthAccPortId portId) - * - * @brief Initializes the ethernet MAC settings - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @param portId @ref IxEthAccPortId [in] - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccMacInit(IxEthAccPortId portId); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccStatsShow(IxEthAccPortId portId) - * - * - * @brief Displays a ports statistics on the standard io console using printf. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @pre - * - * @param portId @ref IxEthAccPortId [in] - * - * @return void - * - *
- */ -PUBLIC void ixEthAccStatsShow(IxEthAccPortId portId); - -/************************************************************************* - - # # # # # # ##### # #### - ## ## # # ## ## # # # # # - # ## # # # # ## # # # # # # - # # # # # # # # # # # - # # # # # # # # # # # - # # # # # # ##### # #### - -*************************************************************************/ - - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMiiReadRtn (UINT8 phyAddr, - UINT8 phyReg, - UINT16 *value) - * - * - * @brief Reads a 16 bit value from a PHY - * - * Reads a 16-bit word from a register of a MII-compliant PHY. Reading - * is performed through the MII management interface. This function returns - * when the read operation has successfully completed, or when a timeout has elapsed. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31) - * @param phyReg UINT8 [in] - the number of the MII register to read (0-31) - * @param value UINT16 [in] - the value read from the register - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : failed to read the register. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccMiiReadRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 *value); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMiiWriteRtn (UINT8 phyAddr, - UINT8 phyReg, - UINT16 value) - * - * - * @brief Writes a 16 bit value to a PHY - * - * Writes a 16-bit word from a register of a MII-compliant PHY. Writing - * is performed through the MII management interface. This function returns - * when the write operation has successfully completed, or when a timeout has elapsed. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31) - * @param phyReg UINT8 [in] - the number of the MII register to write (0-31) - * @param value UINT16 [out] - the value to write to the register - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : failed to write register. - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccMiiWriteRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 value); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMiiAccessTimeoutSet(UINT32 timeout) - * - * @brief Overrides the default timeout value and retry count when reading or - * writing MII registers using ixEthAccMiiWriteRtn or ixEthAccMiiReadRtn - * - * The default behavior of the component is to use a IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS ms - * timeout (declared as 100 in IxEthAccMii_p.h) and a retry count of IX_ETH_ACC_MII_TIMEOUT_10TH_SECS - * (declared as 5 in IxEthAccMii_p.h). - * - * The MII read and write functions will attempt to read the status of the register up - * to the retry count times, delaying between each attempt with the timeout value. - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @pre - * - * @param timeout UINT32 [in] - new timeout value, in milliseconds - * @param timeout UINT32 [in] - new retry count (a minimum value of 1 must be used) - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : invalid parameter(s) - * - *
- */ -PUBLIC IxEthAccStatus -ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount); - -/** - * @ingroup IxEthAcc - * - * @fn ixEthAccMiiStatsShow (UINT32 phyAddr) - * - * - * @brief Displays detailed information on a specified PHY - * - * Displays the current values of the first eigth MII registers for a PHY, - * - * @li Reentrant - no - * @li ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and - * generating the MDIO clock. - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * - * @return IxEthAccStatus - * @li @a IX_ETH_ACC_SUCCESS - * @li @a IX_ETH_ACC_FAIL : invalid arguments. - * - *
- */ -PUBLIC IxEthAccStatus ixEthAccMiiStatsShow (UINT32 phyAddr); - - - -/******* BOARD SPECIFIC DEPRECATED API *********/ - -/* The following functions are high level functions which rely - * on the properties and interface of some Ethernet PHYs. The - * implementation is hardware specific and has been moved to - * the hardware-specific component IxEthMii. - */ - - #include "IxEthMii.h" - -/** - * @ingroup IxEthAcc - * - * @def ixEthAccMiiPhyScan - * - * @brief : deprecated API entry point. This definition - * ensures backward compatibility - * - * See @ref ixEthMiiPhyScan - * - * @note this feature is board specific - * - */ -#define ixEthAccMiiPhyScan(phyPresent) ixEthMiiPhyScan(phyPresent,IXP425_ETH_ACC_MII_MAX_ADDR) - -/** - * @ingroup IxEthAcc - * - * @def ixEthAccMiiPhyConfig - * - * @brief : deprecated API entry point. This definition - * ensures backward compatibility - * - * See @ref ixEthMiiPhyConfig - * - * @note this feature is board specific - */ -#define ixEthAccMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate) \ - ixEthMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate) - -/** - * @ingroup IxEthAcc - * - * @def ixEthAccMiiPhyReset - * - * @brief : deprecated API entry point. This definition - * ensures backward compatibility - * - * See @ref ixEthMiiPhyReset - * - * @note this feature is board specific - */ -#define ixEthAccMiiPhyReset(phyAddr) \ - ixEthMiiPhyReset(phyAddr) - -/** - * @ingroup IxEthAcc - * - * @def ixEthAccMiiLinkStatus - * - * @brief : deprecated API entry point. This definition - * ensures backward compatibility - * - * See @ref ixEthMiiLinkStatus - * - * @note this feature is board specific - */ -#define ixEthAccMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg) \ - ixEthMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg) - - - -/** - * @ingroup IxEthAcc - * - * @def ixEthAccMiiShow - * - * @brief : deprecated API entry point. This definition - * ensures backward compatibility - * - * See @ref ixEthMiiPhyShow - * - * @note this feature is board specific - */ -#define ixEthAccMiiShow(phyAddr) \ - ixEthMiiPhyShow(phyAddr) - -#endif /* ndef IxEthAcc_H */ -/** - *@} - */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h b/arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h deleted file mode 100644 index 8b8e6b2..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthAccDataPlane_p.h +++ /dev/null @@ -1,245 +0,0 @@ -/** - * @file IxEthAccDataPlane_p.h - * - * @author Intel Corporation - * @date 12-Feb-2002 - * - * @brief Internal Header file for IXP425 Ethernet Access component. - * - * Design Notes: - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - - - -#ifndef IxEthAccDataPlane_p_H -#define IxEthAccDataPlane_p_H - -#include -#include - -/** - * @addtogroup IxEthAccPri - *@{ - */ - -/* typedefs global to this file*/ - -typedef struct -{ - IX_OSAL_MBUF *pHead; - IX_OSAL_MBUF *pTail; -}IxEthAccDataPlaneQList; - - -/** - * @struct IxEthAccDataPlaneStats - * @brief Statistics data structure associated with the data plane - * - */ -typedef struct -{ - UINT32 addToSwQ; - UINT32 removeFromSwQ; - UINT32 unchainedTxMBufs; - UINT32 chainedTxMBufs; - UINT32 unchainedTxDoneMBufs; - UINT32 chainedTxDoneMBufs; - UINT32 unchainedRxMBufs; - UINT32 chainedRxMBufs; - UINT32 unchainedRxFreeMBufs; - UINT32 chainedRxFreeMBufs; - UINT32 rxCallbackCounter; - UINT32 rxCallbackBurstRead; - UINT32 txDoneCallbackCounter; - UINT32 unexpectedError; -} IxEthAccDataPlaneStats; - -/** - * @fn ixEthAccMbufFromSwQ - * @brief used during disable steps to convert mbufs from - * swq format, ready to be pushed into hw queues for NPE, - * back into XScale format - */ -IX_OSAL_MBUF *ixEthAccMbufFromSwQ(IX_OSAL_MBUF *mbuf); - -/** - * @fn ixEthAccDataPlaneShow - * @brief Show function (for data plane statistics - */ -void ixEthAccDataPlaneShow(void); - -/* - * lock dataplane when atomic operation is required - */ -#define IX_ETH_ACC_DATA_PLANE_LOCK(arg) arg = ixOsalIrqLock(); -#define IX_ETH_ACC_DATA_PLANE_UNLOCK(arg) ixOsalIrqUnlock(arg); - -/* - * Use MBUF fields - */ -#define IX_ETHACC_NE_SHARED(mBufPtr) \ - ((IxEthAccNe *)&((mBufPtr)->ix_ne)) - -#if 1 - -#define IX_ETHACC_NE_NEXT(mBufPtr) (mBufPtr)->ix_ne.reserved[0] - -/* tm - wrong!! len and pkt_len are in the second word - #define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[3] */ -#define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[1] - -#define IX_ETHACC_NE_DATA(mBufPtr)(mBufPtr)->ix_ne.reserved[2] - -#else - -#define IX_ETHACC_NE_NEXT(mBufPtr) \ - IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_next - -#define IX_ETHACC_NE_LEN(mBufPtr) \ - IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_lengths - -#define IX_ETHACC_NE_DATA(mBufPtr) \ - IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_data -#endif - -/* - * Use MBUF next pointer field to chain data. - */ -#define IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER(mbuf) (mbuf)->ix_ctrl.ix_chain - - - -#define IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(mbuf_list) ((mbuf_list.pHead) == NULL) - - -#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(mbuf_list,mbuf_to_add) \ - do { \ - int lockVal; \ - IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ); \ - if ( (mbuf_list.pHead) != NULL ) \ - { \ - (IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add))) = (mbuf_list.pHead);\ - (mbuf_list.pHead) = (mbuf_to_add); \ - } \ - else { \ - (mbuf_list.pTail) = (mbuf_list.pHead) = (mbuf_to_add); \ - IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \ - } \ - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \ - } while(0) - - -#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(mbuf_list,mbuf_to_add) \ - do { \ - int lockVal; \ - IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ); \ - if ( (mbuf_list.pHead) == NULL ) \ - { \ - (mbuf_list.pHead) = mbuf_to_add; \ - IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \ - } \ - else { \ - IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_list.pTail)) = (mbuf_to_add); \ - IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \ - } \ - (mbuf_list.pTail) = mbuf_to_add; \ - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \ - } while (0) - - -#define IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(mbuf_list,mbuf_to_rem) \ - do { \ - int lockVal; \ - IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \ - if ( (mbuf_list.pHead) != NULL ) \ - { \ - IX_ETH_ACC_STATS_INC(ixEthAccDataStats.removeFromSwQ); \ - (mbuf_to_rem) = (mbuf_list.pHead) ; \ - (mbuf_list.pHead) = (IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_rem)));\ - } \ - else { \ - (mbuf_to_rem) = NULL; \ - } \ - IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \ - } while (0) - - -/** - * @brief message handler QManager entries for NPE id => port ID conversion (NPE_B => 0, NPE_C => 1) - */ -#define IX_ETH_ACC_PORT_TO_NPE_ID(port) \ - ixEthAccPortData[(port)].npeId - -#define IX_ETH_ACC_NPE_TO_PORT_ID(npe) ((npe == 0 ? 2 : (npe == 1 ? 0 : ( npe == 2 ? 1 : -1 )))) - -#define IX_ETH_ACC_PORT_TO_TX_Q_ID(port) \ - ixEthAccPortData[(port)].ixEthAccTxData.txQueue - -#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(port) \ - ixEthAccPortData[(port)].ixEthAccRxData.rxFreeQueue - -#define IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(port) (port == IX_ETH_PORT_1 ? IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE : IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE)) - -#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(port) (port == IX_ETH_PORT_1 ? IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE : IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE )) - -/* Flush the mbufs chain and all data pointed to by the mbuf */ - -#ifndef NDEBUG -#define IX_ETH_ACC_STATS_INC(x) (x++) -#else -#define IX_ETH_ACC_STATS_INC(x) -#endif - -#define IX_ETH_ACC_MAX_TX_FRAMES_TO_SUBMIT 128 - -void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId); -void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId); -void ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId); - -#endif /* IxEthAccDataPlane_p_H */ - - -/** - *@} - */ - diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h b/arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h deleted file mode 100644 index 93e9d98..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthAccMac_p.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - - -#ifndef IxEthAccMac_p_H -#define IxEthAccMac_p_H - -#include "IxOsal.h" - -#define IX_ETH_ACC_MAX_MULTICAST_ADDRESSES 256 -#define IX_ETH_ACC_NUM_PORTS 3 -#define IX_ETH_ACC_MAX_FRAME_SIZE_DEFAULT 1536 -#define IX_ETH_ACC_MAX_FRAME_SIZE_UPPER_RANGE (65536-64) -#define IX_ETH_ACC_MAX_FRAME_SIZE_LOWER_RANGE 64 - -/* - * - * MAC register definitions - * - */ -#define IX_ETH_ACC_MAC_0_BASE IX_OSAL_IXP400_ETHA_PHYS_BASE -#define IX_ETH_ACC_MAC_1_BASE IX_OSAL_IXP400_ETHB_PHYS_BASE -#define IX_ETH_ACC_MAC_2_BASE IX_OSAL_IXP400_ETH_NPEA_PHYS_BASE - -#define IX_ETH_ACC_MAC_TX_CNTRL1 0x000 -#define IX_ETH_ACC_MAC_TX_CNTRL2 0x004 -#define IX_ETH_ACC_MAC_RX_CNTRL1 0x010 -#define IX_ETH_ACC_MAC_RX_CNTRL2 0x014 -#define IX_ETH_ACC_MAC_RANDOM_SEED 0x020 -#define IX_ETH_ACC_MAC_THRESH_P_EMPTY 0x030 -#define IX_ETH_ACC_MAC_THRESH_P_FULL 0x038 -#define IX_ETH_ACC_MAC_BUF_SIZE_TX 0x040 -#define IX_ETH_ACC_MAC_TX_DEFER 0x050 -#define IX_ETH_ACC_MAC_RX_DEFER 0x054 -#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1 0x060 -#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2 0x064 -#define IX_ETH_ACC_MAC_SLOT_TIME 0x070 -#define IX_ETH_ACC_MAC_MDIO_CMD_1 0x080 -#define IX_ETH_ACC_MAC_MDIO_CMD_2 0x084 -#define IX_ETH_ACC_MAC_MDIO_CMD_3 0x088 -#define IX_ETH_ACC_MAC_MDIO_CMD_4 0x08c -#define IX_ETH_ACC_MAC_MDIO_STS_1 0x090 -#define IX_ETH_ACC_MAC_MDIO_STS_2 0x094 -#define IX_ETH_ACC_MAC_MDIO_STS_3 0x098 -#define IX_ETH_ACC_MAC_MDIO_STS_4 0x09c -#define IX_ETH_ACC_MAC_ADDR_MASK_1 0x0A0 -#define IX_ETH_ACC_MAC_ADDR_MASK_2 0x0A4 -#define IX_ETH_ACC_MAC_ADDR_MASK_3 0x0A8 -#define IX_ETH_ACC_MAC_ADDR_MASK_4 0x0AC -#define IX_ETH_ACC_MAC_ADDR_MASK_5 0x0B0 -#define IX_ETH_ACC_MAC_ADDR_MASK_6 0x0B4 -#define IX_ETH_ACC_MAC_ADDR_1 0x0C0 -#define IX_ETH_ACC_MAC_ADDR_2 0x0C4 -#define IX_ETH_ACC_MAC_ADDR_3 0x0C8 -#define IX_ETH_ACC_MAC_ADDR_4 0x0CC -#define IX_ETH_ACC_MAC_ADDR_5 0x0D0 -#define IX_ETH_ACC_MAC_ADDR_6 0x0D4 -#define IX_ETH_ACC_MAC_INT_CLK_THRESH 0x0E0 -#define IX_ETH_ACC_MAC_UNI_ADDR_1 0x0F0 -#define IX_ETH_ACC_MAC_UNI_ADDR_2 0x0F4 -#define IX_ETH_ACC_MAC_UNI_ADDR_3 0x0F8 -#define IX_ETH_ACC_MAC_UNI_ADDR_4 0x0FC -#define IX_ETH_ACC_MAC_UNI_ADDR_5 0x100 -#define IX_ETH_ACC_MAC_UNI_ADDR_6 0x104 -#define IX_ETH_ACC_MAC_CORE_CNTRL 0x1FC - - -/* - * - *Bit definitions - * - */ - -/* TX Control Register 1*/ - -#define IX_ETH_ACC_TX_CNTRL1_TX_EN BIT(0) -#define IX_ETH_ACC_TX_CNTRL1_DUPLEX BIT(1) -#define IX_ETH_ACC_TX_CNTRL1_RETRY BIT(2) -#define IX_ETH_ACC_TX_CNTRL1_PAD_EN BIT(3) -#define IX_ETH_ACC_TX_CNTRL1_FCS_EN BIT(4) -#define IX_ETH_ACC_TX_CNTRL1_2DEFER BIT(5) -#define IX_ETH_ACC_TX_CNTRL1_RMII BIT(6) - -/* TX Control Register 2 */ -#define IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK 0xf - -/* RX Control Register 1 */ -#define IX_ETH_ACC_RX_CNTRL1_RX_EN BIT(0) -#define IX_ETH_ACC_RX_CNTRL1_PADSTRIP_EN BIT(1) -#define IX_ETH_ACC_RX_CNTRL1_CRC_EN BIT(2) -#define IX_ETH_ACC_RX_CNTRL1_PAUSE_EN BIT(3) -#define IX_ETH_ACC_RX_CNTRL1_LOOP_EN BIT(4) -#define IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN BIT(5) -#define IX_ETH_ACC_RX_CNTRL1_RX_RUNT_EN BIT(6) -#define IX_ETH_ACC_RX_CNTRL1_BCAST_DIS BIT(7) - -/* RX Control Register 2 */ -#define IX_ETH_ACC_RX_CNTRL2_DEFER_EN BIT(0) - - - -/* Core Control Register */ -#define IX_ETH_ACC_CORE_RESET BIT(0) -#define IX_ETH_ACC_CORE_RX_FIFO_FLUSH BIT(1) -#define IX_ETH_ACC_CORE_TX_FIFO_FLUSH BIT(2) -#define IX_ETH_ACC_CORE_SEND_JAM BIT(3) -#define IX_ETH_ACC_CORE_MDC_EN BIT(4) - -/* 1st bit of 1st MAC octet */ -#define IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT ( 1) - - -/* - * - * Default values - * - */ - - -#define IX_ETH_ACC_TX_CNTRL1_DEFAULT (IX_ETH_ACC_TX_CNTRL1_TX_EN | \ - IX_ETH_ACC_TX_CNTRL1_RETRY | \ - IX_ETH_ACC_TX_CNTRL1_FCS_EN | \ - IX_ETH_ACC_TX_CNTRL1_2DEFER | \ - IX_ETH_ACC_TX_CNTRL1_PAD_EN) - -#define IX_ETH_ACC_TX_MAX_RETRIES_DEFAULT 0x0f - -#define IX_ETH_ACC_RX_CNTRL1_DEFAULT (IX_ETH_ACC_RX_CNTRL1_CRC_EN \ - | IX_ETH_ACC_RX_CNTRL1_RX_EN) - -#define IX_ETH_ACC_RX_CNTRL2_DEFAULT 0x0 - -/* Thresholds determined by NPE firmware FS */ -#define IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT 0x12 -#define IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT 0x30 - -/* Number of bytes that must be in the tx fifo before - transmission commences*/ -#define IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT 0x8 - -/* One-part deferral values */ -#define IX_ETH_ACC_MAC_TX_DEFER_DEFAULT 0x15 -#define IX_ETH_ACC_MAC_RX_DEFER_DEFAULT 0x16 - -/* Two-part deferral values... */ -#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT 0x08 -#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT 0x07 - -/* This value applies to MII */ -#define IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT 0x80 - -/* This value applies to RMII */ -#define IX_ETH_ACC_MAC_SLOT_TIME_RMII_DEFAULT 0xFF - -#define IX_ETH_ACC_MAC_ADDR_MASK_DEFAULT 0xFF - -#define IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT 0x1 -/*The following is a value chosen at random*/ -#define IX_ETH_ACC_RANDOM_SEED_DEFAULT 0x8 - -/*By default we must configure the MAC to generate the - MDC clock*/ -#define IX_ETH_ACC_CORE_DEFAULT (IX_ETH_ACC_CORE_MDC_EN) - -#define IXP425_ETH_ACC_MAX_PHY 2 -#define IXP425_ETH_ACC_MAX_AN_ENTRIES 20 -#define IX_ETH_ACC_MAC_RESET_DELAY 1 - -#define IX_ETH_ACC_MAC_ALL_BITS_SET 0xFF - -#define IX_ETH_ACC_MAC_MSGID_SHL 24 - -#define IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS 20 -#define IX_ETH_ACC_PORT_DISABLE_DELAY_COUNT 200 /* 4 seconds timeout */ -#define IX_ETH_ACC_PORT_DISABLE_RETRY_COUNT 3 -#define IX_ETH_ACC_MIB_STATS_DELAY_MSECS 2000 /* 2 seconds delay for ethernet stats */ - -/*Register access macros*/ -#if (CPU == SIMSPARCSOLARIS) -extern void registerWriteStub (UINT32 base, UINT32 offset, UINT32 val); -extern UINT32 registerReadStub (UINT32 base, UINT32 offset); - -#define REG_WRITE(b,o,v) registerWriteStub(b, o, v) -#define REG_READ(b,o,v) do { v = registerReadStub(b, o); } while (0) -#else -#define REG_WRITE(b,o,v) IX_OSAL_WRITE_LONG((volatile UINT32 *)(b + o), v) -#define REG_READ(b,o,v) (v = IX_OSAL_READ_LONG((volatile UINT32 *)(b + o))) - -#endif - -void ixEthAccMacUnload(void); -IxEthAccStatus ixEthAccMacMemInit(void); - -/* MAC core loopback */ -IxEthAccStatus ixEthAccPortLoopbackEnable(IxEthAccPortId portId); -IxEthAccStatus ixEthAccPortLoopbackDisable(IxEthAccPortId portId); - -/* MAC core traffic control */ -IxEthAccStatus ixEthAccPortTxEnablePriv(IxEthAccPortId portId); -IxEthAccStatus ixEthAccPortTxDisablePriv(IxEthAccPortId portId); -IxEthAccStatus ixEthAccPortRxEnablePriv(IxEthAccPortId portId); -IxEthAccStatus ixEthAccPortRxDisablePriv(IxEthAccPortId portId); -IxEthAccStatus ixEthAccPortMacResetPriv(IxEthAccPortId portId); - -/* NPE software loopback */ -IxEthAccStatus ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId); -IxEthAccStatus ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId); - -#endif /*IxEthAccMac_p_H*/ - diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h b/arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h deleted file mode 100644 index 568d4a0..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthAccMii_p.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file IxEthAccMii_p.h - * - * @author Intel Corporation - * @date - * - * @brief MII Header file - * - * Design Notes: - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#ifndef IxEthAccMii_p_H -#define IxEthAccMii_p_H - -/* MII definitions - these have been verified against the LXT971 and LXT972 PHYs*/ - -#define IXP425_ETH_ACC_MII_MAX_REG 32 /* max register per phy */ - -#define IX_ETH_ACC_MII_REG_SHL 16 -#define IX_ETH_ACC_MII_ADDR_SHL 21 - -/* Definitions for MII access routines*/ - -#define IX_ETH_ACC_MII_GO BIT(31) -#define IX_ETH_ACC_MII_WRITE BIT(26) -#define IX_ETH_ACC_MII_TIMEOUT_10TH_SECS 5 -#define IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS 100 -#define IX_ETH_ACC_MII_READ_FAIL BIT(31) - -#define IX_ETH_ACC_MII_PHY_DEF_DELAY 300 /* max delay before link up, etc. */ -#define IX_ETH_ACC_MII_PHY_NO_DELAY 0x0 /* do not delay */ -#define IX_ETH_ACC_MII_PHY_NULL 0xff /* PHY is not present */ -#define IX_ETH_ACC_MII_PHY_DEF_ADDR 0x0 /* default PHY's logical address */ - -#ifndef IX_ETH_ACC_MII_MONITOR_DELAY -# define IX_ETH_ACC_MII_MONITOR_DELAY 0x5 /* in seconds */ -#endif - -/* Register definition */ - -#define IX_ETH_ACC_MII_CTRL_REG 0x0 /* Control Register */ -#define IX_ETH_ACC_MII_STAT_REG 0x1 /* Status Register */ -#define IX_ETH_ACC_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */ -#define IX_ETH_ACC_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */ -#define IX_ETH_ACC_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */ - /* Advertisement Register */ -#define IX_ETH_ACC_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */ - /* partner ability Register */ -#define IX_ETH_ACC_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */ - /* Expansion Register */ -#define IX_ETH_ACC_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */ - /* next-page transmit Register */ - -IxEthAccStatus ixEthAccMdioShow (void); -IxEthAccStatus ixEthAccMiiInit(void); -void ixEthAccMiiUnload(void); - -#endif /*IxEthAccMii_p_H*/ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h b/arch/arm/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h deleted file mode 100644 index e5fd16e..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthAccQueueAssign_p.h +++ /dev/null @@ -1,137 +0,0 @@ -/** - * @file IxEthAccQueueAssign_p.h - * - * @author Intel Corporation - * @date 06-Mar-2002 - * - * @brief Mapping from QMgr Q's to internal assignment - * - * Design Notes: - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @addtogroup IxEthAccPri - *@{ - */ - -/* - * Os/System dependancies. - */ -#include "IxOsal.h" - -/* - * Intermodule dependancies - */ -#include "IxQMgr.h" -#include "IxQueueAssignments.h" - -/* Check range of Q's assigned to this component. */ -#if IX_ETH_ACC_RX_FRAME_ETH_Q >= (IX_QMGR_MIN_QUEUPP_QID ) | \ - IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \ - IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \ - IX_ETH_ACC_TX_FRAME_ENET0_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \ - IX_ETH_ACC_TX_FRAME_ENET1_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \ - IX_ETH_ACC_TX_FRAME_DONE_ETH_Q >= (IX_QMGR_MIN_QUEUPP_QID) -#error "Not all Ethernet Access Queues are betweem 1-31, requires full functionalty Q's unless otherwise validated " -#endif - -/** -* -* @typedef IxEthAccQregInfo -* -* @brief -* -*/ -typedef struct -{ - IxQMgrQId qId; - char *qName; - IxQMgrCallback qCallback; - IxQMgrCallbackId callbackTag; - IxQMgrQSizeInWords qSize; - IxQMgrQEntrySizeInWords qWords; - BOOL qNotificationEnableAtStartup; - IxQMgrSourceId qConditionSource; - IxQMgrWMLevel AlmostEmptyThreshold; - IxQMgrWMLevel AlmostFullThreshold; - -} IxEthAccQregInfo; - -/* - * Prototypes for all QM callbacks. - */ - -/* - * Rx Callbacks - */ -IX_ETH_ACC_PUBLIC -void ixEthRxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId); - -IX_ETH_ACC_PUBLIC -void ixEthRxMultiBufferQMCallback(IxQMgrQId, IxQMgrCallbackId); - -IX_ETH_ACC_PUBLIC -void ixEthRxFreeQMCallback(IxQMgrQId, IxQMgrCallbackId); - -/* - * Tx Callback. - */ -IX_ETH_ACC_PUBLIC -void ixEthTxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId); - -IX_ETH_ACC_PUBLIC -void ixEthTxFrameDoneQMCallback(IxQMgrQId, IxQMgrCallbackId ); - - -#define IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY (IX_QMGR_Q_PRIORITY_0) /* Highest priority */ - -/* - * Queue watermarks - */ -#define IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_NOT_E ) -#define IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) -#define IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) -#define IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) -#define IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) -#define IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) -#define IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) -#define IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_NOT_E ) diff --git a/arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h b/arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h deleted file mode 100644 index 4e0de82..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthAcc_p.h +++ /dev/null @@ -1,325 +0,0 @@ -/** - * @file IxEthAcc_p.h - * - * @author Intel Corporation - * @date 12-Feb-2002 - * - * @brief Internal Header file for IXP425 Ethernet Access component. - * - * Design Notes: - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @addtogroup IxEthAccPri - *@{ - */ - -#ifndef IxEthAcc_p_H -#define IxEthAcc_p_H - -/* - * Os/System dependancies. - */ -#include "IxOsal.h" - -/* - * Intermodule dependancies - */ -#include "IxNpeDl.h" -#include "IxQMgr.h" - -#include "IxEthNpe.h" - -/* - * Intra module dependancies - */ - -#include "IxEthAccDataPlane_p.h" -#include "IxEthAccMac_p.h" - - -#define INLINE __inline__ - -#ifdef NDEBUG - -#define IX_ETH_ACC_PRIVATE static - -#else - -#define IX_ETH_ACC_PRIVATE - -#endif /* ndef NDEBUG */ - -#define IX_ETH_ACC_PUBLIC - - -#define IX_ETH_ACC_IS_PORT_VALID(port) ((port) < IX_ETH_ACC_NUMBER_OF_PORTS ? TRUE : FALSE ) - - - -#ifndef NDEBUG -#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);} -#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);} -#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);} -#else -#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);} -#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);} -#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g) {} -#endif - -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccInitDataPlane(void); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrQueuesConfig(void); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries); - -/* prototypes for the private control plane functions (used by the control interface wrapper) */ -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnablePriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDisablePriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressGetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinAllPriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeavePriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeaveAllPriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShowPriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC void ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeSetPriv(IxEthAccPortId portId, IxEthAccDuplexMode mode); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeGetPriv(IxEthAccPortId portId, IxEthAccDuplexMode *mode); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingEnablePriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingDisablePriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSEnablePriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSDisablePriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSEnablePriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSDisablePriv(IxEthAccPortId portId); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched); -IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline sched); - -/** - * @struct ixEthAccRxDataStats - * @brief Stats data structures for data path. - Not obtained from h/w - * - */ -typedef struct -{ - UINT32 rxFrameClientCallback; - UINT32 rxFreeRepOK; - UINT32 rxFreeRepDelayed; - UINT32 rxFreeRepFromSwQOK; - UINT32 rxFreeRepFromSwQDelayed; - UINT32 rxFreeLateNotificationEnabled; - UINT32 rxFreeLowCallback; - UINT32 rxFreeOverflow; - UINT32 rxFreeLock; - UINT32 rxDuringDisable; - UINT32 rxSwQDuringDisable; - UINT32 rxUnlearnedMacAddress; - UINT32 rxPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1]; - UINT32 rxUnexpectedError; - UINT32 rxFiltered; -} IxEthAccRxDataStats; - -/** - * @struct IxEthAccTxDataStats - * @brief Stats data structures for data path. - Not obtained from h/w - * - */ -typedef struct -{ - UINT32 txQOK; - UINT32 txQDelayed; - UINT32 txFromSwQOK; - UINT32 txFromSwQDelayed; - UINT32 txLowThreshCallback; - UINT32 txDoneClientCallback; - UINT32 txDoneClientCallbackDisable; - UINT32 txOverflow; - UINT32 txLock; - UINT32 txPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1]; - UINT32 txLateNotificationEnabled; - UINT32 txDoneDuringDisable; - UINT32 txDoneSwQDuringDisable; - UINT32 txUnexpectedError; -} IxEthAccTxDataStats; - -/* port Disable state machine : list of states */ -typedef enum -{ - /* general port states */ - DISABLED = 0, - ACTIVE, - - /* particular Tx/Rx states */ - REPLENISH, - RECEIVE, - TRANSMIT, - TRANSMIT_DONE -} IxEthAccPortDisableState; - -typedef struct -{ - BOOL fullDuplex; - BOOL rxFCSAppend; - BOOL txFCSAppend; - BOOL txPADAppend; - BOOL enabled; - BOOL promiscuous; - BOOL joinAll; - IxOsalMutex ackMIBStatsLock; - IxOsalMutex ackMIBStatsResetLock; - IxOsalMutex MIBStatsGetAccessLock; - IxOsalMutex MIBStatsGetResetAccessLock; - IxOsalMutex npeLoopbackMessageLock; - IxEthAccMacAddr mcastAddrsTable[IX_ETH_ACC_MAX_MULTICAST_ADDRESSES]; - UINT32 mcastAddrIndex; - IX_OSAL_MBUF *portDisableTxMbufPtr; - IX_OSAL_MBUF *portDisableRxMbufPtr; - - volatile IxEthAccPortDisableState portDisableState; - volatile IxEthAccPortDisableState rxState; - volatile IxEthAccPortDisableState txState; - - BOOL initDone; - BOOL macInitialised; -} IxEthAccMacState; - -/** - * @struct IxEthAccRxInfo - * @brief System-wide data structures associated with the data plane. - * - */ -typedef struct -{ - IxQMgrQId higherPriorityQueue[IX_QMGR_MAX_NUM_QUEUES]; /**< higher priority queue list */ - IxEthAccSchedulerDiscipline schDiscipline; /**< Receive Xscale QoS type */ -} IxEthAccInfo; - -/** - * @struct IxEthAccRxDataInfo - * @brief Per Port data structures associated with the receive data plane. - * - */ -typedef struct -{ - IxQMgrQId rxFreeQueue; /**< rxFree Queue for this port */ - IxEthAccPortRxCallback rxCallbackFn; - UINT32 rxCallbackTag; - IxEthAccDataPlaneQList freeBufferList; - IxEthAccPortMultiBufferRxCallback rxMultiBufferCallbackFn; - UINT32 rxMultiBufferCallbackTag; - BOOL rxMultiBufferCallbackInUse; - IxEthAccRxDataStats stats; /**< Receive s/w stats */ -} IxEthAccRxDataInfo; - -/** - * @struct IxEthAccTxDataInfo - * @brief Per Port data structures associated with the transmit data plane. - * - */ -typedef struct -{ - IxEthAccPortTxDoneCallback txBufferDoneCallbackFn; - UINT32 txCallbackTag; - IxEthAccDataPlaneQList txQ[IX_ETH_ACC_NUM_TX_PRIORITIES]; /**< Transmit Q */ - IxEthAccSchedulerDiscipline schDiscipline; /**< Transmit Xscale QoS */ - IxQMgrQId txQueue; /**< txQueue for this port */ - IxEthAccTxDataStats stats; /**< Transmit s/w stats */ -} IxEthAccTxDataInfo; - - -/** - * @struct IxEthAccPortDataInfo - * @brief Per Port data structures associated with the port data plane. - * - */ -typedef struct -{ - BOOL portInitialized; - UINT32 npeId; /**< NpeId for this port */ - IxEthAccTxDataInfo ixEthAccTxData; /**< Transmit data control structures */ - IxEthAccRxDataInfo ixEthAccRxData; /**< Receive data control structures */ -} IxEthAccPortDataInfo; - -extern IxEthAccPortDataInfo ixEthAccPortData[]; -#define IX_ETH_IS_PORT_INITIALIZED(port) (ixEthAccPortData[port].portInitialized) - -extern BOOL ixEthAccServiceInit; -#define IX_ETH_ACC_IS_SERVICE_INITIALIZED() (ixEthAccServiceInit == TRUE ) - -/* - * Maximum number of frames to consume from the Rx Frame Q. - */ - -#define IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK (128) - -/* - * Max number of times to load the Rx Free Q from callback. - */ -#define IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD (256) /* Set greater than depth of h/w Q + drain time at line rate */ - -/* - * Max number of times to read from the Tx Done Q in one sitting. - */ - -#define IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK (256) - -/* - * Max number of times to take buffers from S/w queues and write them to the H/w Tx - * queues on receipt of a Tx low threshold callback - */ - -#define IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK (16) - - -#define IX_ETH_ACC_FLUSH_CACHE(addr,size) IX_OSAL_CACHE_FLUSH((addr),(size)) -#define IX_ETH_ACC_INVALIDATE_CACHE(addr,size) IX_OSAL_CACHE_INVALIDATE((addr),(size)) - - -#define IX_ETH_ACC_MEMSET(start,value,size) memset(start,value,size) - -#endif /* ndef IxEthAcc_p_H */ - - - diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDB.h b/arch/arm/cpu/ixp/npe/include/IxEthDB.h deleted file mode 100644 index 1189c9a..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthDB.h +++ /dev/null @@ -1,2373 +0,0 @@ -/** @file IxEthDB.h - * - * @brief this file contains the public API of @ref IxEthDB component - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * - */ - -#ifndef IxEthDB_H -#define IxEthDB_H - -#include -#include - -/** - * @defgroup IxEthDB IXP400 Ethernet Database (IxEthDB) API - * - * @brief ethDB is a library that does provides a MAC address database learning/filtering capability - * - *@{ - */ - -#define INLINE __inline__ - -#define IX_ETH_DB_PRIVATE PRIVATE /* imported from IxTypes.h */ - -#define IX_ETH_DB_PUBLIC PUBLIC - -/** - * @brief port ID => message handler NPE id conversion (0 => NPE_B, 1 => NPE_C) - */ -#define IX_ETH_DB_PORT_ID_TO_NPE(id) (id == 0 ? 1 : (id == 1 ? 2 : (id == 2 ? 0 : -1))) - -/** - * @def IX_ETH_DB_NPE_TO_PORT_ID(npe) - * @brief message handler NPE id => port ID conversion (NPE_B => 0, NPE_C => 1) - */ -#define IX_ETH_DB_NPE_TO_PORT_ID(npe) (npe == 0 ? 2 : (npe == 1 ? 0 : (npe == 2 ? 1 : -1))) - -/* temporary define - won't work for Azusa */ -#define IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(id) (IX_ETH_DB_PORT_ID_TO_NPE(id) << 4) -#define IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(id) (IX_ETH_DB_NPE_TO_PORT_ID(id >> 4)) - -/** - * @def IX_IEEE803_MAC_ADDRESS_SIZE - * @brief The size of the MAC address - */ -#define IX_IEEE803_MAC_ADDRESS_SIZE (6) - -/** - * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT - * @brief Number of QoS priorities defined by IEEE802.1Q - */ -#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8) - -/** - * @enum IxEthDBStatus - * @brief Ethernet Database API return values - */ -typedef enum /* IxEthDBStatus */ -{ - IX_ETH_DB_SUCCESS = IX_SUCCESS, /**< Success */ - IX_ETH_DB_FAIL = IX_FAIL, /**< Failure */ - IX_ETH_DB_INVALID_PORT, /**< Invalid port */ - IX_ETH_DB_PORT_UNINITIALIZED, /**< Port not initialized */ - IX_ETH_DB_MAC_UNINITIALIZED, /**< MAC not initialized */ - IX_ETH_DB_INVALID_ARG, /**< Invalid argument */ - IX_ETH_DB_NO_SUCH_ADDR, /**< Address not found for search or delete operations */ - IX_ETH_DB_NOMEM, /**< Learning database memory full */ - IX_ETH_DB_BUSY, /**< Learning database cannot complete operation, access temporarily blocked */ - IX_ETH_DB_END, /**< Database browser passed the end of the record set */ - IX_ETH_DB_INVALID_VLAN, /**< Invalid VLAN ID (valid range is 0..4094, 0 signifies no VLAN membership, used for priority tagged frames) */ - IX_ETH_DB_INVALID_PRIORITY, /**< Invalid QoS priority/traffic class (valid range for QoS priority is 0..7, valid range for traffic class depends on run-time configuration) */ - IX_ETH_DB_NO_PERMISSION, /**< No permission for attempted operation */ - IX_ETH_DB_FEATURE_UNAVAILABLE, /**< Feature not available (or not enabled) */ - IX_ETH_DB_INVALID_KEY, /**< Invalid search key */ - IX_ETH_DB_INVALID_RECORD_TYPE /**< Invalid record type */ -} IxEthDBStatus; - -/** @brief VLAN ID type, valid range is 0..4094, 0 signifying no VLAN membership */ -typedef UINT32 IxEthDBVlanId; - -/** @brief 802.1Q VLAN tag, contains 3 bits user priority, 1 bit CFI, 12 bits VLAN ID */ -typedef UINT32 IxEthDBVlanTag; - -/** @brief QoS priority/traffic class type, valid range is 0..7, 0 being the lowest */ -typedef UINT32 IxEthDBPriority; - -/** @brief Priority mapping table; 0..7 QoS priorities used to index, table contains traffic classes */ -typedef UINT8 IxEthDBPriorityTable[8]; - -/** @brief A 4096 bit array used to map the complete VLAN ID range */ -typedef UINT8 IxEthDBVlanSet[512]; - -#define IX_ETH_DB_802_1Q_VLAN_MASK (0xFFF) -#define IX_ETH_DB_802_1Q_QOS_MASK (0x7) - -#define IX_ETH_DB_802_1Q_MAX_VLAN_ID (0xFFE) - -/** - * @def IX_ETH_DB_SET_VLAN_ID - * @brief returns the given 802.1Q tag with the VLAN ID field substituted with the given VLAN ID - * - * This macro is used to change the VLAN ID in a 802.1Q tag. - * - * Example: - * - * tag = IX_ETH_DB_SET_VLAN_ID(tag, 32) - * - * inserts the VLAN ID "32" in the given tag. - */ -#define IX_ETH_DB_SET_VLAN_ID(vlanTag, vlanID) (((vlanTag) & 0xF000) | ((vlanID) & IX_ETH_DB_802_1Q_VLAN_MASK)) - -/** -* @def IX_ETH_DB_GET_VLAN_ID -* @brief returns the VLAN ID from the given 802.1Q tag -*/ -#define IX_ETH_DB_GET_VLAN_ID(vlanTag) ((vlanTag) & IX_ETH_DB_802_1Q_VLAN_MASK) - -#define IX_ETH_DB_GET_QOS_PRIORITY(vlanTag) (((vlanTag) >> 13) & IX_ETH_DB_802_1Q_QOS_MASK) - -#define IX_ETH_DB_SET_QOS_PRIORITY(vlanTag, priority) (((vlanTag) & 0x1FFF) | (((priority) & IX_ETH_DB_802_1Q_QOS_MASK) << 13)) - -#define IX_ETH_DB_CHECK_VLAN_TAG(vlanTag) { if(((vlanTag & 0xFFFF0000) != 0) || (IX_ETH_DB_GET_VLAN_ID(vlanTag) > 4094)) return IX_ETH_DB_INVALID_VLAN; } - -#define IX_ETH_DB_CHECK_VLAN_ID(vlanId) { if (vlanId > IX_ETH_DB_802_1Q_MAX_VLAN_ID) return IX_ETH_DB_INVALID_VLAN; } - -#define IX_IEEE802_1Q_VLAN_TPID (0x8100) - -typedef enum -{ - IX_ETH_DB_UNTAGGED_FRAMES = 0x1, /**< Accepts untagged frames */ - IX_ETH_DB_VLAN_TAGGED_FRAMES = 0x2, /**< Accepts tagged frames */ - IX_ETH_DB_PRIORITY_TAGGED_FRAMES = 0x4, /**< Accepts tagged frames with VLAN ID set to 0 (no VLAN membership) */ - IX_ETH_DB_ACCEPT_ALL_FRAMES = - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES /**< Accepts all the frames */ -} IxEthDBFrameFilter; - -typedef enum -{ - IX_ETH_DB_PASS_THROUGH = 0x1, /**< Leave frame as-is */ - IX_ETH_DB_ADD_TAG = 0x2, /**< Add default port VLAN tag */ - IX_ETH_DB_REMOVE_TAG = 0x3 /**< Remove VLAN tag from frame */ -} IxEthDBTaggingAction; - -typedef enum -{ - IX_ETH_DB_FIREWALL_WHITE_LIST = 0x1, /**< Firewall operates in white-list mode (MAC address based admission) */ - IX_ETH_DB_FIREWALL_BLACK_LIST = 0x2 /**< Firewall operates in black-list mode (MAC address based blocking) */ -} IxEthDBFirewallMode; - -typedef enum -{ - IX_ETH_DB_FILTERING_RECORD = 0x01, /**< - *
Filtering record
MAC address static/dynamic type age - *
- */ - IX_ETH_DB_FILTERING_VLAN_RECORD = 0x02, /**< - *
VLAN-enabled filtering record
MAC address static/dynamic type age 802.1Q tag - *
- */ - IX_ETH_DB_WIFI_RECORD = 0x04, /**< - *
WiFi header conversion record
MAC address optional gateway MAC address - *
- */ - IX_ETH_DB_FIREWALL_RECORD = 0x08, /**< - *
Firewall record
MAC address - *
- */ - IX_ETH_DB_GATEWAY_RECORD = 0x10, /**< For internal use only */ - IX_ETH_DB_MAX_RECORD_TYPE_INDEX = 0x10, /**< For internal use only */ - IX_ETH_DB_NO_RECORD_TYPE = 0, /**< None of the registered record types */ - IX_ETH_DB_ALL_FILTERING_RECORDS = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD, /**< All the filtering records */ - IX_ETH_DB_ALL_RECORD_TYPES = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD | - IX_ETH_DB_WIFI_RECORD | IX_ETH_DB_FIREWALL_RECORD /**< All the record types registered within EthDB */ -} IxEthDBRecordType; - -typedef enum -{ - IX_ETH_DB_LEARNING = 0x01, /**< Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records */ - IX_ETH_DB_FILTERING = 0x02, /**< Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature */ - IX_ETH_DB_VLAN_QOS = 0x04, /**< VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes */ - IX_ETH_DB_FIREWALL = 0x08, /**< Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists */ - IX_ETH_DB_SPANNING_TREE_PROTOCOL = 0x10, /**< Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes */ - IX_ETH_DB_WIFI_HEADER_CONVERSION = 0x20 /**< WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data */ -} IxEthDBFeature; - -typedef UINT32 IxEthDBProperty; /**< Property ID type */ - -typedef enum -{ - IX_ETH_DB_INTEGER_PROPERTY = 0x1, /**< 4 byte unsigned integer type */ - IX_ETH_DB_STRING_PROPERTY = 0x2, /**< NULL-terminated string type of maximum 255 characters (including the terminator) */ - IX_ETH_DB_MAC_ADDR_PROPERTY = 0x3, /**< 6 byte MAC address type */ - IX_ETH_DB_BOOL_PROPERTY = 0x4 /**< 4 byte boolean type; can contain only TRUE and FALSE values */ -} IxEthDBPropertyType; - -/* list of supported properties for the IX_ETH_DB_VLAN_QOS feature */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY (0x01) /**< Property identifying number the supported number of traffic classes */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY (0x10) /**< Rx queue assigned to traffic class 0 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY (0x11) /**< Rx queue assigned to traffic class 1 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY (0x12) /**< Rx queue assigned to traffic class 2 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY (0x13) /**< Rx queue assigned to traffic class 3 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY (0x14) /**< Rx queue assigned to traffic class 4 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY (0x15) /**< Rx queue assigned to traffic class 5 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY (0x16) /**< Rx queue assigned to traffic class 6 */ -#define IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY (0x17) /**< Rx queue assigned to traffic class 7 */ - -/* private property used by EthAcc to indicate queue configuration complete */ -#define IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (0x18) - -/** - * - * @brief The IEEE 802.3 Ethernet MAC address structure. - * - * The data should be packed with bytes xx:xx:xx:xx:xx:xx - * - * @note The data must be packed in network byte order. - */ -typedef struct -{ - UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; -} IxEthDBMacAddr; - -/** - * @ingroup IxEthDB - * - * @brief Definition of an IXP400 port. - */ -typedef UINT32 IxEthDBPortId; - -/** - * @ingroup IxEthDB - * - * @brief Port dependency map definition - */ -typedef UINT8 IxEthDBPortMap[32]; - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBInit(void) - * - * @brief Initializes the Ethernet learning/filtering database - * - * @note calling this function multiple times does not constitute an error; - * redundant calls will be ignored, returning IX_ETH_DB_SUCCESS - * - * @retval IX_ETH_DB_SUCCESS initialization was successful - * @retval IX_ETH_DB_FAIL initialization failed (OS error) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBInit(void); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBUnload(void) - * - * @brief Stops and prepares the EthDB component for unloading. - * - * @retval IX_ETH_DB_SUCCESS de-initialization was successful - * @retval IX_ETH_DB_BUSY de-initialization failed, ports must be disabled first - * @retval IX_ETH_DB_FAIL de-initialization failed (OS error) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUnload(void); - -/** - * @ingroup IxEthDB - * - * @fn void ixEthDBPortInit(IxEthDBPortId portID) - * - * @brief Initializes a port - * - * This function is called automatically by the Ethernet Access - * ixEthAccPortInit() routine for Ethernet NPE ports and should be manually - * called for any user-defined port (any port that is not one of - * the two Ethernet NPEs). - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to be initialized - * - * @see IxEthDBPortDefs.h for port definitions - * - * @note calling this function multiple times does not constitute an error; - * redundant calls will be ignored - */ -IX_ETH_DB_PUBLIC -void ixEthDBPortInit(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID) - * - * @brief Enables a port - * - * This function is called automatically from the Ethernet Access component - * ixEthAccPortEnable() routine for Ethernet NPE ports and should be manually - * called for any user-defined port (any port that is not one of - * the Ethernet NPEs). - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to enable processing on - * - * @retval IX_ETH_DB_SUCCESS if enabling is successful - * @retval IX_ETH_DB_FAIL if the enabling was not successful due to - * a message handler error - * @retval IX_ETH_DB_MAC_UNINITIALIZED the MAC address of this port was - * not initialized (only for Ethernet NPEs) - * @retval IX_ETH_DB_INVALID_PORT if portID is invalid - * - * @pre ixEthDBPortAddressSet needs to be called prior to enabling the port events - * for Ethernet NPEs - * - * @see ixEthDBPortAddressSet - * - * @see IxEthDBPortDefs.h for port definitions - * - * @note calling this function multiple times does not constitute an error; - * redundant calls will be ignored - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID) - * - * @brief Disables processing on a port - * - * This function is called automatically from the Ethernet Access component - * ixEthAccPortDisable() routine for Ethernet NPE ports and should be manually - * called for any user-defined port (any port that is not one of - * the Ethernet NPEs). - * - * @note Calling ixEthAccPortDisable() will disable the respective Ethernet NPE. - * After Ethernet NPEs are disabled they are stopped therefore - * when re-enabled they need to be reset, downloaded with microcode and started. - * For learning to restart working the user needs to call again - * ixEthAccPortUnicastMacAddressSet or ixEthDBUnicastAddressSet - * with the respective port MAC address. - * Residual MAC addresses learnt before the port was disabled are deleted as soon - * as the port is disabled. This only applies to dynamic (learnt) entries, static - * entries do not dissapear when the port is disabled. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to disable processing on - * - * @retval IX_ETH_DB_SUCCESS if disabling is successful - * @retval IX_ETH_DB_FAIL if the disabling was not successful due to - * a message handler error - * @retval IX_ETH_DB_INVALID_PORT if portID is invalid - * - * @note calling this function multiple times after the first time completed successfully - * does not constitute an error; redundant calls will be ignored and return IX_ETH_DB_SUCCESS -*/ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Sets the port MAC address - * - * This function is to be called from the Ethernet Access component top-level - * ixEthDBUnicastAddressSet(). Event processing cannot be enabled for a port - * until its MAC address has been set. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port whose MAC address is set - * @param macAddr @ref IxEthDBMacAddr [in] - port MAC address - * - * @retval IX_ETH_DB_SUCCESS MAC address was set successfully - * @retval IX_ETH_DB_FAIL MAC address was not set due to a message handler failure - * @retval IX_ETH_DB_INVALID_PORT if the port is not an Ethernet NPE - * - * @see IxEthDBPortDefs.h for port definitions - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize) - * - * @brief Set the maximum frame size supported on the given port ID - * - * This functions set the maximum frame size supported on a specific port ID - * - * - Reentrant - yes - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to configure - * @param maximumFrameSize UINT32 [in] - maximum frame size to configure - * - * @retval IX_ETH_DB_SUCCESS the port is configured - * @retval IX_ETH_DB_PORT_UNINITIALIZED the port has not been initialized - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_INVALID_ARG size parameter is out of range - * @retval IX_ETH_DB_NO_PERMISSION selected port is not an Ethernet NPE - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note - * This maximum frame size is used to filter the frames based on their - * destination addresses and the capabilities of the destination port. - * The mximum value that can be set for a NPE port is 16320. - * (IX_ETHNPE_ACC_FRAME_LENGTH_MAX) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Populate the Ethernet learning/filtering database with a static MAC address - * - * Populates the Ethernet learning/filtering database with a static MAC address. The entry will not be subject to aging. - * If there is an entry (static or dynamic) with the corresponding MAC address on any port this entry will take precedence. - * Any other entry with the same MAC address will be removed. - * - * - Reentrant - yes - * - ISR Callable - yes - * - * @param portID @ref IxEthDBPortId [in] - port ID to add the static address to - * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add - * - * @retval IX_ETH_DB_SUCCESS the add was successful - * @retval IX_ETH_DB_FAIL failed to populate the database entry - * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Populate the Ethernet learning/filtering database with a dynamic MAC address - * - * Populates the Ethernet learning/filtering database with a dynamic MAC address. This entry will be subject to normal - * aging function, if aging is enabled on its port. - * If there is an entry (static or dynamic) with the same MAC address on any port this entry will take precedence. - * Any other entry with the same MAC address will be removed. - * - * - Reentrant - yes - * - ISR Callable - yes - * - * @param portID @ref IxEthDBPortId [in] - port ID to add the dynamic address to - * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add - * - * @retval IX_ETH_DB_SUCCESS the add was successful - * @retval IX_ETH_DB_FAIL failed to populate the database entry - * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr) - * - * @brief Removes a MAC address entry from the Ethernet learning/filtering database - * - * @param macAddr IxEthDBMacAddr [in] - MAC address to remove - * - * - Reentrant - yes - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS the removal was successful - * @retval IX_ETH_DB_NO_SUCH_ADDR failed to remove the address (not in the database) - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Search the Ethernet learning/filtering database for the given MAC address and port ID - * - * This functions searches the database for a specific port ID and MAC address. Both the port ID - * and the MAC address have to match in order for the record to be reported as found. - * - * - Reentrant - yes - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to search for - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for - * - * @retval IX_ETH_DB_SUCCESS the record exists in the database - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) - * - * @brief Search the Ethernet learning/filtering database for a MAC address and return the port ID - * - * Searches the database for a MAC address. The function returns the portID for the - * MAC address record, if found. If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR. - * The portID is only valid if the function finds a match. - * - * - Reentrant - yes - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID the address belongs to (populated only on a successful search) - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for - * - * @retval IX_ETH_DB_SUCCESS the record exists in the database - * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) - * - * @brief Search the filtering database for a MAC address, return the port ID and reset the record age - * - * Searches the database for a MAC address. The function returns the portID for the - * MAC address record and resets the entry age to 0, if found. - * If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR. - * The portID is only valid if the function finds a match. - * - * - Reentrant - yes - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS the MAC address was found - * @retval IX_ETH_DB_NO_SUCH_ADDR the MAC address was not found - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @def IX_ETH_DB_MAINTENANCE_TIME - * - * @brief The @ref ixEthDBDatabaseMaintenance must be called by the user at a frequency of - * IX_ETH_DB_MAINTENANCE_TIME - * - */ -#define IX_ETH_DB_MAINTENANCE_TIME (1 * 60) /* 1 Minute */ - -/** - * @ingroup IxEthDB - * - * @def IX_ETH_DB_LEARNING_ENTRY_AGE_TIME - * - * @brief The define specifies the filtering database age entry time. Static entries older than - * IX_ETH_DB_LEARNING_ENTRY_AGE_TIME +/- IX_ETH_DB_MAINTENANCE_TIME shall be removed. - * - */ -#define IX_ETH_DB_LEARNING_ENTRY_AGE_TIME (15 * 60 ) /* 15 Mins */ - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID) - * - * @brief Disable the aging function for a specific port - * - * @param portID @ref IxEthDBPortId [in] - port ID to disable aging on - * - * - Reentrant - yes - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS aging disabled successfully - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID) - * - * @brief Enable the aging function for a specific port - * - * Enables the aging of dynamic MAC address entries stored in the learning/filtering database - * - * @note The aging function relies on the @ref ixEthDBDatabaseMaintenance being called with a period of - * @ref IX_ETH_DB_MAINTENANCE_TIME seconds. - * - * - Reentrant - yes - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to enable aging on - * - * @retval IX_ETH_DB_SUCCESS aging enabled successfully - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn void ixEthDBDatabaseMaintenance(void) - * - * @brief Performs a maintenance operation on the Ethernet learning/filtering database - * - * In order to perform a database maintenance this function must be called every - * @ref IX_ETH_DB_MAINTENANCE_TIME seconds. It should be called regardless of whether learning is - * enabled or not. - * - * - Reentrant - no - * - ISR Callable - no - * - * @note this function call will be ignored if the learning feature is disabled - */ -IX_ETH_DB_PUBLIC -void ixEthDBDatabaseMaintenance(void); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID) - * - * @brief This function displays the Mac Ethernet MAC address filtering tables. - * - * It displays the MAC address, port ID, entry type (dynamic/static),and age for - * the given port ID. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to display the MAC address entries - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized - * @retval IX_ETH_DB_FAIL record browser failed due to an internal busy or lock condition - * - * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead - * - * @see ixEthDBFilteringDatabaseShowRecords - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn void ixEthDBFilteringDatabaseShowAll(void) - * - * @brief Displays the MAC address recorded in the filtering database for all registered - * ports (see IxEthDBPortDefs.h), grouped by port ID. - * - * - Reentrant - no - * - ISR Callable - no - * - * @retval void - * - * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead - * - * @see ixEthDBFilteringDatabaseShowRecords - */ -IX_ETH_DB_PUBLIC -void ixEthDBFilteringDatabaseShowAll(void); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter) - * - * @brief This function displays per port database records, given a record type filter - * - * The supported record type filters are: - * - * - IX_ETH_DB_FILTERING_RECORD - displays the non-VLAN filtering records (MAC address, age, static/dynamic) - * - IX_ETH_DB_FILTERING_VLAN_RECORD - displays the VLAN filtering records (MAC address, age, static/dynamic, VLAN ID, CFI, QoS class) - * - IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD - displays the previous two types of records - * - IX_ETH_DB_WIFI_RECORD - displays the WiFi header conversion records (MAC address, optional gateway MAC address) and WiFi header conversion parameters (BBSID, Duration/ID) - * - IX_ETH_DB_FIREWALL_RECORD - displays the firewall MAC address table and firewall operating mode (white list/black list) - * - IX_ETH_DB_ALL_RECORD_TYPES - displays all the record types - * - IX_ETH_DB_NO_RECORD_TYPE - displays only the port status (no records are displayed) - * - * Additionally, the status of each port will be displayed, containg the following information: type, capabilities, enabled status, - * aging enabled status, group membership and maximum frame size. - * - * The port ID can either be an actual port or IX_ETH_DB_ALL_PORTS, in which case the requested information - * will be displayed for all the ports (grouped by port) - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID ID of the port to display information on (use IX_ETH_DB_ALL_PORTS for all the ports) - * @param recordFilter record type filter - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is invalid - * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) - * - * @brief Sets the dependency port map for a port - * - * @param portID ID of the port to set the dependency map to - * @param dependencyPortMap new dependency map (as bitmap, each bit set indicates a port being included) - * - * This function is used to share filtering information between ports. - * By adding a port into another port's dependency map the target port - * filtering data will import the filtering data from the port it depends on. - * Any changes to filtering data for a port - such as adding, updating or removing records - - * will trigger updates in the filtering information for all the ports depending on - * on the updated port. - * - * For example, if ports 2 and 3 are set in the port 0 dependency map the filtering - * information for port 0 will also include the filtering information from ports 2 and 3. - * Adding a record to port 2 will also trigger an update not only on port 2 but also on - * port 0. - * - * The dependency map is a 256 bit array where each bit corresponds to a port corresponding to the - * bit offset (bit 0 - port 0, bit 1 - port 1 etc). Setting a bit to 1 indicates that the corresponding - * port is the port map. For example, a dependency port map of 0x14 consists in the ports with IDs 2 and 4. - * Note that the last bit (offset 255) is reserved and should never be set (it will be automatically - * cleared by the function). - * - * By default, each port has a dependency port map consisting only of itself, i.e. - * - * @verbatim - IxEthDBPortMap portMap; - - // clear all ports from port map - memset(portMap, 0, sizeof (portMap)); - - // include portID in port map - portMap[portID / 8] = 1 << (portID % 8); - @endverbatim - * - * - Reentrant - no - * - ISR Callable - no - * - * @note Setting dependency maps is useful for NPE ports, which benefit from automatic updates - * of filtering information. Setting dependency maps for user-defined ports is not an error - * but will have no actual effect. - * - * @note Including a port in its own dependency map is not compulsory, however note that - * in this case updating the port will not trigger an update on the port itself, which - * might not be the intended behavior - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid dependencyPortMap pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) - * - * @brief Retrieves the dependency port map for a port - * - * @param portID ID of the port to set the dependency map to - * @param dependencyPortMap location where the port dependency map is to be copied - * - * This function will copy the port dependency map to a user specified location. - * - * - Reentrant - no - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid dependencyPortMap pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag) - * - * @brief Sets the default 802.1Q VLAN tag for a given port - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to set the default VLAN tag to - * @param vlanTag @ref IxEthDBVlanTag [in] - default 802.1Q VLAN tag - * - * The tag format has 16 bits and it is defined in the IEEE802.1Q specification. - * This tag will be used for tagging untagged frames (if enabled) and classifying - * unexpedited traffic into an internal traffic class (using the user priority field). - * - * - *
802.1Q tag format
3 bits 1 bit 12 bits - *
user priority CFI VID - *
- * - * User Priority : Defines user priority, giving eight (2^3) priority levels. IEEE 802.1P defines - * the operation for these 3 user priority bits - * - * CFI : Canonical Format Indicator is always set to zero for Ethernet switches. CFI is used for - * compatibility reason between Ethernet type network and Token Ring type network. If a frame received - * at an Ethernet port has a CFI set to 1, then that frame should not be forwarded as it is to an untagged port. - * - * VID : VLAN ID is the identification of the VLAN, which is basically used by the standard 802.1Q. - * It has 12 bits and allow the id entification of 4096 (2^12) VLANs. Of the 4096 possible VIDs, a VID of 0 - * is used to identify priority frames and value 4095 (FFF) is reserved, so the maximum possible VLAN - * configurations are 4,094. - * - * - Reentrant - no - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_ETH_DB_INVALID_VLAN vlanTag argument does not parse to a valid 802.1Q VLAN tag - * - * @note a VLAN ID value of 0 indicates that the port is not part of any VLAN - * @note the value of the cannonical frame indicator (CFI) field is ignored, the - * field being used only in frame tagging operations - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag) - * - * @brief Retrieves the default 802.1Q port VLAN tag for a given port (see also @ref ixEthDBPortVlanTagSet) - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the default VLAN tag from - * @param vlanTag @ref IxEthDBVlanTag [out] - location to write the default port 802.1Q VLAN tag to - * - * - Reentrant - no - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid vlanTag pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag) - * - * @brief Sets the 802.1Q VLAN tag for a database record - * - * @param macAddr MAC address - * @param vlanTag 802.1Q VLAN tag - * - * This function is used together with @ref ixEthDBVlanTagGet to provide MAC-based VLAN classification support. - * Please note that the bridging application must contain specific code to make use of this feature (see below). - * - * VLAN tags can be set only in IX_ETH_DB_FILTERING_RECORD or IX_ETH_DB_FILTERING_VLAN_RECORD type records. - * If to an IX_ETH_DB_FILTERING_RECORD type record is added a VLAN tag the record type is automatically - * changed to IX_ETH_DB_FILTERING_VLAN_RECORD. Once this has occurred the record type will never - * revert to a non-VLAN type (unless deleted and re-added). - * - * Record types used for different purposes (such as IX_ETH_DB_WIFI_RECORD) will be ignored by - * this function. - * - * After using this function to associate a VLAN ID with a MAC address the VLAN ID can be extracted knowing the - * MAC address using @ref ixEthDBVlanTagGet. This mechanism can be used to implement MAC-based VLAN classification - * if a bridging application searches for the VLAN tag when receiving a frame based on the source MAC address - * (contained in the ixp_ne_src_mac field of the buffer header). - * If found in the database, the application can instruct the NPE to tag the frame by writing the VLAN tag - * in the ixp_ne_vlan_tci field of the buffer header. This way the NPE will inspect the Egress tagging - * rule associated with the given VLAN ID on the Tx port and tag the frame if Egress tagging on the VLAN is - * allowed. Additionally, Egress tagging can be forced by setting the ixp_ne_tx_flags.tag_over and - * ixp_ne_tx_flags.tag_mode flags in the buffer header. - * - * - Reentrant - no - * - ISR Callable - no - * - * @note this function will not add a filtering record, it can only be used to update an existing one - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer - * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found - * @retval IX_ETH_DB_INVALID_VLAN vlanTag argument does not parse to a valid 802.1Q VLAN tag - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag); - -/** - * @ingroup IxEthDB - * - * @fn ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag) - * - * @brief Retrieves the 802.1Q VLAN tag from a database record given the record MAC address - * - * @param macAddr MAC address - * @param vlanTag location to write the record 802.1Q VLAN tag to - * - * @note VLAN tags can be retrieved only from IX_ETH_DB_FILTERING_VLAN_RECORD type records - * - * This function is used together with ixEthDBVlanTagSet to provide MAC-based VLAN classification support. - * Please note that the bridging application must contain specific code to make use of this feature (see @ref ixEthDBVlanTagSet). - * - * - Reentrant - no - * - ISR Callable - no - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or vlanTag pointer - * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID) - * - * @brief Adds a VLAN ID to a port's VLAN membership table - * - * Adding a VLAN ID to a port's VLAN membership table will cause frames tagged with the specified - * VLAN ID to be accepted by the frame filter, if Ingress VLAN membership filtering is enabled. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to add the VLAN ID membership to - * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be added to the port membership table - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note A port's default VLAN ID is always in its own membership table, hence there - * is no need to explicitly add it using this function (although it is not an error - * to do so) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) - * - * @brief Adds a VLAN ID range to a port's VLAN membership table - * - * All the VLAN IDs in the specified range will be added to the port VLAN - * membership table, including the range start and end VLAN IDs. Tagged frames with - * VLAN IDs in the specified range will be accepted by the frame filter, if Ingress VLAN - * membership filtering is enabled. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to add the VLAN membership range into - * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range - * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case this - * function will behave as @ref ixEthDBPortVlanMembershipAdd - * - * @note A port's default VLAN ID is always in its own membership table, hence there is no need - * to explicitly add it using this function (although it is not an error to do so) - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID) - * - * @brief Removes a VLAN ID from a port's VLAN membership table - * - * Frames tagged with a VLAN ID which is not in a port's VLAN membership table - * will be discarded by the frame filter, if Ingress membership filtering is enabled. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN ID membership from - * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be removed from the port membership table - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID - * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID - * from the port membership table (vlanID was set to the default port VLAN ID) - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note A port's default VLAN ID cannot be removed from the port's membership - * table; attempting it will return IX_ETH_DB_NO_PERMISSION - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) - * - * @brief Removes a VLAN ID range from a port's VLAN membership table - * - * All the VLAN IDs in the specified range will be removed from the port VLAN - * membership table, including the range start and end VLAN IDs. Tagged frames - * with VLAN IDs in the range will be discarded by the frame filter, if Ingress - * membership filtering is enabled. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN membership range from - * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range - * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range - * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID - * from the port membership table (both vlanIDMin and vlanIDMax were set to the default port VLAN ID) - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case - * function will behave as @ref ixEthDBPortVlanMembershipRemove - * - * @note If the given range overlaps the default port VLAN ID this function - * will remove all the VLAN IDs in the range except for the port VLAN ID from its - * own membership table. This situation will be silently dealt with (no error message - * will be returned) as long as the range contains more than one value (i.e. at least - * one other value, apart from the default port VLAN ID). If the function is called - * with the vlanIDMin and vlanIDMax parameters both set to the port default VLAN ID, the - * function will infer that an attempt was specifically made to remove the default port - * VLAN ID from the port membership table, in which case the return value will be - * IX_ETH_DB_NO_PERMISSION. - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) - * - * @brief Sets a port's VLAN membership table - * - * Sets a port's VLAN membership table from a complete VLAN table containing all the possible - * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit - * indicates whether the VLAN at that bit index is in the port's membership list (if set) or - * not (unset). - * - * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no - * other bit must be set if bit 0 is set. - * - * The bit at index 4095 is reserved and should never be set (it will be ignored if set). - * - * The bit referencing the same VLAN ID as the default port VLAN ID should always be set, as - * the membership list must contain at least the default port VLAN ID. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to set the VLAN membership table to - * @param vlanSet @ref IxEthDBVlanSet [in] - pointer to the VLAN membership table - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) - * - * @brief Retrieves a port's VLAN membership table - * - * Retrieves the complete VLAN membership table from a port, containing all the possible - * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit - * indicates whether the VLAN at that bit index is in the port's membership list (if set) or - * not (unset). - * - * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no - * other bit will be set if bit 0 is set. - * - * The bit at index 4095 is reserved and will not be set (it will be ignored if set). - * - * The bit referencing the same VLAN ID as the default port VLAN ID will always be set, as - * the membership list must contain at least the default port VLAN ID. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the VLAN membership table from - * @param vlanSet @ref IxEthDBVlanSet [out] - pointer a location where the VLAN membership table will be - * written to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter) - * - * @brief Sets a port's acceptable frame type filter - * - * The acceptable frame type is one (or a combination) of the following values: - * - IX_ETH_DB_ACCEPT_ALL_FRAMES - accepts all the frames - * - IX_ETH_DB_UNTAGGED_FRAMES - accepts untagged frames - * - IX_ETH_DB_VLAN_TAGGED_FRAMES - accepts tagged frames - * - IX_ETH_DB_PRIORITY_TAGGED_FRAMES - accepts tagged frames with VLAN ID set to 0 (no VLAN membership) - * - * Except for using the exact values given above only the following combinations are valid: - * - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES - * - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_PRIORITY_TAGGED_FRAMES - * - * Please note that IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES is equivalent - * to IX_ETH_DB_ACCEPT_ALL_FRAMES. - * - * - Reentrant - no - * - ISR Callable - no - * - * @note by default the acceptable frame type filter is set to IX_ETH_DB_ACCEPT_ALL_FRAMES - * - * @note setting the acceptable frame type to PRIORITY_TAGGED_FRAMES is internally - * accomplished by changing the frame filter to VLAN_TAGGED_FRAMES and setting the - * VLAN membership list to include only VLAN ID 0; the membership list will need - * to be restored manually to an appropriate value if the acceptable frame type - * filter is changed back to ACCEPT_ALL_FRAMES or VLAN_TAGGED_FRAMES; failure to do so - * will filter all VLAN traffic bar frames tagged with VLAN ID 0 - * - * @param portID @ref IxEthDBPortId [in] - port ID to set the acceptable frame type filter to - * @param frameFilter @ref IxEthDBFrameFilter [in] - acceptable frame type filter - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid frame type filter - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter) - * - * @brief Retrieves a port's acceptable frame type filter - * - * For a description of the acceptable frame types see @ref ixEthDBAcceptableFrameTypeSet - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the acceptable frame type filter from - * @param frameFilter @ref IxEthDBFrameFilter [out] - location to store the acceptable frame type filter - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid frameFilter pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) - * - * @brief Sets a port's priority mapping table - * - * The priority mapping table is an 8x2 table mapping a QoS (user) priority into an internal - * traffic class. There are 8 valid QoS priorities (0..7, 0 being the lowest) which can be - * mapped into one of the 4 available traffic classes (0..3, 0 being the lowest). - * If a custom priority mapping table is not specified using this function the following - * default priority table will be used (as per IEEE 802.1Q and IEEE 802.1D): - * - * - *
QoS traffic classes
QoS priority Default traffic class Traffic type - *
0 1 Best effort, default class for unexpedited traffic - *
1 0 Background traffic - *
2 0 Spare bandwidth - *
3 1 Excellent effort - *
4 2 Controlled load - *
5 2 Video traffic - *
6 3 Voice traffic - *
7 3 Network control - *
- * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - port ID of the port to set the priority mapping table to - * @param priorityTable @ref IxEthDBPriorityTable [in] - location of the user priority table - * - * @note The provided table will be copied into internal data structures in EthDB and - * can be deallocated by the called after this function has completed its execution, if - * so desired - * - * @warning The number of available traffic classes differs depending on the NPE images - * and queue configuration. Check IxEthDBQoS.h for up-to-date information on the availability of - * traffic classes. Note that specifiying a traffic class in the priority map which exceeds - * the system availability will produce an IX_ETH_DB_INVALID_PRIORITY return error code and no - * priority will be remapped. - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid priorityTable pointer - * @retval IX_ETH_DB_INVALID_PRIORITY at least one priority value exceeds - * the current number of available traffic classes - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) - * - * @brief Retrieves a port's priority mapping table - * - * The priority mapping table for the given port will be copied in the location - * specified by the caller using "priorityTable" - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID ID @ref IxEthDBPortId [in] - of the port to retrieve the priority mapping table from - * @param priorityTable @ref IxEthDBPriorityTable [out] - pointer to a user specified location where the table will be copied to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid priorityTable pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass) - * - * @brief Sets one QoS/user priority => traffic class mapping in a port's priority mapping table - * - * This function establishes a mapping between a user (QoS) priority and an internal traffic class. - * The mapping will be saved in the port's priority mapping table. Use this function when not all - * the QoS priorities need remapping (see also @ref ixEthDBPriorityMappingTableSet) - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to - * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest) - * @param trafficClass @ref IxEthDBPriority [in] - internal traffic class, between 0 and 3 (0 being the lowest) - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_PRIORITY userPriority out of range or - * trafficClass is beyond the number of currently available traffic classes - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass) - * - * @brief Retrieves one QoS/user priority => traffic class mapping in a port's priority mapping table - * - * This function retrieves the internal traffic class associated with a QoS (user) priority from a given - * port's priority mapping table. Use this function when not all the QoS priority mappings are - * required (see also @ref ixEthDBPriorityMappingTableGet) - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to - * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest) - * @param trafficClass @ref IxEthDBPriority [out] - location to write the corresponding internal traffic class to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_PRIORITY invalid userPriority value (out of range) - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_ETH_DB_INVALID_ARG invalid trafficClass pointer argument - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled) - * - * @brief Enables or disables Egress VLAN tagging for a port and a given VLAN - * - * This function enables or disables Egress VLAN tagging for the given port and VLAN ID. - * If the VLAN tagging for a certain VLAN ID is enabled then all the frames to be - * transmitted on the given port tagged with the same VLAN ID will be transmitted in a tagged format. - * If tagging is not enabled for the given VLAN ID, the VLAN tag from the frames matching - * this VLAN ID will be removed (the frames will be untagged). - * - * VLAN ID 4095 is reserved and should never be used with this function. - * VLAN ID 0 has the special meaning of "No VLAN membership" and it is used in this - * context to allow the port to send priority-tagged frames or not. - * - * By default, no Egress VLAN tagging is enabled on any port. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on - * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be matched against outgoing frames - * @param enabled BOOL [in] - TRUE to enable Egress VLAN tagging on the port and given VLAN, and - * FALSE to disable Egress VLAN tagging - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range) - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled) - * - * @brief Retrieves the Egress VLAN tagging enabling status for a port and VLAN ID - * - * @param portID [in] - ID of the port to extract the Egress VLAN ID tagging status from - * @param vlanID VLAN [in] - ID whose tagging status is to be extracted - * @param enabled [in] - user-specifed location where the status is copied to; following - * the successfull execution of this function the value will be TRUE if Egress VLAN - * tagging is enabled for the given port and VLAN ID, and FALSE otherwise - * - * - Reentrant - no - * - ISR Callable - no - * - * @see ixEthDBEgressVlanEntryTaggingEnabledGet - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range) - * @retval IX_ETH_DB_INVALID_ARG invalid enabled argument pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled) - * - * @brief Enables or disables Egress VLAN tagging for a port and given VLAN range - * - * This function is very similar to @ref ixEthDBEgressVlanEntryTaggingEnabledSet with the - * difference that it can manipulate the Egress tagging status on multiple VLAN IDs, - * defined by a contiguous range. Note that both limits in the range are explicitly - * included in the execution of this function. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on - * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN range to be matched against outgoing frames - * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN range to be matched against outgoing frames - * @param enabled BOOL [in] - TRUE to enable Egress VLAN tagging on the port and given VLAN range, - * and FALSE to disable Egress VLAN tagging - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range), or do not constitute a range - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_ETH_DB_NO_PERMISSION attempted to explicitly remove the default port VLAN ID from the tagging table - * @retval IX_FAIL unknown OS or NPE communication error - * - * @note Specifically removing the default port VLAN ID from the Egress tagging table by setting both vlanIDMin and vlanIDMax - * to the VLAN ID portion of the PVID is not allowed by this function and will return IX_ETH_DB_NO_PERMISSION. - * However, this can be circumvented, should the user specifically desire this, by either using a - * larger range (vlanIDMin < vlanIDMax) or by using ixEthDBEgressVlanEntryTaggingEnabledSet. - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) - * - * @brief Sets the complete Egress VLAN tagging table for a port - * - * This function is used to set the VLAN tagging/untagging per VLAN ID for a given port - * covering the entire VLAN ID range (0..4094). The vlanSet parameter is a 4096 - * bit array, each bit indicating the Egress behavior for the corresponding VLAN ID. - * If a bit is set then outgoing frames with the corresponding VLAN ID will be transmitted - * with the VLAN tag, otherwise the frame will be transmitted without the VLAN tag. - * - * Bit 0 has a special significance, indicating tagging or tag removal for priority-tagged - * frames. - * - * Bit 4095 is reserved and should never be set (it will be ignored if set). - * - * - Reentrant - no - * - ISR Callable - no - * - * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is set - * @param vlanSet @ref IxEthDBVlanSet [in] - 4096 bit array controlling per-VLAN tagging and untagging - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - * - * @warning This function will automatically add the default port VLAN ID to the Egress tagging table - * every time it is called. The user should manually call ixEthDBEgressVlanEntryTaggingEnabledSet to - * prevent tagging on the default port VLAN ID if the default behavior is not intended. - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) - * - * @brief Retrieves the complete Egress VLAN tagging table from a port - * - * This function copies the 4096 bit table controlling the Egress VLAN tagging into a user specified - * area. Each bit in the array indicates whether tagging for the corresponding VLAN (the bit position - * in the array) is enabled (the bit is set) or not (the bit is unset). - * - * Bit 4095 is reserved and should not be set (it will be ignored if set). - * - * @see ixEthDBEgressVlanTaggingEnabledSet - * - * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is retrieved - * @param vlanSet @ref IxEthDBVlanSet [out] - user location to copy the Egress tagging table into; should have - * room to store 4096 bits (512 bytes) - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction) - * - * @brief Sets the Ingress VLAN tagging behavior for a port - * - * A port's Ingress tagging behavior is controlled by the taggingAction parameter, - * which can take one of the following values: - * - * - IX_ETH_DB_PASS_THROUGH - leaves the frame unchanged (does not add or remove the VLAN tag) - * - IX_ETH_DB_ADD_TAG - adds the VLAN tag if not present, using the default port VID - * - IX_ETH_DB_REMOVE_TAG - removes the VLAN tag if present - * - * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set - * @param taggingAction @ref IxEthDBTaggingAction [in] - tagging behavior for the port - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid taggingAction argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction) - * - * @brief Retrieves the Ingress VLAN tagging behavior from a port (see @ref ixEthDBIngressVlanTaggingEnabledSet) - * - * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set - * @param taggingAction @ref IxEthDBTaggingAction [out] - location where the tagging behavior for the port is written to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid taggingAction pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable) - * - * @brief Enables or disables port ID extraction - * - * This feature can be used in the situation when a multi-port device (e.g. a switch) - * is connected to an IXP4xx port and the device can provide incoming frame port - * identification by tagging the TPID field in the Ethernet frame. Enabling - * port extraction will instruct the NPE to copy the TPID field from the frame and - * place it in the ixp_ne_src_port of the ixp_buf header. In addition, - * the NPE restores the TPID field to 0. - * - * If the frame is not tagged the NPE will fill the ixp_ne_src_port with the - * port ID of the MII interface the frame was received from. - * - * The TPID field is the least significant byte of the type/length field, which is - * normally set to 0x8100 for 802.1Q-tagged frames. - * - * This feature is disabled by default. - * - * @param portID ID of the port to configure port ID extraction on - * @param enable TRUE to enable port ID extraction and FALSE to disable it - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet) - * - * @brief Retrieves the feature capability set for a port - * - * This function retrieves the feature capability set for a port or the common capabilities shared between all - * the ports, writing the feature capability set in a user specified location. - * - * The feature capability set will consist of a set formed by OR-ing one or more of the following values: - * - IX_ETH_DB_LEARNING - Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records - * - IX_ETH_DB_FILTERING - Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature - * - IX_ETH_DB_VLAN_QOS - VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes - * - IX_ETH_DB_FIREWALL - Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists - * - IX_ETH_DB_SPANNING_TREE_PROTOCOL - Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes - * - IX_ETH_DB_WIFI_HEADER_CONVERSION - WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data - * - * Note that EthDB provides only the LEARNING feature for non-NPE ports. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the capability set for - * (use IX_ETH_DB_ALL_PORTS to retrieve the common capabilities shared between all the ports) - * @param featureSet @ref IxEthDBFeature [out] - location where the capability set will be written to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid featureSet pointer - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled) - * - * @brief Enables or disables one or more EthDB features - * - * Selects one or more features (see @ref ixEthDBFeatureCapabilityGet for a description of the supported - * features) to be enabled or disabled on the selected port (or all the ports). - * - * Note that some features are mutually incompatible: - * - IX_ETH_DB_FILTERING is incompatible with IX_ETH_DB_WIFI_HEADER_CONVERSION - * - * Also note that some features require other features to be enabled: - * - IX_ETH_DB_FILTERING requires IX_ETH_DB_LEARNING - * - * This function will either enable the entire selected feature set for the selected port (or all the ports), - * in which case it will return IX_ETH_DB_SUCCESS, or in case of error it will not enable any feature at all - * and return an appropriate error message. - * - * The following features are enabled by default (for ports with the respective capability), - * for compatibility reasons with previous versions of CSR: - * - IX_ETH_DB_LEARNING - * - IX_ETH_DB_FILTERING - * - * All other features are disabled by default and require manual enabling using ixEthDBFeatureEnable. - * - * Default settings for VLAN, QoS, Firewall and WiFi header conversion features: - * - * VLAN - * - * When the VLAN/QoS feature is enabled for a port for the first time the default VLAN behavior - * of the port is set to be as permissive (it will accept all the frames) and - * non-interferential (it will not change any frames) as possible: - * - the port VLAN ID (VID) is set to 0 - * - the Ingress acceptable frame filter is set to accept all frames - * - the VLAN port membership is set to the complete VLAN range (0 - 4094) - * - the Ingress tagging mode is set to pass-through (will not change frames) - * - the Egress tagging mode is to send tagged frames in the entire VLAN range (0 - 4094) - * - * Note that further disabling and re-enabling the VLAN feature for a given port will not reset the port VLAN behavior - * to the settings listed above. Any VLAN settings made by the user are kept. - * - * QoS - * - * The following default priority mapping table will be used (as per IEEE 802.1Q and IEEE 802.1D): - * - * - *
QoS traffic classes
QoS priority Default traffic class Traffic type - *
0 1 Best effort, default class for unexpedited traffic - *
1 0 Background traffic - *
2 0 Spare bandwidth - *
3 1 Excellent effort - *
4 2 Controlled load - *
5 2 Video traffic - *
6 3 Voice traffic - *
7 3 Network control - *
- * - * Firewall - * - * The port firewall is configured by default in black-list mode, and the firewall address table is empty. - * This means the firewall will not filter any frames until the feature is configured and the firewall table is - * downloaded to the NPE. - * - * Spanning Tree - * - * The port is set to STP unblocked mode, therefore it will accept all frames until re-configured. - * - * WiFi header conversion - * - * The WiFi header conversion database is empty, therefore no actual header conversion will take place until this - * feature is configured and the conversion table downloaded to the NPE. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the features on (use IX_ETH_DB_ALL_PORTS for all the ports) - * @param feature @ref IxEthDBFeature [in] - feature or feature set to enable or disable - * @param enabled BOOL [in] - TRUE to enable the feature and FALSE to disable it - * - * @note Certain features, from a functional point of view, cannot be disabled as such at NPE level; - * when such features are set to disabled using the EthDB API they will be configured in such - * a way to determine a behavior equivalent to the feature being disabled. As well as this, disabled - * features cannot be configured or accessed via the EthDB API (except for getting their status). - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_NO_PERMISSION attempted to enable mutually exclusive features, - * or a feature that depends on another feature which is not present or enabled - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE at least one of the features selected is unavailable - * @retval IX_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled) - * - * @brief Retrieves the availability and status of a feature set - * - * This function returns the availability and status for a feature set. - * Note that if more than one feature is selected (e.g. IX_ETH_DB_LEARNING | IX_ETH_DB_FILTERING) - * the "present" and "enabled" return values will be set to TRUE only if all the features in the - * feature set are present and enabled (not only some). - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param feature @ref IxEthDBFeature [in] - identifier of the feature to retrieve the status for - * @param present BOOL [out] - location where a boolean flag indicating whether this feature is present will be written to - * @param enabled BOOL [out] - location where a boolean flag indicating whether this feature is enabled will be written to - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG either present or enabled pointer argument is invalid - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value) - * - * @brief Retrieves the value of a feature property - * - * The EthDB features usually contain feature-specific properties describing or - * controlling how the feature operates. While essential properties (e.g. the - * firewall operating mode) have their own API, secondary properties can be - * retrieved using this function. - * - * Properties can be read-only or read-write. ixEthDBFeaturePropertyGet operates with - * both types of features. - * - * Properties have types associated with them. A descriptor indicating the property - * type is returned in the type argument for convenience. - * - * The currently supported properties and their corresponding features are as follows: - * - * - *
Properties for IX_ETH_DB_VLAN_QOS
Property identifier Property type Property value Read-Only - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY IX_ETH_DB_INTEGER_PROPERTY number of internal traffic classes Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 0 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 1 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 2 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 3 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 4 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 5 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 6 Yes - *
IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 7 Yes - *
- * - * @see ixEthDBFeaturePropertySet - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is retrieved - * @param property @ref IxEthDBProperty [in] - property identifier - * @param type @ref IxEthDBPropertyType [out] - location where the property type will be stored - * @param value void [out] - location where the property value will be stored - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, type or value pointer arguments - * @retval IX_ETH_DB_FAIL incorrect property value or unknown error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value) - * - * @brief Sets the value of a feature property - * - * Unlike @ref ixEthDBFeaturePropertyGet, this function operates only with read-write properties - * - * The currently supported properties and their corresponding features are as follows: - * - * - IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (for IX_ETH_DB_VLAN_QOS): freezes the availability of traffic classes - * to the number of traffic classes currently in use - * - * Note that this function creates deep copies of the property values; once the function is invoked the client - * can free or reuse the memory area containing the original property value. - * - * Copy behavior for different property types is defined as follows: - * - * - IX_ETH_DB_INTEGER_PROPERTY - 4 bytes are copied from the source location - * - IX_ETH_DB_STRING_PROPERTY - the source string will be copied up to the NULL '\0' string terminator, maximum of 255 characters - * - IX_ETH_DB_MAC_ADDR_PROPERTY - 6 bytes are copied from the source location - * - IX_ETH_DB_BOOL_PROPERTY - 4 bytes are copied from the source location; the only allowed values are TRUE (1L) and false (0L) - * - * @see ixEthDBFeaturePropertySet - * - * @warning IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE is provided for EthAcc internal use; - * do not attempt to set this property directly - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is set - * @param property @ref IxEthDBProperty [in] - property identifier - * @param value void [in] - location where the property value is to be copied from - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, value pointer, or invalid property value - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType) - * - * @brief Deletes a set of record types from the Ethernet Database - * - * This function deletes all the records of certain types (specified in the recordType filter) - * associated with a port. Additionally, the IX_ETH_DB_ALL_PORTS value can be used as port ID - * to indicate that the specified record types should be deleted for all the ports. - * - * The record type filter can be an ORed combination of the following types: - * - * Record types - * - IX_ETH_DB_FILTERING_RECORD - * - *
Filtering record
MAC address static/dynamic type age
- * - * - IX_ETH_DB_FILTERING_VLAN_RECORD - * - *
VLAN-enabled filtering record
MAC address static/dynamic type age 802.1Q tag
- * - * - IX_ETH_DB_WIFI_RECORD - * - *
WiFi header conversion record
MAC address optional gateway MAC address
- * - * - IX_ETH_DB_FIREWALL_RECORD - * - *
Firewall record
MAC address
- * - IX_ETH_DB_ALL_RECORD_TYPES - * - * Any combination of the above types is valid e.g. - * - * (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD | IX_ETH_DB_FIREWALL_RECORD), - * - * although some might be redundant (it is not an error to do so) e.g. - * - * (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_ALL_RECORD_TYPES) - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param recordType @ref IxEthDBRecordType [in] - record type filter - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG invalid recordType filter - * - * @note If the record type filter contains any unrecognized value (hence the - * IX_ETH_DB_INVALID_ARG error value is returned) no actual records will be deleted. - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Adds an "Access Point to Station" record to the database, for 802.3 => 802.11 frame - * header conversion - * - * Frame header conversion is controlled by the set of MAC addresses - * added using @ref ixEthDBWiFiStationEntryAdd and @ref ixEthDBWiFiAccessPointEntryAdd. - * Conversion arguments are added using @ref ixEthDBWiFiFrameControlSet, - * @ref ixEthDBWiFiDurationIDSet and @ref ixEthDBWiFiBBSIDSet. - * - * Note that adding the same MAC address twice will not return an error - * (but will not accomplish anything either), while re-adding a record previously added - * as an "Access Point to Access Point" will migrate the record to the "Access Point - * to Station" type. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NOMEM maximum number of records reached - * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr) - * - * @brief Adds an "Access Point to Access Point" record to the database - * - * @see ixEthDBWiFiStationEntryAdd - * - * Note that adding the same MAC address twice will simply overwrite the previously - * defined gateway MAC address value in the same record, if the record was previously of the - * "Access Point to Access Point" type. - * - * Re-adding a MAC address as "Access Point to Access Point", which was previously added as - * "Access Point to Station" will migrate the record type to "Access Point to Access Point" and - * record the gateway MAC address. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add - * @param gatewayMacAddr @ref IxEthDBMacAddr [in] - MAC address of the gateway Access Point - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or gatewayMacAddr pointer argument - * @retval IX_ETH_DB_NOMEM maximum number of records reached - * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Removes a WiFi station record - * - * This function removes both types of WiFi records ("Access Point to Station" and - * "Access Point to Access Point"). - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to remove - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NO_SUCH_ADDR specified address was not found in the database - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID) - * - * @brief Downloads the MAC address table for 802.3 => 802.11 frame header - * conversion to the NPE - * - * Note that the frame conversion MAC address table must be individually downloaded - * to each NPE for which the frame header conversion feature is enabled (i.e. it - * is not possible to specify IX_ETH_DB_ALL_PORTS). - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl) - * - * @brief Sets the GlobalFrameControl field - * - * The GlobalFrameControl field is a 2-byte value inserted in the Frame Control - * field for all 802.3 to 802.11 frame header conversions - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param frameControl UINT16 [in] - GlobalFrameControl value - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID) - * - * @brief Sets the GlobalDurationID field - * - * The GlobalDurationID field is a 2-byte value inserted in the Duration/ID - * field for all 802.3 to 802.11 frame header conversions - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param durationID UINT16 [in] - GlobalDurationID field - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid) - * - * @brief Sets the BBSID field - * - * The BBSID field is a 6-byte value which - * identifies the infrastructure of the service set managed - * by the Access Point having the IXP400 as its processor. The value - * is written in the BBSID field of the 802.11 frame header. - * The BBSID value is the MAC address of the Access Point. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param bbsid @ref IxEthDBMacAddr [in] - pointer to 6 bytes containing the BSSID - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid bbsid pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked) - * - * @brief Sets the STP blocked/unblocked state for a port - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param blocked BOOL [in] - TRUE to set the port as STP blocked, FALSE to set it as unblocked - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked) - * - * @brief Retrieves the STP blocked/unblocked state for a port - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param blocked BOOL * [in] - set to TRUE if the port is STP blocked, FALSE otherwise - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid blocked pointer argument - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode) - * - * @brief Sets the firewall mode to use white or black listing - * - * When enabled, the NPE MAC address based firewall support operates in two modes: - * - * - white-list mode (MAC address based admission) - * - mode set to IX_ETH_DB_FIREWALL_WHITE_LIST - * - only packets originating from MAC addresses contained in the firewall address list - * are allowed on the Rx path - * - black-list mode (MAC address based blocking) - * - mode set to IX_ETH_DB_FIREWALL_BLACK_LIST - * - packets originating from MAC addresses contained in the firewall address list - * are discarded - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param mode @ref IxEthDBFirewallMode [in] - firewall mode (IX_ETH_DB_FIREWALL_WHITE_LIST or IX_ETH_DB_FIREWALL_BLACK_LIST) - * - * @note by default the firewall operates in black-list mode with an empty address - * list, hence it doesn't filter any packets - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled - * @retval IX_ETH_DB_INVALID_ARGUMENT mode argument is not a valid firewall configuration mode - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error -*/ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode); - -/** - * @ingroup IxEthDB - * - * @fn ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable) - * - * @brief Enables or disables invalid MAC address filtering - * - * According to IEEE802 it is illegal for a source address to be a multicast - * or broadcast address. If this feature is enabled the NPE inspects the source - * MAC addresses of incoming frames and discards them if invalid addresses are - * detected. - * - * By default this service is enabled, if the firewall feature is supported by the - * NPE image. - * - * @param portID ID of the port - * @param enable TRUE to enable invalid MAC address filtering and FALSE to disable it - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Adds a MAC address to the firewall address list - * - * Note that adding the same MAC address twice will not return an error - * but will not actually accomplish anything. - * - * The firewall MAC address list has a limited number of entries; once - * the maximum number of entries has been reached this function will failed - * to add more addresses, returning IX_ETH_DB_NOMEM. - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be added - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NOMEM maximum number of records reached - * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) - * - * @brief Removes a MAC address from the firewall address list - * - * @param portID @ref IxEthDBPortId [in] - ID of the port - * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be removed - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NO_SUCH_ADDR address not found - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID) - * - * @brief Downloads the MAC firewall table to a port - * - * @param portID ID of the port - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier - * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized - * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled - * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field) - * - * @brief Adds a user-defined field to a database record - * - * This function associates a user-defined field to a database record. - * The user-defined field is passed as a (void *) parameter, hence it can be used - * for any purpose (such as identifying a structure). Retrieving the user-defined field from - * a record is done using @ref ixEthDBUserFieldGet. Note that EthDB never uses the user-defined - * field for any internal operation and it is not aware of the significance of its contents. The - * field is only stored as a pointer. - * - * The database record is identified using a combination of the given parameters, depending on the record type. - * All the record types require the record MAC address. - * - * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address - * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID - * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID - * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID - * - * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking). - * The user-defined field can be cleared using a NULL field parameter. - * - * @param recordType @ref IxEthDBRecordType [in] - type of record (can be IX_ETH_DB_FILTERING_RECORD, - * IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD or IX_ETH_DB_FIREWALL_RECORD) - * @param portID @ref IxEthDBPortId [in] - ID of the port (required only for WIFI and FIREWALL records) - * @param macAddr @ref IxEthDBMacAddr * [in] - MAC address of the record - * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID of the record (required only for FILTERING_VLAN records) - * @param field void * [in] - user defined field - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument - * @retval IX_ETH_DB_NO_SUCH_ADDR record not found - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field); - -/** - * @ingroup IxEthDB - * - * @fn IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field) - * - * @brief Retrieves a user-defined field from a database record - * - * The database record is identified using a combination of the given parameters, depending on the record type. - * All the record types require the record MAC address. - * - * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address - * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID - * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID - * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID - * - * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking). - * - * If no user-defined field was registered with the specified record then NULL will be written - * at the location specified by field. - * - * @param recordType type of record (can be IX_ETH_DB_FILTERING_RECORD, IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD - * or IX_ETH_DB_FIREWALL_RECORD) - * @param portID ID of the port (required only for WIFI and FIREWALL records) - * @param macAddr MAC address of the record - * @param vlanID VLAN ID of the record (required only for FILTERING_VLAN records) - * @param field location to write the user defined field into - * - * @retval IX_ETH_DB_SUCCESS operation completed successfully - * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier - * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or field pointer arguments - * @retval IX_ETH_DB_NO_SUCH_ADDR record not found - */ -IX_ETH_DB_PUBLIC -IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portId, IxEthDBVlanId vlanID, void **field); - -/** - * @} - */ - -#endif /* IxEthDB_H */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h b/arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h deleted file mode 100644 index 1d8b24f..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthDBLocks_p.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @file IxEthAccDBLocks_p.h - * - * @brief Definition of transaction lock stacks and lock utility macros - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#ifndef IxEthAccDBLocks_p_H -#define IxEthAccDBLocks_p_H - -#include "IxOsPrintf.h" - -/* Lock and lock stacks */ -typedef struct -{ - IxOsalFastMutex* locks[MAX_LOCKS]; - UINT32 stackPointer, basePointer; -} LockStack; - -#define TRY_LOCK(mutex) \ - { \ - if (ixOsalFastMutexTryLock(mutex) != IX_SUCCESS) \ - { \ - return IX_ETH_DB_BUSY; \ - } \ - } - - -#define UNLOCK(mutex) { ixOsalFastMutexUnlock(mutex); } - -#define INIT_STACK(stack) \ - { \ - (stack)->basePointer = 0; \ - (stack)->stackPointer = 0; \ - } - -#define PUSH_LOCK(stack, lock) \ - { \ - if ((stack)->stackPointer == MAX_LOCKS) \ - { \ - ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on push, heavy chaining?\n"); \ - UNROLL_STACK(stack); \ - \ - return IX_ETH_DB_NOMEM; \ - } \ - \ - if (ixOsalFastMutexTryLock(lock) == IX_SUCCESS) \ - { \ - (stack)->locks[(stack)->stackPointer++] = (lock); \ - } \ - else \ - { \ - UNROLL_STACK(stack); \ - \ - return IX_ETH_DB_BUSY; \ - } \ - } - -#define POP_LOCK(stack) \ - { \ - ixOsalFastMutexUnlock((stack)->locks[--(stack)->stackPointer]); \ - } - -#define UNROLL_STACK(stack) \ - { \ - while ((stack)->stackPointer > (stack)->basePointer) \ - { \ - POP_LOCK(stack); \ - } \ - } - -#define SHIFT_STACK(stack) \ - { \ - if ((stack)->basePointer == MAX_LOCKS - 1) \ - { \ - ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on shift, heavy chaining?\n"); \ - UNROLL_STACK(stack); \ - \ - return IX_ETH_DB_BUSY; \ - } \ - \ - ixOsalFastMutexUnlock((stack)->locks[(stack)->basePointer++]); \ - } - -#endif /* IxEthAccDBLocks_p_H */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h b/arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h deleted file mode 100644 index 1d6b0bb..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthDBLog_p.h +++ /dev/null @@ -1,227 +0,0 @@ -/** - * @file IxEthDBLog_p.h - * - * @brief definitions of log macros and log configuration - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#include - -#ifdef IX_UNIT_TEST -#define NULL_PRINT_ROUTINE(format, arg...) /* nothing */ -#else -#define NULL_PRINT_ROUTINE if(0) printf -#endif - -/*************************************************** - * Globals * - ***************************************************/ -/* safe to permanently leave these on */ -#define HAS_ERROR_LOG -#define HAS_ERROR_IRQ_LOG -#define HAS_WARNING_LOG - -/*************************************************** - * Log Configuration * - ***************************************************/ - -/* debug output can be turned on unless specifically - declared as a non-debug build */ -#ifndef NDEBUG - -#undef HAS_EVENTS_TRACE -#undef HAS_EVENTS_VERBOSE_TRACE - -#undef HAS_SUPPORT_TRACE -#undef HAS_SUPPORT_VERBOSE_TRACE - -#undef HAS_NPE_TRACE -#undef HAS_NPE_VERBOSE_TRACE -#undef HAS_DUMP_NPE_TREE - -#undef HAS_UPDATE_TRACE -#undef HAS_UPDATE_VERBOSE_TRACE - -#endif /* NDEBUG */ - - -/*************************************************** - * Log Macros * - ***************************************************/ - -/************** Globals ******************/ - -#ifdef HAS_ERROR_LOG - - #define ERROR_LOG printf - -#else - - #define ERROR_LOG NULL_PRINT_ROUTINE - -#endif - -#ifdef HAS_ERROR_IRQ_LOG - - #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) - -#else - - #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ - -#endif - -#ifdef HAS_WARNING_LOG - - #define WARNING_LOG printf - -#else - - #define WARNING_LOG NULL_PRINT_ROUTINE - -#endif - -/************** Events *******************/ - -#ifdef HAS_EVENTS_TRACE - - #define IX_ETH_DB_EVENTS_TRACE printf - #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) - - #ifdef HAS_EVENTS_VERBOSE_TRACE - - #define IX_ETH_DB_EVENTS_VERBOSE_TRACE printf - - #else - - #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE - - #endif /* HAS_EVENTS_VERBOSE_TRACE */ - -#else - - #define IX_ETH_DB_EVENTS_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ - -#endif /* HAS_EVENTS_TRACE */ - -/************** Support *******************/ - -#ifdef HAS_SUPPORT_TRACE - - #define IX_ETH_DB_SUPPORT_TRACE printf - #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) - - #ifdef HAS_SUPPORT_VERBOSE_TRACE - - #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE printf - - #else - - #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE - - #endif /* HAS_SUPPORT_VERBOSE_TRACE */ - -#else - - #define IX_ETH_DB_SUPPORT_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ - -#endif /* HAS_SUPPORT_TRACE */ - -/************** NPE Adaptor *******************/ - -#ifdef HAS_NPE_TRACE - - #define IX_ETH_DB_NPE_TRACE printf - #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) - - #ifdef HAS_NPE_VERBOSE_TRACE - - #define IX_ETH_DB_NPE_VERBOSE_TRACE printf - - #else - - #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE - - #endif /* HAS_NPE_VERBOSE_TRACE */ - -#else - - #define IX_ETH_DB_NPE_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ - -#endif /* HAS_NPE_TRACE */ - -#ifdef HAS_DUMP_NPE_TREE - -#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) ixEthELTDumpTree(eltBaseAddress, eltSize) - -#else - -#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) /* nothing */ - -#endif /* HAS_DUMP_NPE_TREE */ - -/************** Port Update *******************/ - -#ifdef HAS_UPDATE_TRACE - - #define IX_ETH_DB_UPDATE_TRACE printf - - #ifdef HAS_UPDATE_VERBOSE_TRACE - - #define IX_ETH_DB_UPDATE_VERBOSE_TRACE printf - - #else - - #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE - - #endif - -#else /* HAS_UPDATE_VERBOSE_TRACE */ - - #define IX_ETH_DB_UPDATE_TRACE NULL_PRINT_ROUTINE - #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE - -#endif /* HAS_UPDATE_TRACE */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h b/arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h deleted file mode 100644 index ff18160..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthDBMessages_p.h +++ /dev/null @@ -1,258 +0,0 @@ -/** - * @file IxEthDBMessages_p.h - * - * @brief Definitions of NPE messages - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#ifndef IxEthDBMessages_p_H -#define IxEthDBMessages_p_H - -#include -#include -#include "IxEthDB_p.h" - -/* events watched by the Eth event processor */ -#define IX_ETH_DB_MIN_EVENT_ID (IX_ETHNPE_EDB_GETMACADDRESSDATABASE) -#define IX_ETH_DB_MAX_EVENT_ID (IX_ETHNPE_PC_SETAPMACTABLE) - -/* macros to fill and extract data from NPE messages - place any endian conversions here */ -#define RESET_ELT_MESSAGE(message) { memset((void *) &(message), 0, sizeof((message))); } -#define NPE_MSG_ID(msg) ((msg).data[0] >> 24) - -#define FILL_SETPORTVLANTABLEENTRY_MSG(message, portID, setOffset, vlanMembershipSet, ttiSet) \ - do { \ - message.data[0] = (IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY << 24) | (portID << 16) | (setOffset * 2); \ - message.data[1] = (vlanMembershipSet << 8) | ttiSet; \ - } while (0); - -#define FILL_SETPORTVLANTABLERANGE_MSG(message, portID, offset, length, zone) \ - do { \ - message.data[0] = IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE << 24 | portID << 16 | offset << 9 | length << 1; \ - message.data[1] = (UINT32) zone; \ - } while (0); - -#define FILL_SETDEFAULTRXVID_MSG(message, portID, tpid, vlanTag) \ - do { \ - message.data[0] = (IX_ETHNPE_VLAN_SETDEFAULTRXVID << 24) \ - | (portID << 16); \ - \ - message.data[1] = (tpid << 16) | vlanTag; \ - } while (0); - -#define FILL_SETRXTAGMODE_MSG(message, portID, filterMode, tagMode) \ - do { \ - message.data[0] = IX_ETHNPE_VLAN_SETRXTAGMODE << 24 \ - | portID << 16 \ - | filterMode << 2 \ - | tagMode; \ - \ - message.data[1] = 0; \ - } while (0); - -#define FILL_SETRXQOSENTRY(message, portID, classIndex, trafficClass, aqmQueue) \ - do { \ - message.data[0] = IX_ETHNPE_VLAN_SETRXQOSENTRY << 24 \ - | portID << 16 \ - | classIndex; \ - \ - message.data[1] = trafficClass << 24 \ - | 0x1 << 23 \ - | aqmQueue << 16 \ - | aqmQueue << 4; \ - } while (0); - -#define FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable) \ - do { \ - message.data[0] = IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE << 24 \ - | portID << 16 \ - | (enable ? 0x1 : 0x0); \ - \ - message.data[1] = 0; \ - } while (0); - - -#define FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked) \ - do { \ - message.data[0] = IX_ETHNPE_STP_SETBLOCKINGSTATE << 24 \ - | portID << 16 \ - | (blocked ? 0x1 : 0x0); \ - \ - message.data[1] = 0; \ - } while (0); - -#define FILL_SETBBSID_MSG(message, portID, bbsid) \ - do { \ - message.data[0] = IX_ETHNPE_PC_SETBBSID << 24 \ - | portID << 16 \ - | bbsid->macAddress[0] << 8 \ - | bbsid->macAddress[1]; \ - \ - message.data[1] = bbsid->macAddress[2] << 24 \ - | bbsid->macAddress[3] << 16 \ - | bbsid->macAddress[4] << 8 \ - | bbsid->macAddress[5]; \ - } while (0); - -#define FILL_SETFRAMECONTROLDURATIONID(message, portID, frameControlDurationID) \ - do { \ - message.data[0] = (IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID << 24) | (portID << 16); \ - message.data[1] = frameControlDurationID; \ - } while (0); - -#define FILL_SETAPMACTABLE_MSG(message, zone) \ - do { \ - message.data[0] = IX_ETHNPE_PC_SETAPMACTABLE << 24 \ - | 0 << 8 /* always use index 0 */ \ - | 64; /* 32 entries, 8 bytes each, 4 bytes in a word */ \ - message.data[1] = (UINT32) zone; \ - } while (0); - -#define FILL_SETFIREWALLMODE_MSG(message, portID, epDelta, mode, address) \ - do { \ - message.data[0] = IX_ETHNPE_FW_SETFIREWALLMODE << 24 \ - | portID << 16 \ - | (epDelta & 0xFF) << 8 \ - | mode; \ - \ - message.data[1] = (UINT32) address; \ - } while (0); - -#define FILL_SETMACADDRESSDATABASE_MSG(message, portID, epDelta, blockCount, address) \ - do { \ - message.data[0] = IX_ETHNPE_EDB_SETMACADDRESSSDATABASE << 24 \ - | (epDelta & 0xFF) << 8 \ - | (blockCount & 0xFF); \ - \ - message.data[1] = (UINT32) address; \ - } while (0); - -#define FILL_GETMACADDRESSDATABASE(message, npeId, zone) \ - do { \ - message.data[0] = IX_ETHNPE_EDB_GETMACADDRESSDATABASE << 24; \ - message.data[1] = (UINT32) zone; \ - } while (0); - -#define FILL_SETMAXFRAMELENGTHS_MSG(message, portID, maxRxFrameSize, maxTxFrameSize) \ - do { \ - message.data[0] = IX_ETHNPE_SETMAXFRAMELENGTHS << 24 \ - | portID << 16 \ - | ((maxRxFrameSize + 63) / 64) << 8 /* max Rx 64-byte blocks */ \ - | (maxTxFrameSize + 63) / 64; /* max Tx 64-byte blocks */ \ - \ - message.data[1] = maxRxFrameSize << 16 | maxTxFrameSize; \ - } while (0); - -#define FILL_SETPORTADDRESS_MSG(message, portID, macAddress) \ - do { \ - message.data[0] = IX_ETHNPE_EDB_SETPORTADDRESS << 24 \ - | portID << 16 \ - | macAddress[0] << 8 \ - | macAddress[1]; \ - \ - message.data[1] = macAddress[2] << 24 \ - | macAddress[3] << 16 \ - | macAddress[4] << 8 \ - | macAddress[5]; \ - } while (0); - -/* access to a MAC node in the NPE tree */ -#define NPE_NODE_BYTE(eltNodeAddr, offset) (((UINT8 *) (eltNodeAddr))[offset]) - -/* browsing of the implicit linear binary tree structure of the NPE tree */ -#define LEFT_CHILD_OFFSET(offset) ((offset) << 1) -#define RIGHT_CHILD_OFFSET(offset) (((offset) << 1) + 1) - -#define IX_EDB_FLAGS_ACTIVE (0x2) -#define IX_EDB_FLAGS_VALID (0x1) -#define IX_EDB_FLAGS_RESERVED (0xfc) -#define IX_EDB_FLAGS_INACTIVE_VALID (0x1) - -#define IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET (6) -#define IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET (7) -#define IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET (6) -#define IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET (7) -#define IX_EDB_NPE_NODE_FW_FLAGS_OFFSET (1) -#define IX_EDB_NPE_NODE_FW_RESERVED_OFFSET (6) -#define IX_EDB_NPE_NODE_FW_ADDR_OFFSET (2) - -#define IX_EDB_NPE_NODE_VALID(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_VALID) != 0) -#define IX_EDB_NPE_NODE_ACTIVE(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_ACTIVE) != 0) -#define IX_EDB_NPE_NODE_PORT_ID(address) (NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET)) - -/* macros to send messages to the NPEs */ -#define IX_ETHDB_ASYNC_SEND_NPE_MSG(npeId, msg, result) \ - do { \ - result = ixNpeMhMessageSend(npeId, msg, IX_NPEMH_SEND_RETRIES_DEFAULT); \ - \ - if (result != IX_SUCCESS) \ - { \ - ERROR_LOG("DB: Failed to send NPE message\n"); \ - } \ - } while (0); - -#define IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result) \ - do { \ - result = ixNpeMhMessageWithResponseSend(npeId, msg, msg.data[0] >> 24, ixEthDBNpeMsgAck, IX_NPEMH_SEND_RETRIES_DEFAULT); \ - \ - if (result == IX_SUCCESS) \ - { \ - result = ixOsalMutexLock(&ixEthDBPortInfo[IX_ETH_DB_NPE_TO_PORT_ID(npeId)].npeAckLock, IX_ETH_DB_NPE_TIMEOUT); \ - \ - if (result != IX_SUCCESS) \ - { \ - ERROR_LOG("DB: NPE failed to respond within %dms\n", IX_ETH_DB_NPE_TIMEOUT); \ - } \ - } \ - else \ - { \ - ERROR_LOG("DB: Failed to send NPE message\n"); \ - } \ - } while (0); - -#ifndef IX_NDEBUG -#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100) -extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2]; -extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen; -#endif - -#define IX_ETHDB_SEND_NPE_MSG(npeId, msg, result) { LOG_NPE_MSG(msg); IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result); } - -#endif /* IxEthDBMessages_p_H */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h b/arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h deleted file mode 100644 index c3acbdd..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthDBPortDefs.h +++ /dev/null @@ -1,163 +0,0 @@ -/** - * @file IxEthDBPortDefs.h - * - * @brief Public definition of the ports and port capabilities - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @defgroup IxEthDBPortDefs IXP400 Ethernet Database Port Definitions (IxEthDBPortDefs) - * - * @brief IXP400 Public definition of the ports and port capabilities - * - * @{ - */ - -#ifndef IxEthDBPortDefs_H -#define IxEthDBPortDefs_H - -/** - * @brief Port types - currently only Ethernet NPEs are recognized as specific types - * All other (user-defined) ports must be specified as IX_ETH_GENERIC - */ -typedef enum -{ - IX_ETH_GENERIC = 0, /**< generic ethernet port */ - IX_ETH_NPE /**< specific Ethernet NPE */ -} IxEthDBPortType; - -/** - * @brief Port capabilities - used by ixEthAccDatabaseMaintenance to decide whether it - * should manually age entries or not depending on the port capabilities. - * - * Ethernet NPEs have aging capabilities, meaning that they will age the entries - * automatically (by themselves).*/ -typedef enum -{ - IX_ETH_NO_CAPABILITIES = 0, /**< no aging capabilities */ - IX_ETH_ENTRY_AGING = 0x1 /**< aging capabilities present */ -} IxEthDBPortCapability; - -/** - * @brief Port Definition - a structure contains the Port type and capabilities - */ -typedef struct -{ - IxEthDBPortType type; - IxEthDBPortCapability capabilities; -} IxEthDBPortDefinition; - -/** - * @brief Port definitions structure, indexed on the port ID - * @warning Ports 0 and 1 are used by the Ethernet access component therefore - * it is essential to be left untouched. Port 2 here (WAN) is given as - * an example port. The NPE firmware also assumes the NPE B to be - * the port 0 and NPE C to be the port 1. - * - * @note that only 32 ports (0..31) are supported by EthDB - */ -static const IxEthDBPortDefinition ixEthDBPortDefinitions[] = -{ - /* id type capabilities */ - { /* 0 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE B */ - { /* 1 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE C */ - { /* 2 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE A */ - { /* 3 */ IX_ETH_GENERIC, IX_ETH_NO_CAPABILITIES }, /* WAN port */ -}; - -/** - * @def IX_ETH_DB_NUMBER_OF_PORTS - * @brief number of supported ports - */ -#define IX_ETH_DB_NUMBER_OF_PORTS (sizeof (ixEthDBPortDefinitions) / sizeof (ixEthDBPortDefinitions[0])) - -/** - * @def IX_ETH_DB_UNKNOWN_PORT - * @brief definition of an unknown port - */ -#define IX_ETH_DB_UNKNOWN_PORT (0xff) - -/** - * @def IX_ETH_DB_ALL_PORTS - * @brief Special port ID indicating all the ports - * @note This port ID can be used only by a subset of the EthDB API; each - * function specifically mentions whether this is a valid parameter as the port ID - */ -#define IX_ETH_DB_ALL_PORTS (IX_ETH_DB_NUMBER_OF_PORTS + 1) - -/** - * @def IX_ETH_DB_PORTS_ASSERTION - * @brief catch invalid port definitions (<2) with a - * compile-time assertion resulting in a duplicate case error. - */ -#define IX_ETH_DB_PORTS_ASSERTION { switch(0) { case 0 : ; case 1 : ; case IX_ETH_DB_NUMBER_OF_PORTS : ; }} - -/** - * @def IX_ETH_DB_CHECK_PORT(portID) - * @brief safety checks to verify whether the port is invalid or uninitialized - */ -#define IX_ETH_DB_CHECK_PORT(portID) \ -{ \ - if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ - { \ - return IX_ETH_DB_INVALID_PORT; \ - } \ - \ - if (!ixEthDBPortInfo[(portID)].enabled) \ - { \ - return IX_ETH_DB_PORT_UNINITIALIZED; \ - } \ -} - -/** - * @def IX_ETH_DB_CHECK_PORT_ALL(portID) - * @brief safety checks to verify whether the port is invalid or uninitialized; - * tolerates the use of IX_ETH_DB_ALL_PORTS - */ -#define IX_ETH_DB_CHECK_PORT_ALL(portID) \ -{ \ - if ((portID) != IX_ETH_DB_ALL_PORTS) \ - IX_ETH_DB_CHECK_PORT(portID) \ -} - -#endif /* IxEthDBPortDefs_H */ -/** - *@} - */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h b/arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h deleted file mode 100644 index 6d34889..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthDBQoS.h +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file IxEthDBQoS.h - * - * @brief Public definitions for QoS traffic classes - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @defgroup IxEthDBPortDefs IXP400 Ethernet QoS definitions - * - * @brief IXP00 Public definitions for QoS traffic classes - * - * @{ - */ - -#ifndef IxEthDBQoS_H -#define IxEthDBQoS_H - -/** - * @def IX_ETH_DB_QUEUE_UNAVAILABLE - * @brief alias to indicate a queue (traffic class) is not available - */ -#define IX_ETH_DB_QUEUE_UNAVAILABLE (0) - -#ifndef IX_IEEE802_1Q_QOS_PRIORITY_COUNT -/** - * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT - * @brief number of QoS priorities, according to IEEE 802.1Q - */ -#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8) -#endif - -/** - * @brief array containing all the supported traffic class configurations - */ -static const -UINT8 ixEthDBQueueAssignments[][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] = -{ - { 4, 5, 6, 7, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, - { 15, 16, 17, 18, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, - { 11, 23, 26, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, - { 4, 5, 6, 7, 8, 9, 10, 11 } - /* add here all other cases of queue configuration structures and update ixEthDBTrafficClassDefinitions to use them */ -}; - -/** - * @brief value used to index the NPE A functionality ID in the traffic class definition table - */ -#define IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX (0) - -/** - * @brief value used to index the traffic class count in the traffic class definition table - */ -#define IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX (1) - -/** - * @brief value used to index the queue assignment index in the traffic class definition table - */ -#define IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX (2) - -/** - * @brief traffic class definitions - * - * This array contains the default traffic class definition configuration, - * as well as any special cases dictated by the functionality ID of NPE A. - * - * The default case should not be removed (otherwise the Ethernet - * components will assert a fatal failure on initialization). - */ -static const -UINT8 ixEthDBTrafficClassDefinitions[][3] = -{ - /* NPE A functionality ID | traffic class count | queue assignment index (points to the queue enumeration in ixEthDBQueueAssignments) */ - { 0x00, 4, 0 }, /* default case - DO NOT REMOVE */ - { 0x04, 4, 1 }, /* NPE A image ID 0.4.0.0 */ - { 0x09, 3, 2 }, /* NPE A image ID 0.9.0.0 */ - { 0x80, 8, 3 }, /* NPE A image ID 10.80.02.0 */ - { 0x81, 8, 3 }, /* NPE A image ID 10.81.02.0 */ - { 0x82, 8, 3 } /* NPE A image ID 10.82.02.0 */ -}; - -/** - * @brief IEEE 802.1Q recommended QoS Priority => traffic class maps - * - * @verbatim - Number of available traffic classes - 1 2 3 4 5 6 7 8 - QoS Priority - 0 0 0 0 1 1 1 1 2 - 1 0 0 0 0 0 0 0 0 - 2 0 0 0 0 0 0 0 1 - 3 0 0 0 1 1 2 2 3 - 4 0 1 1 2 2 3 3 4 - 5 0 1 1 2 3 4 4 5 - 6 0 1 2 3 4 5 5 6 - 7 0 1 2 3 4 5 6 7 - - @endverbatim - */ -static const -UINT8 ixEthIEEE802_1QUserPriorityToTrafficClassMapping[IX_IEEE802_1Q_QOS_PRIORITY_COUNT][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] = - { - { 0, 0, 0, 0, 0, 0, 0, 0 }, /* 1 traffic class available */ - { 0, 0, 0, 0, 1, 1, 1, 1 }, /* 2 traffic classes available */ - { 0, 0, 0, 0, 1, 1, 2, 2 }, /* 3 traffic classes available */ - { 1, 0, 0, 1, 2, 2, 3, 3 }, /* 4 traffic classes available */ - { 1, 0, 0, 1, 2, 3, 4, 4 }, /* 5 traffic classes available */ - { 1, 0, 0, 2, 3, 4, 5, 5 }, /* 6 traffic classes available */ - { 1, 0, 0, 2, 3, 4, 5, 6 }, /* 7 traffic classes available */ - { 2, 0, 1, 3, 4, 5, 6, 7 } /* 8 traffic classes available */ - }; - -#endif /* IxEthDBQoS_H */ - -/** - *@} - */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthDB_p.h b/arch/arm/cpu/ixp/npe/include/IxEthDB_p.h deleted file mode 100644 index ccec7ea..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthDB_p.h +++ /dev/null @@ -1,710 +0,0 @@ -/** - * @file IxEthDB_p.h - * - * @brief Private MAC learning API - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#ifndef IxEthDB_p_H -#define IxEthDB_p_H - -#include -#include -#include -#include -#include - -#include "IxEthDBMessages_p.h" -#include "IxEthDBLog_p.h" - -#if (CPU==SIMSPARCSOLARIS) - -/* when running unit tests intLock() won't protect the event queue so we lock it manually */ -#define TEST_FIXTURE_LOCK_EVENT_QUEUE { ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); } -#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE { ixOsalMutexUnlock(&eventQueueLock); } - -#else - -#define TEST_FIXTURE_LOCK_EVENT_QUEUE /* nothing */ -#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE /* nothing */ - -#endif /* #if(CPU==SIMSPARCSOLARIS) */ - -#ifndef IX_UNIT_TEST - -#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER /* nothing */ -#define TEST_FIXTURE_MARK_OVERFLOW_EVENT /* nothing */ - -#else - -extern int dbAccessCounter; -extern int overflowEvent; - -#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER { dbAccessCounter++; } -#define TEST_FIXTURE_MARK_OVERFLOW_EVENT { overflowEvent = 1; } - -#endif - -/* code readability markers */ -#define __mempool__ /* memory pool marker */ -#define __lock__ /* hash write locking marker */ -#define __smartpointer__ /* smart pointer marker - warning: use only clone() when duplicating! */ -#define __alignment__ /* marker for data used only as alignment zones */ - -/* constants */ -#define IX_ETH_DB_NPE_TIMEOUT (100) /* NPE response timeout, in ms */ - -/** - * number of hash table buckets - * it should be at least 8x the predicted number of entries for performance - * each bucket needs 8 bytes - */ -#define NUM_BUCKETS (8192) - -/** - * number of hash table buckets to preload when incrementing bucket iterator - * = two cache lines - */ -#define IX_ETHDB_CACHE_LINE_AHEAD (2) - -#define IX_ETHDB_BUCKETPTR_AHEAD ((IX_ETHDB_CACHE_LINE_AHEAD * IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) - -#define IX_ETHDB_BUCKET_INDEX_MASK (((IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) - 1) - -/* locks */ -#define MAX_LOCKS (20) /**< maximum number of locks used simultaneously, do not tamper with */ - -/* learning tree constants */ -#define INITIAL_ELT_SIZE (8) /**< initial byte size of tree (empty unused root size) */ -#define MAX_ELT_SIZE (512) /**< maximum number of entries (includes unused root) */ -#define MAX_GW_SIZE (32) /**< maximum number of gateway entries (including unused root) */ -#define MAX_FW_SIZE (32) /**< maximum number of firewall entries (including unused root) */ -#define ELT_ENTRY_SIZE (8) /**< entry size, in bytes */ -#define ELT_ROOT_OFFSET (ELT_ENTRY_SIZE) /**< tree root offset, in bytes - node preceeding root is unused */ -#define FULL_ELT_BYTE_SIZE (MAX_ELT_SIZE * ELT_ENTRY_SIZE) /**< full size of tree, in bytes, including unused root */ -#define FULL_GW_BYTE_SIZE (MAX_GW_SIZE * ELT_ENTRY_SIZE) /**< full size of gateway list, in bytes, including unused root */ -#define FULL_FW_BYTE_SIZE (MAX_FW_SIZE * ELT_ENTRY_SIZE) /**< full size of firewall table, in bytes, including unused root */ - -/* maximum size of the VLAN table: - * 4096 bits (one per VLAN) - * 8 bits in one byte - * interleaved VLAN membership and VLAN TTI (*2) */ -#define FULL_VLAN_BYTE_SIZE (4096 / 8 * 2) - -/* upper 9 bits used as set index, lower 3 bits as byte index */ -#define VLAN_SET_OFFSET(vlanID) ((vlanID) >> 3) -#define VLAN_SET_MASK(vlanID) (0x7 - ((vlanID) & 0x7)) - -/* Update zone definitions */ -#define NPE_TREE_MEM_SIZE (4096) /* ((511 entries + 1 unused root) * 8 bytes/entry) */ - -/* check the above value, we rely on 4k */ -#if NPE_TREE_MEM_SIZE != 4096 - #error NPE_TREE_MEM_SIZE is not defined to 4096 bytes! -#endif - -/* Size Filtering limits (Jumbo frame filtering) */ -#define IX_ETHDB_MAX_FRAME_SIZE 65535 /* other ports than NPE ports */ -#define IX_ETHDB_MIN_FRAME_SIZE 1 /* other ports than NPE ports */ -#define IX_ETHDB_MAX_NPE_FRAME_SIZE 16320 /* NPE ports firmware limit */ -#define IX_ETHDB_MIN_NPE_FRAME_SIZE 1 /* NPE ports firmware limit */ -#define IX_ETHDB_DEFAULT_FRAME_SIZE 1522 - -/* memory management pool sizes */ - -/* - * Note: - * - * NODE_POOL_SIZE controls the maximum number of elements in the database at any one time. - * It should be large enough to cover all the search trees of all the ports simultaneously. - * - * MAC_POOL_SIZE should be higher than NODE_POOL_SIZE by at least the total number of MAC addresses - * possible to be held at any time in all the ports. - * - * TREE_POOL_SIZE should follow the same guideline as for MAC_POOL_SIZE. - * - * The database structure described here (2000/4000/4000) is enough for two NPEs holding at most 511 - * entries each plus one PCI NIC holding at most 900 entries. - */ - -#define NODE_POOL_SIZE (2000) /**< number of HashNode objects - also master number of elements in the database; each entry has 16 bytes */ -#define MAC_POOL_SIZE (4000) /**< number of MacDescriptor objects; each entry has 28 bytes */ -#define TREE_POOL_SIZE (4000) /**< number of MacTreeNode objects; each entry has 16 bytes */ - -/* retry policies */ -#define BUSY_RETRY_ENABLED (TRUE) /**< if set to TRUE the API will retry automatically calls returning BUSY */ -#define FOREVER_RETRY (TRUE) /**< if set to TRUE the API will retry forever BUSY calls */ -#define MAX_RETRIES (400) /**< upper retry limit - used only when FOREVER_RETRY is FALSE */ -#define BUSY_RETRY_YIELD (5) /**< ticks to yield for every failed retry */ - -/* event management */ -#define EVENT_QUEUE_SIZE (500) /**< size of the sink collecting events from the Message Handler FIFO */ -#define EVENT_PROCESSING_LIMIT (100) /**< batch processing control size (how many events are extracted from the queue at once) */ - -/* MAC descriptors */ -#define STATIC_ENTRY (TRUE) -#define DYNAMIC_ENTRY (FALSE) - -/* age reset on next maintenance - incrementing by 1 will reset to 0 */ -#define AGE_RESET (0xFFFFFFFF) - -/* dependency maps */ -#define EMPTY_DEPENDENCY_MAP (0) - -/* trees */ -#define RIGHT (1) -#define LEFT (-1) - -/* macros */ -#define IX_ETH_DB_CHECK_PORT_EXISTS(portID) \ -{ \ - if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ - { \ - return IX_ETH_DB_INVALID_PORT; \ - } \ -} - -#define IX_ETH_DB_CHECK_PORT_INITIALIZED(portID) \ -{ \ - if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ - { \ - return IX_ETH_DB_INVALID_PORT; \ - } \ - else \ - { \ - if (!ixEthDBPortInfo[portID].initialized) \ - { \ - return IX_ETH_DB_PORT_UNINITIALIZED; \ - } \ - } \ -} - -/* single NPE check */ -#define IX_ETH_DB_CHECK_SINGLE_NPE(portID) \ - if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS) \ - { \ - WARNING_LOG("EthDB: port ID %d is unavailable\n",(UINT32) portID); \ - \ - return IX_ETH_DB_INVALID_PORT; \ - } - -/* feature check */ -#define IX_ETH_DB_CHECK_FEATURE(portID, feature) \ - if ((ixEthDBPortInfo[portID].featureStatus & feature) == 0) \ - { \ - return IX_ETH_DB_FEATURE_UNAVAILABLE; \ - } - -/* busy retrying */ -#define BUSY_RETRY(functionCall) \ - { \ - UINT32 retries = 0; \ - IxEthDBStatus br_result; \ - \ - while ((br_result = functionCall) == IX_ETH_DB_BUSY \ - && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \ - \ - if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (br_result == IX_ETH_DB_FAIL)) \ - {\ - ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY failed at %s:%d\n", __FILE__, __LINE__); \ - }\ - } - -#define BUSY_RETRY_WITH_RESULT(functionCall, brwr_result) \ - { \ - UINT32 retries = 0; \ - \ - while ((brwr_result = functionCall) == IX_ETH_DB_BUSY \ - && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \ - \ - if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (brwr_result == IX_ETH_DB_FAIL)) \ - {\ - ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY_WITH_RESULT failed at %s:%d\n", __FILE__, __LINE__); \ - }\ - } - -/* iterators */ -#define IS_ITERATOR_VALID(iteratorPtr) ((iteratorPtr)->node != NULL) - -/* dependency port maps */ - -/* Warning: if port indexing starts from 1 replace (portID) with (portID - 1) in DEPENDENCY_MAP (and make sure IX_ETH_DB_NUMBER_OF_PORTS is big enough) */ - -/* gives an empty dependency map */ -#define SET_EMPTY_DEPENDENCY_MAP(map) { int i = 0; for (; i < 32 ; i++) map[i] = 0; } - -#define IS_EMPTY_DEPENDENCY_MAP(result, map) { int i = 0 ; result = TRUE; for (; i < 32 ; i++) if (map[i] != 0) { result = FALSE; break; }} - -/** - * gives a map consisting only of 'portID' - */ -#define SET_DEPENDENCY_MAP(map, portID) {SET_EMPTY_DEPENDENCY_MAP(map); map[portID >> 3] = 1 << (portID & 0x7);} - -/** - * gives a map resulting from joining map1 and map2 - */ -#define JOIN_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] | map2[i]; } - -/** - * gives the map resulting from joining portID and map - */ -#define JOIN_PORT_TO_MAP(map, portID) { map[portID >> 3] |= 1 << (portID & 0x7); } - -/** - * gives the map resulting from excluding portID from map - */ -#define EXCLUDE_PORT_FROM_MAP(map, portID) { map[portID >> 3] &= ~(1 << (portID & 0x7); } - -/** - * returns TRUE if map1 is a subset of map2 and FALSE otherwise - */ -#define IS_MAP_SUBSET(result, map1, map2) { int i = 0; result = TRUE; for (; i < 32 ; i++) if ((map1[i] | map2[i]) != map2[i]) result = FALSE; } - -/** - * returns TRUE is portID is part of map and FALSE otherwise - */ -#define IS_PORT_INCLUDED(portID, map) ((map[portID >> 3] & (1 << (portID & 0x7))) != 0) - -/** - * returns the difference between map1 and map2 (ports included in map1 and not included in map2) - */ -#define DIFF_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] ^ (map1[i] & map2[i]); } - -/** - * returns TRUE if the maps collide (have at least one port in common) and FALSE otherwise - */ -#define MAPS_COLLIDE(result, map1, map2) { int i = 0; result = FALSE; for (; i < 32 ; i++) if ((map1[i] & map2[i]) != 0) result = TRUE; } - -/* size (number of ports) of a dependency map */ -#define GET_MAP_SIZE(map, size) { int i = 0, b = 0; size = 0; for (; i < 32 ; i++) { char y = map[i]; for (; b < 8 && (y >>= 1); b++) size += (y & 1); }} - -/* copy map2 into map1 */ -#define COPY_DEPENDENCY_MAP(map1, map2) { memcpy (map1, map2, sizeof (map1)); } - -/* definition of a port map size/port number which cannot be reached (we support at most 32 ports) */ -#define MAX_PORT_SIZE (0xFF) -#define MAX_PORT_NUMBER (0xFF) - -#define IX_ETH_DB_CHECK_REFERENCE(ptr) { if ((ptr) == NULL) { return IX_ETH_DB_INVALID_ARG; } } -#define IX_ETH_DB_CHECK_MAP(portID, map) { if (!IS_PORT_INCLUDED(portID, map)) { return IX_ETH_DB_INVALID_ARG; } } - -/* event queue macros */ -#define EVENT_QUEUE_WRAP(offset) ((offset) >= EVENT_QUEUE_SIZE ? (offset) - EVENT_QUEUE_SIZE : (offset)) - -#define CAN_ENQUEUE(eventQueuePtr) ((eventQueuePtr)->length < EVENT_QUEUE_SIZE) - -#define QUEUE_HEAD(eventQueuePtr) (&(eventQueuePtr)->queue[EVENT_QUEUE_WRAP((eventQueuePtr)->base + (eventQueuePtr)->length)]) - -#define QUEUE_TAIL(eventQueuePtr) (&(eventQueuePtr)->queue[(eventQueuePtr)->base]) - -#define PUSH_UPDATE_QUEUE(eventQueuePtr) { (eventQueuePtr)->length++; } - -#define SHIFT_UPDATE_QUEUE(eventQueuePtr) \ - { \ - (eventQueuePtr)->base = EVENT_QUEUE_WRAP((eventQueuePtr)->base + 1); \ - (eventQueuePtr)->length--; \ - } - -#define RESET_QUEUE(eventQueuePtr) \ - { \ - (eventQueuePtr)->base = 0; \ - (eventQueuePtr)->length = 0; \ - } - -/* node stack macros - used to browse a tree without using a recursive function */ -#define NODE_STACK_INIT(stack) { (stack)->nodeCount = 0; } -#define NODE_STACK_PUSH(stack, node, offset) { (stack)->nodes[(stack)->nodeCount] = (node); (stack)->offsets[(stack)->nodeCount++] = (offset); } -#define NODE_STACK_POP(stack, node, offset) { (node) = (stack)->nodes[--(stack)->nodeCount]; offset = (stack)->offsets[(stack)->nodeCount]; } -#define NODE_STACK_NONEMPTY(stack) ((stack)->nodeCount != 0) - -#ifndef IX_NDEBUG -#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100) -#define LOG_NPE_MSG(msg) \ - do { \ - UINT32 npeMsgHistoryIndex = (npeMsgHistoryLen++) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; \ - npeMsgHistory[npeMsgHistoryIndex][0] = msg.data[0]; \ - npeMsgHistory[npeMsgHistoryIndex][1] = msg.data[1]; \ - } while (0); -#else -#define LOG_NPE_MSG() /* nothing */ -#endif - -/* ----------- Data -------------- */ - -/* typedefs */ - -typedef UINT32 (*HashFunction)(void *entity); -typedef BOOL (*MatchFunction)(void *reference, void *entry); -typedef void (*FreeFunction)(void *entry); - -/** - * basic component of a hash table - */ -typedef struct HashNode_t -{ - void *data; /**< specific data */ - struct HashNode_t *next; /**< used for bucket chaining */ - - __mempool__ struct HashNode_t *nextFree; /**< memory pool management */ - - __lock__ IxOsalFastMutex lock; /**< node lock */ -} HashNode; - -/** - * @brief hash table iterator definition - * - * an iterator is an object which can be used - * to browse a hash table - */ -typedef struct -{ - UINT32 bucketIndex; /**< index of the currently iterated bucket */ - HashNode *previousNode; /**< reference to the previously iterated node within the current bucket */ - HashNode *node; /**< reference to the currently iterated node */ -} HashIterator; - -/** - * definition of a MAC descriptor (a database record) - */ - -typedef enum -{ - IX_ETH_DB_WIFI_AP_TO_STA = 0x0, - IX_ETH_DB_WIFI_AP_TO_AP = 0x1 -} IxEthDBWiFiRecordType; - -typedef union -{ - struct - { - UINT32 age; - BOOL staticEntry; /**< TRUE if this address is static (doesn't age) */ - } filteringData; - - struct - { - UINT32 age; - BOOL staticEntry; - UINT32 ieee802_1qTag; - } filteringVlanData; - - struct - { - IxEthDBWiFiRecordType type; /**< AP_TO_AP (0x1) or AP_TO_STA (0x0) */ - UINT32 gwAddressIndex; /**< used only when linearizing the entries for NPE usage */ - UINT8 gwMacAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; - - __alignment__ UINT8 reserved2[2]; - } wifiData; -} IxEthDBRecordData; - -typedef struct MacDescriptor_t -{ - UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; - - __alignment__ UINT8 reserved1[2]; - - UINT32 portID; - IxEthDBRecordType type; - IxEthDBRecordData recordData; - - /* used for internal operations, such as NPE linearization */ - void *internal; - - /* custom user data */ - void *user; - - __mempool__ struct MacDescriptor_t *nextFree; /**< memory pool management */ - __smartpointer__ UINT32 refCount; /**< smart pointer reference counter */ -} MacDescriptor; - -/** - * hash table definition - */ -typedef struct -{ - HashNode *hashBuckets[NUM_BUCKETS]; - UINT32 numBuckets; - - __lock__ IxOsalFastMutex bucketLocks[NUM_BUCKETS]; - - HashFunction entryHashFunction; - MatchFunction *matchFunctions; - FreeFunction freeFunction; -} HashTable; - -typedef enum -{ - IX_ETH_DB_MAC_KEY = 1, - IX_ETH_DB_MAC_PORT_KEY = 2, - IX_ETH_DB_MAC_VLAN_KEY = 3, - IX_ETH_DB_MAX_KEY_INDEX = 3 -} IxEthDBSearchKeyType; - -typedef struct MacTreeNode_t -{ - __smartpointer__ MacDescriptor *descriptor; - struct MacTreeNode_t *left, *right; - - __mempool__ struct MacTreeNode_t *nextFree; -} MacTreeNode; - -typedef IxEthDBStatus (*IxEthDBPortUpdateHandler)(IxEthDBPortId portID, IxEthDBRecordType type); - -typedef void (*IxEthDBNoteWriteFn)(void *address, MacTreeNode *node); - -typedef struct -{ - BOOL updateEnabled; /**< TRUE if updates are enabled for port */ - BOOL userControlled; /**< TRUE if the user has manually used ixEthDBPortUpdateEnableSet */ - BOOL treeInitialized; /**< TRUE if the NPE has received an initial tree */ - IxEthDBPortUpdateHandler updateHandler; /**< port update handler routine */ - void *npeUpdateZone; /**< port update memory zone */ - void *npeGwUpdateZone; /**< port update memory zone for gateways */ - void *vlanUpdateZone; /**< port update memory zone for VLAN tables */ - MacTreeNode *searchTree; /**< internal search tree, in MacTreeNode representation */ - BOOL searchTreePendingWrite; /**< TRUE if searchTree holds a tree pending write to the port */ -} PortUpdateMethod; - -typedef struct -{ - IxEthDBPortId portID; /**< port ID */ - BOOL enabled; /**< TRUE if the port is enabled */ - BOOL agingEnabled; /**< TRUE if aging on this port is enabled */ - BOOL initialized; - IxEthDBPortMap dependencyPortMap; /**< dependency port map for this port */ - PortUpdateMethod updateMethod; /**< update method structure */ - BOOL macAddressUploaded; /**< TRUE if the MAC address was uploaded into the port */ - UINT32 maxRxFrameSize; /**< maximum Rx frame size for this port */ - UINT32 maxTxFrameSize; /**< maximum Rx frame size for this port */ - - UINT8 bbsid[6]; - __alignment__ UINT8 reserved[2]; - UINT32 frameControlDurationID; /**< Frame Control - Duration/ID WiFi control */ - - IxEthDBVlanTag vlanTag; /**< default VLAN tag for port */ - IxEthDBPriorityTable priorityTable; /**< QoS <=> internal priority mapping */ - IxEthDBVlanSet vlanMembership; - IxEthDBVlanSet transmitTaggingInfo; - IxEthDBFrameFilter frameFilter; - IxEthDBTaggingAction taggingAction; - - UINT32 npeFrameFilter; - UINT32 npeTaggingAction; - - IxEthDBFirewallMode firewallMode; - BOOL srcAddressFilterEnabled; - - BOOL stpBlocked; - - IxEthDBFeature featureCapability; - IxEthDBFeature featureStatus; - - UINT32 ixEthDBTrafficClassAQMAssignments[IX_IEEE802_1Q_QOS_PRIORITY_COUNT]; - - UINT32 ixEthDBTrafficClassCount; - - UINT32 ixEthDBTrafficClassAvailable; - - - - __lock__ IxOsalMutex npeAckLock; -} PortInfo; - -/* list of port information structures indexed on port Ids */ -extern IX_ETH_DB_PUBLIC PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS]; - -typedef enum -{ - IX_ETH_DB_ADD_FILTERING_RECORD = 0xFF0001, - IX_ETH_DB_REMOVE_FILTERING_RECORD = 0xFF0002 -} PortEventType; - -typedef struct -{ - UINT32 eventType; - IxEthDBPortId portID; - IxEthDBMacAddr macAddr; - BOOL staticEntry; -} PortEvent; - -typedef struct -{ - PortEvent queue[EVENT_QUEUE_SIZE]; - UINT32 base; - UINT32 length; -} PortEventQueue; - -typedef struct -{ - IxEthDBPortId portID; /**< originating port */ - MacDescriptor *macDescriptors[MAX_ELT_SIZE]; /**< addresses to be synced into db */ - UINT32 addressCount; /**< number of addresses */ -} TreeSyncInfo; - -typedef struct -{ - MacTreeNode *nodes[MAX_ELT_SIZE]; - UINT32 offsets[MAX_ELT_SIZE]; - UINT32 nodeCount; -} MacTreeNodeStack; - -/* Prototypes */ - -/* ----------- Memory management -------------- */ - -IX_ETH_DB_PUBLIC void ixEthDBInitMemoryPools(void); - -IX_ETH_DB_PUBLIC HashNode* ixEthDBAllocHashNode(void); -IX_ETH_DB_PUBLIC void ixEthDBFreeHashNode(HashNode *); - -IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBAllocMacDescriptor(void); -IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor); -IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacDescriptor(MacDescriptor *); - -IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBAllocMacTreeNode(void); -IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *); -IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacTreeNode(MacTreeNode *); - -IX_ETH_DB_PUBLIC void ixEthDBPoolFreeMacTreeNode(MacTreeNode *); -IX_ETH_DB_PUBLIC UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree); -IX_ETH_DB_PUBLIC int ixEthDBShowMemoryStatus(void); - -/* Hash Table */ -IX_ETH_DB_PUBLIC void ixEthDBInitHash(HashTable *hashTable, UINT32 numBuckets, HashFunction entryHashFunction, MatchFunction *matchFunctions, FreeFunction freeFunction); - -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference); -IX_ETH_DB_PUBLIC void ixEthDBReleaseHashNode(HashNode *node); - -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator); -IX_ETH_DB_PUBLIC void ixEthDBReleaseHashIterator(HashIterator *iterator); - -/* API Support */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); -IX_ETH_DB_PUBLIC void ixEthDBMaximumFrameSizeAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); - -/* DB Core functions */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInit(void); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger); -IX_ETH_DB_PUBLIC HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter); - -/* Learning support */ -IX_ETH_DB_PUBLIC UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2); -IX_ETH_DB_PUBLIC BOOL ixEthDBAddressMatch(void *reference, void *entry); -IX_ETH_DB_PUBLIC UINT32 ixEthDBEntryXORHash(void *macDescriptor); -IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyXORHash(void *macAddress); - -/* Port updates */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type); -IX_ETH_DB_PUBLIC void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts); -IX_ETH_DB_PUBLIC void ixEthDBNPEAccessRequest(IxEthDBPortId portID); -IX_ETH_DB_PUBLIC void ixEthDBUpdateLock(void); -IX_ETH_DB_PUBLIC void ixEthDBUpdateUnlock(void); -IX_ETH_DB_PUBLIC MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maximumEntries); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta); - -/* Init/unload */ -IX_ETH_DB_PUBLIC void ixEthDBPortSetAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBEventProcessorInit(void); -IX_ETH_DB_PUBLIC void ixEthDBPortInit(IxEthDBPortId portID); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID); -IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasInit(void); -IX_ETH_DB_PUBLIC UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions); -IX_ETH_DB_PUBLIC UINT32 ixEthDBRecordSerializeMethodsRegister(void); -IX_ETH_DB_PUBLIC UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray); -IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasUnload(void); -IX_ETH_DB_PUBLIC void ixEthDBFeatureCapabilityScan(void); -IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType); - -/* Event processing */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDefaultEventCallbackEnable(IxEthDBPortId portID, BOOL enable); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID); -IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); - -/* NPE adaptor */ -IX_ETH_DB_PUBLIC void ixEthDBGetMacDatabaseCbk(IxNpeMhNpeId npeID, IxNpeMhMessage msg); -IX_ETH_DB_PUBLIC void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg); -IX_ETH_DB_PUBLIC void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize); -IX_ETH_DB_PUBLIC void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *blocks, UINT32 *startIndex); -IX_ETH_DB_PUBLIC void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node); - -/* Other public API functions */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate); - -/* Maximum Tx/Rx public functions */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize); -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize); - -/* VLAN-related */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet); - -/* Record search */ -IX_ETH_DB_PUBLIC BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry); -IX_ETH_DB_PUBLIC BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry); -IX_ETH_DB_PUBLIC BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry); -IX_ETH_DB_PUBLIC BOOL ixEthDBNullMatch(void *reference, void *entry); -IX_ETH_DB_PUBLIC HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter); -IX_ETH_DB_PUBLIC HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter); - -/* Utilities */ -IX_ETH_DB_PUBLIC const char* mac2string(const unsigned char *mac); -IX_ETH_DB_PUBLIC void showHashInfo(void); -IX_ETH_DB_PUBLIC int ixEthDBAnalyzeHash(void); -IX_ETH_DB_PUBLIC const char* errorString(IxEthDBStatus error); -IX_ETH_DB_PUBLIC int numHashElements(void); -IX_ETH_DB_PUBLIC void zapHashtable(void); -IX_ETH_DB_PUBLIC BOOL ixEthDBCheckSingleBitValue(UINT32 value); - -/* Single Eth NPE Check */ -IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portId); - -#endif /* IxEthDB_p_H */ - diff --git a/arch/arm/cpu/ixp/npe/include/IxEthMii.h b/arch/arm/cpu/ixp/npe/include/IxEthMii.h deleted file mode 100644 index 397253a..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthMii.h +++ /dev/null @@ -1,270 +0,0 @@ -/** - * @file IxEthMii.h - * - * @brief this file contains the public API of @ref IxEthMii component - * - * Design notes : - * The main intent of this API is to inplement MII high level fonctionalitoes - * to support the codelets provided with the IXP400 software releases. It - * superceedes previous interfaces provided with @ref IxEThAcc component. - * - * This API has been tested with the PHYs provided with the - * IXP400 development platforms. It may not work for specific Ethernet PHYs - * used on specific boards. - * - * This source code detects and interface the LXT972, LXT973 and KS6995 - * Ethernet PHYs. - * - * This source code should be considered as an example which may need - * to be adapted for different hardware implementations. - * - * It is strongly recommended to use public domain and GPL utilities - * like libmii, mii-diag for MII interface support. - * - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#ifndef IxEthMii_H -#define IxEthMii_H - -#include - -/** - * @defgroup IxEthMii IXP400 Ethernet Phy Access (IxEthMii) API - * - * @brief ethMii is a library that does provides access to the - * Ethernet PHYs - * - *@{ - */ - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount) - * - * @brief Scan the MDIO bus for PHYs - * This function scans PHY addresses 0 through 31, and sets phyPresent[n] to - * TRUE if a phy is discovered at address n. - * - * - Reentrant - no - * - ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyPresent BOOL [in] - boolean array of IXP425_ETH_ACC_MII_MAX_ADDR entries - * @param maxPhyCount UINT32 [in] - number of PHYs to search for (the scan will stop when - * the indicated number of PHYs is found). - * - * @return IX_STATUS - * - IX_ETH_ACC_SUCCESS - * - IX_ETH_ACC_FAIL : invalid arguments. - * - *
- */ -PUBLIC IX_STATUS ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount); - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyConfig(UINT32 phyAddr, - BOOL speed100, - BOOL fullDuplex, - BOOL autonegotiate) - * - * - * @brief Configure a PHY - * Configure a PHY's speed, duplex and autonegotiation status - * - * - Reentrant - no - * - ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT32 [in] - * @param speed100 BOOL [in] - set to TRUE for 100Mbit/s operation, FALSE for 10Mbit/s - * @param fullDuplex BOOL [in] - set to TRUE for Full Duplex, FALSE for Half Duplex - * @param autonegotiate BOOL [in] - set to TRUE to enable autonegotiation - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - * - *
- */ -PUBLIC IX_STATUS ixEthMiiPhyConfig(UINT32 phyAddr, - BOOL speed100, - BOOL fullDuplex, - BOOL autonegotiate); - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyLoopbackEnable(UINT32 phyAddr) - * - * - * @brief Enable PHY Loopback in a specific Eth MII port - * - * @note When PHY Loopback is enabled, frames sent out to the PHY from the - * IXP400 will be looped back to the IXP400. They will not be transmitted out - * on the wire. - * - * - Reentrant - no - * - ISR Callable - no - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - *
- */ -PUBLIC IX_STATUS -ixEthMiiPhyLoopbackEnable (UINT32 phyAddr); - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyLoopbackDisable(UINT32 phyAddr) - * - * - * @brief Disable PHY Loopback in a specific Eth MII port - * - * - Reentrant - no - * - ISR Callable - no - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - *
- */ -PUBLIC IX_STATUS -ixEthMiiPhyLoopbackDisable (UINT32 phyAddr); - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyReset(UINT32 phyAddr) - * - * @brief Reset a PHY - * Reset a PHY - * - * - Reentrant - no - * - ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - * - *
- */ -PUBLIC IX_STATUS ixEthMiiPhyReset(UINT32 phyAddr); - - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiLinkStatus(UINT32 phyAddr, - BOOL *linkUp, - BOOL *speed100, - BOOL *fullDuplex, - BOOL *autoneg) - * - * @brief Retrieve the current status of a PHY - * Retrieve the link, speed, duplex and autonegotiation status of a PHY - * - * - Reentrant - no - * - ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * @param linkUp BOOL [out] - set to TRUE if the link is up - * @param speed100 BOOL [out] - set to TRUE indicates 100Mbit/s, FALSE indicates 10Mbit/s - * @param fullDuplex BOOL [out] - set to TRUE indicates Full Duplex, FALSE indicates Half Duplex - * @param autoneg BOOL [out] - set to TRUE indicates autonegotiation is enabled, FALSE indicates autonegotiation is disabled - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - * - *
- */ -PUBLIC IX_STATUS ixEthMiiLinkStatus(UINT32 phyAddr, - BOOL *linkUp, - BOOL *speed100, - BOOL *fullDuplex, - BOOL *autoneg); - -/** - * @ingroup IxEthMii - * - * @fn ixEthMiiPhyShow (UINT32 phyAddr) - * - * - * @brief Display information on a specified PHY - * Display link status, speed, duplex and Auto Negotiation status - * - * - Reentrant - no - * - ISR Callable - no - * - * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. - * - * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) - * - * @return IX_STATUS - * - IX_SUCCESS - * - IX_FAIL : invalid arguments. - * - *
- */ -PUBLIC IX_STATUS ixEthMiiPhyShow (UINT32 phyAddr); - -#endif /* ndef IxEthMii_H */ -/** - *@} - */ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthMii_p.h b/arch/arm/cpu/ixp/npe/include/IxEthMii_p.h deleted file mode 100644 index 104b65c..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthMii_p.h +++ /dev/null @@ -1,185 +0,0 @@ -/** - * @file IxEthMii_p.h - * - * @author Intel Corporation - * @date - * - * @brief MII Header file - * - * Design Notes: - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -#ifndef IxEthMii_p_H -#define IxEthMii_p_H - - -/* MII definitions - these have been verified against the LXT971 and - LXT972 PHYs*/ - -#define IX_ETH_MII_MAX_REG_NUM 0x20 /* max number of registers */ - -#define IX_ETH_MII_CTRL_REG 0x0 /* Control Register */ -#define IX_ETH_MII_STAT_REG 0x1 /* Status Register */ -#define IX_ETH_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */ -#define IX_ETH_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */ -#define IX_ETH_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */ - /* Advertisement Register */ -#define IX_ETH_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */ - /* partner ability Register */ -#define IX_ETH_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */ - /* Expansion Register */ -#define IX_ETH_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */ - /* next-page transmit Register */ - -#define IX_ETH_MII_STAT2_REG 0x11 /* Status Register 2*/ - - -/* MII control register bit */ - -#define IX_ETH_MII_CR_COLL_TEST 0x0080 /* collision test */ -#define IX_ETH_MII_CR_FDX 0x0100 /* FDX =1, half duplex =0 */ -#define IX_ETH_MII_CR_RESTART 0x0200 /* restart auto negotiation */ -#define IX_ETH_MII_CR_ISOLATE 0x0400 /* isolate PHY from MII */ -#define IX_ETH_MII_CR_POWER_DOWN 0x0800 /* power down */ -#define IX_ETH_MII_CR_AUTO_EN 0x1000 /* auto-negotiation enable */ -#define IX_ETH_MII_CR_100 0x2000 /* 0 = 10mb, 1 = 100mb */ -#define IX_ETH_MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ -#define IX_ETH_MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ -#define IX_ETH_MII_CR_NORM_EN 0x0000 /* just enable the PHY */ -#define IX_ETH_MII_CR_DEF_0_MASK 0xca7f /* they must return zero */ -#define IX_ETH_MII_CR_RES_MASK 0x007f /* reserved bits, return zero */ - -/* MII Status register bit definitions */ - -#define IX_ETH_MII_SR_LINK_STATUS 0x0004 /* link Status -- 1 = link */ -#define IX_ETH_MII_SR_AUTO_SEL 0x0008 /* auto speed select capable */ -#define IX_ETH_MII_SR_REMOTE_FAULT 0x0010 /* Remote fault detect */ -#define IX_ETH_MII_SR_AUTO_NEG 0x0020 /* auto negotiation complete */ -#define IX_ETH_MII_SR_10T_HALF_DPX 0x0800 /* 10BaseT HD capable */ -#define IX_ETH_MII_SR_10T_FULL_DPX 0x1000 /* 10BaseT FD capable */ -#define IX_ETH_MII_SR_TX_HALF_DPX 0x2000 /* TX HD capable */ -#define IX_ETH_MII_SR_TX_FULL_DPX 0x4000 /* TX FD capable */ -#define IX_ETH_MII_SR_T4 0x8000 /* T4 capable */ -#define IX_ETH_MII_SR_ABIL_MASK 0xff80 /* abilities mask */ -#define IX_ETH_MII_SR_EXT_CAP 0x0001 /* extended capabilities */ - - -/* LXT971/2 Status 2 register bit definitions */ -#define IX_ETH_MII_SR2_100 0x4000 -#define IX_ETH_MII_SR2_TX 0x2000 -#define IX_ETH_MII_SR2_RX 0x1000 -#define IX_ETH_MII_SR2_COL 0x0800 -#define IX_ETH_MII_SR2_LINK 0x0400 -#define IX_ETH_MII_SR2_FD 0x0200 -#define IX_ETH_MII_SR2_AUTO 0x0100 -#define IX_ETH_MII_SR2_AUTO_CMPLT 0x0080 -#define IX_ETH_MII_SR2_POLARITY 0x0020 -#define IX_ETH_MII_SR2_PAUSE 0x0010 -#define IX_ETH_MII_SR2_ERROR 0x0008 - -/* MII Link Code word bit definitions */ - -#define IX_ETH_MII_BP_FAULT 0x2000 /* remote fault */ -#define IX_ETH_MII_BP_ACK 0x4000 /* acknowledge */ -#define IX_ETH_MII_BP_NP 0x8000 /* nexp page is supported */ - -/* MII Next Page bit definitions */ - -#define IX_ETH_MII_NP_TOGGLE 0x0800 /* toggle bit */ -#define IX_ETH_MII_NP_ACK2 0x1000 /* acknowledge two */ -#define IX_ETH_MII_NP_MSG 0x2000 /* message page */ -#define IX_ETH_MII_NP_ACK1 0x4000 /* acknowledge one */ -#define IX_ETH_MII_NP_NP 0x8000 /* nexp page will follow */ - -/* MII Expansion Register bit definitions */ - -#define IX_ETH_MII_EXP_FAULT 0x0010 /* parallel detection fault */ -#define IX_ETH_MII_EXP_PRTN_NP 0x0008 /* link partner next-page able */ -#define IX_ETH_MII_EXP_LOC_NP 0x0004 /* local PHY next-page able */ -#define IX_ETH_MII_EXP_PR 0x0002 /* full page received */ -#define IX_ETH_MII_EXP_PRT_AN 0x0001 /* link partner auto neg able */ - -/* technology ability field bit definitions */ - -#define IX_ETH_MII_TECH_10BASE_T 0x0020 /* 10Base-T */ -#define IX_ETH_MII_TECH_10BASE_FD 0x0040 /* 10Base-T Full Duplex */ -#define IX_ETH_MII_TECH_100BASE_TX 0x0080 /* 100Base-TX */ -#define IX_ETH_MII_TECH_100BASE_TX_FD 0x0100 /* 100Base-TX Full Duplex */ - -#define IX_ETH_MII_TECH_100BASE_T4 0x0200 /* 100Base-T4 */ -#define IX_ETH_MII_ADS_TECH_MASK 0x1fe0 /* technology abilities mask */ -#define IX_ETH_MII_TECH_MASK IX_ETH_MII_ADS_TECH_MASK -#define IX_ETH_MII_ADS_SEL_MASK 0x001f /* selector field mask */ - -#define IX_ETH_MII_AN_FAIL 0x10 /* auto-negotiation fail */ -#define IX_ETH_MII_STAT_FAIL 0x20 /* errors in the status register */ -#define IX_ETH_MII_PHY_NO_ABLE 0x40 /* the PHY lacks some abilities */ - -/* Definitions for MII access routines*/ - -#define IX_ETH_MII_GO BIT(31) -#define IX_ETH_MII_WRITE BIT(26) -#define IX_ETH_MII_TIMEOUT_10TH_SECS (5) -#define IX_ETH_MII_10TH_SEC_IN_MILLIS (100) -#define IX_ETH_MII_READ_FAIL BIT(31) - -/* When we reset the PHY we delay for 2 seconds to allow the reset to - complete*/ -#define IX_ETH_MII_RESET_DELAY_MS (2000) -#define IX_ETH_MII_RESET_POLL_MS (50) - -#define IX_ETH_MII_REG_SHL 16 -#define IX_ETH_MII_ADDR_SHL 21 - -/* supported PHYs */ -#define IX_ETH_MII_LXT971_PHY_ID 0x001378E0 -#define IX_ETH_MII_LXT972_PHY_ID 0x001378E2 -#define IX_ETH_MII_LXT973_PHY_ID 0x00137A10 -#define IX_ETH_MII_LXT973A3_PHY_ID 0x00137A11 -#define IX_ETH_MII_KS8995_PHY_ID 0x00221450 -#define IX_ETH_MII_LXT9785_PHY_ID 0x001378FF - - -#define IX_ETH_MII_INVALID_PHY_ID 0x00000000 -#define IX_ETH_MII_UNKNOWN_PHY_ID 0xffffffff - -#endif /*IxEthAccMii_p_H*/ diff --git a/arch/arm/cpu/ixp/npe/include/IxEthNpe.h b/arch/arm/cpu/ixp/npe/include/IxEthNpe.h deleted file mode 100644 index 21bdedc..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxEthNpe.h +++ /dev/null @@ -1,695 +0,0 @@ -#ifndef __doxygen_HIDE /* This file is not part of the API */ - -/** - * @file IxEthNpe.h - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/** - * @defgroup IxEthNpe IXP400 Ethernet NPE (IxEthNpe) API - * - * @brief Contains the API for Ethernet NPE. - * - * All messages given to NPE, get back an acknowledgment. The acknowledgment - * is identical to the message sent to the NPE (except for NPE_GETSTATUS message). - * - * @{ - */ - - -/*-------------------------------------------------------------------------- - * APB Message IDs - XScale->NPE - *------------------------------------------------------------------------*/ - -/** - * @def IX_ETHNPE_NPE_GETSTATUS - * - * @brief Request from the XScale client for the NPE to return the firmware - * version of the currently executing image. - * - * Acknowledgment message id is same as the request message id. - * NPE returns the firmware version ID to XScale. - */ -#define IX_ETHNPE_NPE_GETSTATUS 0x00 - -/** - * @def IX_ETHNPE_EDB_SETPORTADDRESS - * - * @brief Request from the XScale client for the NPE to set the Ethernet - * port's port ID and MAC address. - */ -#define IX_ETHNPE_EDB_SETPORTADDRESS 0x01 - -/** - * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE - * - * @brief Request from XScale client to the NPE requesting upload of - * Ethernet Filtering Database or Header Conversion Database from NPE's - * data memory to XScale accessible SDRAM. - */ -#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE 0x02 - -/** - * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE - * - * @brief Request from XScale client to the NPE requesting download of - * Ethernet Filtering Database or Header Conversion Database from SDRAM - * to the NPE's datamemory. - */ -#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE 0x03 - -/** - * @def IX_ETHNPE_GETSTATS - * - * @brief Request from the XScale client for the current MAC port statistics - * data to be written to the (empty) statistics structure and the specified - * location in externa memory. - */ -#define IX_ETHNPE_GETSTATS 0x04 - -/** - * @def IX_ETHNPE_RESETSTATS - * - * @brief Request from the XScale client to the NPE to reset all of its internal - * MAC port statistics state variables. - * - * As a side effect, this message entails an implicit request that the NPE - * write the current MAC port statistics into the MAC statistics structure - * at the specified location in external memory. - */ -#define IX_ETHNPE_RESETSTATS 0x05 - -/** - * @def IX_ETHNPE_SETMAXFRAMELENGTHS - * - * @brief Request from the XScale client to the NPE to configure maximum framelengths - * and block sizes in receive and transmit direction. - */ -#define IX_ETHNPE_SETMAXFRAMELENGTHS 0x06 - -/** - * @def IX_ETHNPE_VLAN_SETRXTAGMODE - * - * @brief Request from the XScale client to the NPE to configure VLAN frame type - * filtering and VLAN the tagging mode for the receiver. - */ -#define IX_ETHNPE_VLAN_SETRXTAGMODE 0x07 - -/** - * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID - * - * @brief Request from the XScale client to the NPE to set receiver's default - * VLAN tag (PVID)and internal traffic class. - */ -#define IX_ETHNPE_VLAN_SETDEFAULTRXVID 0x08 - -/** - * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY - * - * @brief Request from the XScale client to the NPE to configure VLAN Port - * membership and Tx tagging for 8 consecutive VLANID's. - */ -#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY 0x09 - -/** - * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE - * - * @brief Request from the XScale client to the NPE to configure VLAN Port - * membership and Tx tagging for a range of VLANID's. - */ -#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE 0x0A - -/** - * @def IX_ETHNPE_VLAN_SETRXQOSENTRY - * - * @brief Request from the XScale client to the NPE to map a user priority - * to QoS class and an AQM queue number. - */ -#define IX_ETHNPE_VLAN_SETRXQOSENTRY 0x0B - -/** - * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE - * - * @brief Request from the XScale client to the NPE to enable or disable - * portID extraction from VLAN-tagged frames for the specified port. - */ -#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE 0x0C - -/** - * @def IX_ETHNPE_STP_SETBLOCKINGSTATE - * - * @brief Request from the XScale client to the NPE to block or unblock - * forwarding for spanning tree BPDUs. - */ -#define IX_ETHNPE_STP_SETBLOCKINGSTATE 0x0D - -/** - * @def IX_ETHNPE_FW_SETFIREWALLMODE - * - * @brief Request from the XScale client to the NPE to configure firewall - * services modes of operation and/or download Ethernet Firewall Database from - * SDRAM to NPE. - */ -#define IX_ETHNPE_FW_SETFIREWALLMODE 0x0E - -/** - * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID - * - * @brief Request from the XScale client to the NPE to set global frame control - * and duration/ID field for the 802.3 to 802.11 protocol header conversion - * service. - */ -#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID 0x0F - -/** - * @def IX_ETHNPE_PC_SETBBSID - * - * @brief Request from the XScale client to the NPE to set global BBSID field - * value for the 802.3 to 802.11 protocol header conversion service. - */ -#define IX_ETHNPE_PC_SETBBSID 0x10 - -/** - * @def IX_ETHNPE_PC_SETAPMACTABLE - * - * @brief Request from the XScale client to the NPE to update a block/section/ - * range of the AP MAC Address Table. - */ -#define IX_ETHNPE_PC_SETAPMACTABLE 0x11 - -/** - * @def IX_ETHNPE_SETLOOPBACK_MODE - * - * @brief Turn on or off the NPE frame loopback. - */ -#define IX_ETHNPE_SETLOOPBACK_MODE (0x12) - -/*-------------------------------------------------------------------------- - * APB Message IDs - NPE->XScale - *------------------------------------------------------------------------*/ - -/** - * @def IX_ETHNPE_NPE_GETSTATUS_ACK - * - * @brief Acknowledgment to IX_ETHNPE_NPE_GETSTATUS message. NPE firmware version - * id is returned in the message. - */ -#define IX_ETHNPE_NPE_GETSTATUS_ACK 0x00 - -/** - * @def IX_ETHNPE_EDB_SETPORTADDRESS_ACK - * - * @brief Acknowledgment to IX_ETHNPE_EDB_SETPORTADDRESS message. - */ -#define IX_ETHNPE_EDB_SETPORTADDRESS_ACK 0x01 - -/** - * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_EDB_GETMACADDRESSDATABASE message - */ -#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK 0x02 - -/** - * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_EDB_SETMACADDRESSSDATABASE message. - */ -#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK 0x03 - -/** - * @def IX_ETHNPE_GETSTATS_ACK - * - * @brief Acknowledgment to IX_ETHNPE_GETSTATS message. - */ -#define IX_ETHNPE_GETSTATS_ACK 0x04 - -/** - * @def IX_ETHNPE_RESETSTATS_ACK - * - * @brief Acknowledgment to IX_ETHNPE_RESETSTATS message. - */ -#define IX_ETHNPE_RESETSTATS_ACK 0x05 - -/** - * @def IX_ETHNPE_SETMAXFRAMELENGTHS_ACK - * - * @brief Acknowledgment to IX_ETHNPE_SETMAXFRAMELENGTHS message. - */ -#define IX_ETHNPE_SETMAXFRAMELENGTHS_ACK 0x06 - -/** - * @def IX_ETHNPE_VLAN_SETRXTAGMODE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXTAGMODE message. - */ -#define IX_ETHNPE_VLAN_SETRXTAGMODE_ACK 0x07 - -/** - * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETDEFAULTRXVID message. - */ -#define IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK 0x08 - -/** - * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY message. - */ -#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK 0x09 - -/** - * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE message. - */ -#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK 0x0A - -/** - * @def IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXQOSENTRY message. - */ -#define IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK 0x0B - -/** - * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE message. - */ -#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK 0x0C - -/** - * @def IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_STP_SETBLOCKINGSTATE message. - */ -#define IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK 0x0D - -/** - * @def IX_ETHNPE_FW_SETFIREWALLMODE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_FW_SETFIREWALLMODE message. - */ -#define IX_ETHNPE_FW_SETFIREWALLMODE_ACK 0x0E - -/** - * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK - * - * @brief Acknowledgment to IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID message. - */ -#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK 0x0F - -/** - * @def IX_ETHNPE_PC_SETBBSID_ACK - * - * @brief Acknowledgment to IX_ETHNPE_PC_SETBBSID message. - */ -#define IX_ETHNPE_PC_SETBBSID_ACK 0x10 - -/** - * @def IX_ETHNPE_PC_SETAPMACTABLE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_PC_SETAPMACTABLE message. - */ -#define IX_ETHNPE_PC_SETAPMACTABLE_ACK 0x11 - -/** - * @def IX_ETHNPE_SETLOOPBACK_MODE_ACK - * - * @brief Acknowledgment to IX_ETHNPE_SETLOOPBACK_MODE message. - */ -#define IX_ETHNPE_SETLOOPBACK_MODE_ACK (0x12) - -/*-------------------------------------------------------------------------- - * Queue Manager Queue entry bit field boundary definitions - *------------------------------------------------------------------------*/ - -/** - * @def MASK(hi,lo) - * - * @brief Macro for mask - */ -#define MASK(hi,lo) (((1 << (1 + ((hi) - (lo)))) - 1) << (lo)) - -/** - * @def BITS(x,hi,lo) - * - * @brief Macro for bits - */ -#define BITS(x,hi,lo) (((x) & MASK(hi,lo)) >> (lo)) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK - * - * @brief QMgr Queue LENGTH field mask - */ -#define IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK 0x3fff - -/** - * @def IX_ETHNPE_QM_Q_FIELD_FLAG_R - * - * @brief QMgr Queue FLAG field right boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_FLAG_R 20 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_FLAG_MASK - * - * @brief QMgr Queue FLAG field mask - * - * Multicast bit : BIT(4) - * Broadcast bit : BIT(5) - * IP bit : BIT(6) (linux only) - * - */ -#ifdef __vxworks -#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x30 -#else -#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x70 -#endif - - -/** - * @def IX_ETHNPE_QM_Q_FIELD_NPEID_L - * - * @brief QMgr Queue NPE ID field left boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_NPEID_L 1 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_NPEID_R - * - * @brief QMgr Queue NPE ID field right boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_NPEID_R 0 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_L - * - * @brief QMgr Queue Priority field left boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_PRIOR_L 2 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_R - * - * @brief QMgr Queue Priority field right boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_PRIOR_R 0 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_ADDR_L - * - * @brief QMgr Queue Address field left boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_ADDR_L 31 - -/** - * @def IX_ETHNPE_QM_Q_FIELD_ADDR_R - * - * @brief QMgr Queue Address field right boundary - */ -#define IX_ETHNPE_QM_Q_FIELD_ADDR_R 5 - -/*-------------------------------------------------------------------------- - * Queue Manager Queue entry bit field masks - *------------------------------------------------------------------------*/ - -/** - * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK - * - * @brief Macro to mask the Address field of the FreeEnet Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ - IX_ETHNPE_QM_Q_FIELD_ADDR_R) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_NPEID_MASK - * - * @brief Macro to mask the NPE ID field of the RxEnet Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_RXENET_NPEID_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ - IX_ETHNPE_QM_Q_FIELD_NPEID_R) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_ADDR_MASK - * - * @brief Macro to mask the Mbuf Address field of the RxEnet Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_RXENET_ADDR_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ - IX_ETHNPE_QM_Q_FIELD_ADDR_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK - * - * @brief Macro to mask the Priority field of the TxEnet Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \ - IX_ETHNPE_QM_Q_FIELD_PRIOR_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENET_ADDR_MASK - * - * @brief Macro to mask the Mbuf Address field of the TxEnet Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_TXENET_ADDR_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ - IX_ETHNPE_QM_Q_FIELD_ADDR_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK - * - * @brief Macro to mask the NPE ID field of the TxEnetDone Queue Manager Entry - */ -#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ - IX_ETHNPE_QM_Q_FIELD_NPEID_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK - * - * @brief Macro to mask the Mbuf Address field of the TxEnetDone Queue Manager - * Entry - */ -#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK \ - MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ - IX_ETHNPE_QM_Q_FIELD_ADDR_R) - -/*-------------------------------------------------------------------------- - * Queue Manager Queue entry bit field value extraction macros - *------------------------------------------------------------------------*/ - -/** - * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x) - * - * @brief Extraction macro for Address field of FreeNet Queue Manager Entry - * - * Pointer to an mbuf buffer descriptor - */ -#define IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x) \ - ((x) & IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x) - * - * @brief Extraction macro for NPE ID field of RxEnet Queue Manager Entry - * - * Set to 0 for entries originating from the Eth0 NPE; - * Set to 1 for entries originating from the Eth1 NPE. - */ -#define IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x) \ - BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ - IX_ETHNPE_QM_Q_FIELD_NPEID_R) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x) - * - * @brief Extraction macro for Port ID field of RxEnet Queue Manager Entry - * - * 0-5: Assignable (by the XScale client) to any of the physical ports. - * 6: It is reserved - * 7: Indication that the NPE did not find the associated frame's destination MAC address within - * its internal filtering database. - */ -#define IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x) \ - BITS (x, IX_ETHNPE_QM_Q_FIELD_PORTID_L, \ - IX_ETHNPE_QM_Q_Field_PortID_R) - -/** - * @def IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x) - * - * @brief Extraction macro for Address field of RxEnet Queue Manager Entry - * - * Pointer to an mbuf buffer descriptor - */ -#define IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x) \ - ((x) & IX_ETHNPE_QM_Q_RXENET_ADDR_MASK) - -/** - * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x) - * - * @brief Extraction macro for Priority field of TxEnet Queue Manager Entry - * - * Priority of the packet (as described in IEEE 802.1D). This field is - * cleared upon return from the Ethernet NPE to the TxEnetDone queue. - */ -#define IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x) \ - BITS (x, IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \ - IX_ETHNPE_QM_Q_FIELD_PRIOR_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x) - * - * @brief Extraction macro for Address field of Queue Manager TxEnet Queue - * Manager Entry - * - * Pointer to an mbuf buffer descriptor - */ -#define IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x) \ - ((x) & IX_ETHNPE_QM_Q_TXENET_ADDR_MASK) - -/** - * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x) - * - * @brief Extraction macro for NPE ID field of TxEnetDone Queue Manager Entry - * - * Set to 0 for entries originating from the Eth0 NPE; set to 1 for en-tries - * originating from the Eth1 NPE. - */ -#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x) \ - BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ - IX_ETHNPE_QM_Q_FIELD_NPEID_R) - -/** - * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x) - * - * @brief Extraction macro for Address field of TxEnetDone Queue Manager Entry - * - * Pointer to an mbuf buffer descriptor - */ -#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x) \ - ((x) & IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK) - - -/*-------------------------------------------------------------------------- - * NPE limits - *------------------------------------------------------------------------*/ - -/** - * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN - * - * @brief Macro to check the minimum length of a rx free buffer - */ -#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN (64) - -/** - * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK - * - * @brief Mask to apply to the mbuf length before submitting it to the NPE - * (the NPE handles only rx free mbufs which are multiple of 64) - * - * @sa IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK - */ -#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK (~63) - -/** - * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size) - * - * @brief Round up to get the size necessary to receive without chaining - * the frames which are (size) bytes (the NPE operates by multiple of 64) - * e.g. To receive 1514 bytes frames, the size of the buffers in replenish - * has to be at least (1514+63)&(~63) = 1536 bytes. - * - */ -#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size) (((size) + 63) & ~63) - -/** - * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size) - * - * @brief Round down to apply to the mbuf length before submitting - * it to the NPE. (the NPE operates by multiple of 64) - * - */ -#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size) ((size) & ~63) - -/** - * @def IX_ETHNPE_ACC_FRAME_LENGTH_MAX - * - * @brief maximum mbuf length supported by the NPE - * - * @sa IX_ETHNPE_ACC_FRAME_LENGTH_MAX - */ -#define IX_ETHNPE_ACC_FRAME_LENGTH_MAX (16320) - -/** - * @def IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT - * - * @brief default mbuf length supported by the NPE - * - * @sa IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT - */ -#define IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT (1522) - -/** - * @def IX_ETHNPE_ACC_LENGTH_OFFSET - * - * @brief Offset of the cluster length field in the word shared with the NPEs - */ -#define IX_ETHNPE_ACC_LENGTH_OFFSET 16 - -/** - * @def IX_ETHNPE_ACC_PKTLENGTH_MASK - * - * @brief Mask of the cluster length field in the word shared with the NPEs - */ -#define IX_ETHNPE_ACC_PKTLENGTH_MASK 0x3fff - - -/** - *@} - */ - -#endif /* __doxygen_HIDE */ diff --git a/arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h b/arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h deleted file mode 100644 index dabc38e..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxFeatureCtrl.h +++ /dev/null @@ -1,742 +0,0 @@ -/** - * @file IxFeatureCtrl.h - * - * @date 30-Jan-2003 - - * @brief This file contains the public API of the IXP400 Feature Control - * component. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ -/* ------------------------------------------------------ - Doxygen group definitions - ------------------------------------------------------ */ -/** - * @defgroup IxFeatureCtrlAPI IXP400 Feature Control (IxFeatureCtrl) API - * - * @brief The Public API for the IXP400 Feature Control. - * - * @{ - */ - -#ifndef IXFEATURECTRL_H -#define IXFEATURECTRL_H - -/* - * User defined include files - */ -#include "IxOsal.h" - -/* - * #defines and macros - */ - -/************************************************************* - * The following are IxFeatureCtrlComponentCheck return values. - ************************************************************/ - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_COMPONENT_DISABLED - * - * @brief Hardware Component is disabled/unavailable. - * Return status by ixFeatureCtrlComponentCheck() - */ -#define IX_FEATURE_CTRL_COMPONENT_DISABLED 0 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_COMPONENT_ENABLED - * - * @brief Hardware Component is available. - * Return status by ixFeatureCtrlComponentCheck() - */ -#define IX_FEATURE_CTRL_COMPONENT_ENABLED 1 - -/*********************************************************************************** - * Product ID in XScale CP15 - Register 0 - * - It contains information on the maximum XScale Core Frequency and - * Silicon Stepping. - * - XScale Core Frequency Id indicates only the maximum XScale frequency - * achievable and not the running XScale frequency (maybe stepped down). - * - The register is read by using ixFeatureCtrlProductIdRead. - * - Usage example: - * productId = ixFeatureCtrlProductIdRead(); - * if( (productId & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) == - * IX_FEATURE_CTRL_SILICON_TYPE_A0 ) - * if( (productId & IX_FEATURE_CTRL_XSCALE_FREQ_MASK) == - * IX_FEATURE_CTRL_XSCALE_FREQ_533 ) - * - * 31 28 27 24 23 20 19 16 15 12 11 9 8 4 3 0 - * -------------------------------------------------------------------------------- - * | 0x6 | 0x9 | 0x0 | 0x5 | 0x4 | Device ID | XScale Core Freq Id | Si Stepping Id | - * -------------------------------------------------------------------------------- - * - * Maximum Achievable XScale Core Frequency Id : 533MHz - 0x1C - * 400MHz - 0x1D - * 266MHz - 0x1F - * - * THE CORE FREQUENCY ID IS NOT APPLICABLE TO IXP46X <\b> - * - * The above is applicable to IXP42X only. CP15 in IXP46X does not contain any - * Frequency ID. - * - * Si Stepping Id : A - 0x0 - * B - 0x1 - * - * XScale Core freq Id - Device ID [11:9] : IXP42X - 0x0 - * IXP46X - 0x1 - *************************************************************************************/ - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_SILICON_TYPE_A0 - * - * @brief This is the value of A0 Silicon in product ID. - */ -#define IX_FEATURE_CTRL_SILICON_TYPE_A0 0 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_SILICON_TYPE_B0 - * - * @brief This is the value of B0 Silicon in product ID. - */ -#define IX_FEATURE_CTRL_SILICON_TYPE_B0 1 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_SILICON_STEPPING_MASK - * - * @brief This is the mask of silicon stepping in product ID. - */ -#define IX_FEATURE_CTRL_SILICON_STEPPING_MASK 0xF - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_DEVICE_TYPE_MASK - * - * @brief This is the mask of silicon stepping in product ID. - */ -#define IX_FEATURE_CTRL_DEVICE_TYPE_MASK (0x7) - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET - * - * @brief This is the mask of silicon stepping in product ID. - */ -#define IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET 9 - - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_XSCALE_FREQ_533 - * - * @brief This is the value of 533MHz XScale Core in product ID. - */ -#define IX_FEATURE_CTRL_XSCALE_FREQ_533 ((0x1C)<<4) - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_XSCALE_FREQ_400 - * - * @brief This is the value of 400MHz XScale Core in product ID. - */ -#define IX_FEATURE_CTRL_XSCALE_FREQ_400 ((0x1D)<<4) - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_XSCALE_FREQ_266 - * - * @brief This is the value of 266MHz XScale Core in product ID. - */ -#define IX_FEATURE_CTRL_XSCALE_FREQ_266 ((0x1F)<<4) - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURE_CTRL_XSCALE_FREQ_MASK - * - * @brief This is the mask of XScale Core in product ID. - */ -#define IX_FEATURE_CTRL_XSCALE_FREQ_MASK ((0xFF)<<4) - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_UTOPIA_32PHY - * - * @brief Maximum UTOPIA PHY available is 32. - * - */ -#define IX_FEATURECTRL_REG_UTOPIA_32PHY 0x0 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_UTOPIA_16PHY - * - * @brief Maximum UTOPIA PHY available is 16. - * - */ -#define IX_FEATURECTRL_REG_UTOPIA_16PHY 0x1 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_UTOPIA_8PHY - * - * @brief Maximum UTOPIA PHY available to is 8. - * - */ -#define IX_FEATURECTRL_REG_UTOPIA_8PHY 0x2 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_UTOPIA_4PHY - * - * @brief Maximum UTOPIA PHY available to is 4. - * - */ -#define IX_FEATURECTRL_REG_UTOPIA_4PHY 0x3 - -#ifdef __ixp46X - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_XSCALE_533FREQ - * - * @brief Maximum frequency available to IXP46x is 533 MHz. - * - */ -#define IX_FEATURECTRL_REG_XSCALE_533FREQ 0x0 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_XSCALE_667FREQ - * - * @brief Maximum frequency available to IXP46x is 667 MHz. - * - */ -#define IX_FEATURECTRL_REG_XSCALE_667FREQ 0x1 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_XSCALE_400FREQ - * - * @brief Maximum frequency available to IXP46x is 400 MHz. - * - */ -#define IX_FEATURECTRL_REG_XSCALE_400FREQ 0x2 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_REG_XSCALE_266FREQ - * - * @brief Maximum frequency available to IXP46x is 266 MHz. - * - */ -#define IX_FEATURECTRL_REG_XSCALE_266FREQ 0x3 - -#endif /* __ixp46X */ - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE - * - * @brief Component selected is not available for device - * - */ -#define IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE 0x0000 - -/** - * @ingroup IxFeatureCtrlAPI - * - * @def IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE - * - * @brief Component selected is not available for device - * - */ -#define IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE 0xffff - -/** - * @defgroup IxFeatureCtrlSwConfig Software Configuration for Access Component - * - * @ingroup IxFeatureCtrlAPI - * - * @brief This section describes software configuration in access component. The - * configuration can be changed at run-time. ixFeatureCtrlSwConfigurationCheck( ) - * will be used across applicable access component to check the configuration. - * ixFeatureCtrlSwConfigurationWrite( ) is used to write the software configuration. - * - * @note All software configurations are default to be enabled. - * - * @{ - */ -/** - * @ingroup IxFeatureCtrlSwConfig - * - * @def IX_FEATURE_CTRL_SWCONFIG_DISABLED - * - * @brief Software configuration is disabled. - * - */ -#define IX_FEATURE_CTRL_SWCONFIG_DISABLED 0 - -/** - * @ingroup IxFeatureCtrlSwConfig - * - * @def IX_FEATURE_CTRL_SWCONFIG_ENABLED - * - * @brief Software configuration is enabled. - * - */ -#define IX_FEATURE_CTRL_SWCONFIG_ENABLED 1 - -/** - * Section for enums - **/ - -/** - * @ingroup IxFeatureCtrlBuildDevice - * - * @enum IxFeatureCtrlBuildDevice - * - * @brief Indicates software build type. - * - * Default build type is IXP42X - * - */ -typedef enum -{ - IX_FEATURE_CTRL_SW_BUILD_IXP42X = 0, /** - * - if(IX_FEATURE_CTRL_COMPONENT_DISABLED != - * ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0))
- * - if(IX_FEATURE_CTRL_COMPONENT_ENABLED == - * ixFeatureCtrlComponentCheck(IX_FEATURECTRL_PCI))
- * - * This function is typically called during component initialization time. - * - * @param componentType @ref IxFeatureCtrlComponentType [in] - the type of a component as - * defined above as IX_FEATURECTRL_XXX (Exp: IX_FEATURECTRL_PCI, IX_FEATURECTRL_ETH0) - - * - * @return - * - IX_FEATURE_CTRL_COMPONENT_ENABLED if component is available - * - IX_FEATURE_CTRL_COMPONENT_DISABLED if component is unavailable - */ -PUBLIC IX_STATUS -ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType); - -/** - * @ingroup IxFeatureCtrlAPI - * - * @fn IxFeatureCtrlProductId ixFeatureCtrlProductIdRead (void) - * - * @brief This function will return IXP400 product ID i.e. CP15, - * Register 0. - * - * @return - * - IxFeatureCtrlProductId - the value of product ID. - * - */ -PUBLIC IxFeatureCtrlProductId -ixFeatureCtrlProductIdRead (void) ; - -/** - * @ingroup IxFeatureCtrlAPI - * - * @fn IX_STATUS ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType) - * - * @brief This function checks whether the specified software configuration is - * enabled or disabled. - * - * Usage Example:
- * - if(IX_FEATURE_CTRL_SWCONFIG_DISABLED != - * ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
- * - if(IX_FEATURE_CTRL_SWCONFIG_ENABLED == - * ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
- * - * This function is typically called during access component initialization time. - * - * @param swConfigType @ref IxFeatureCtrlSwConfig [in] - the type of a software configuration - * defined in IxFeatureCtrlSwConfig enumeration. - * - * @return - * - IX_FEATURE_CTRL_SWCONFIG_ENABLED if software configuration is enabled. - * - IX_FEATURE_CTRL_SWCONFIG_DISABLED if software configuration is disabled. - */ -PUBLIC IX_STATUS -ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType); - -/** - * @ingroup IxFeatureCtrlAPI - * - * @fn void ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled) - * - * @brief This function enable/disable the specified software configuration. - * - * Usage Example:
- * - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, TRUE) is used - * to enable Ethernet Learning Feature
- * - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, FALSE) is used - * to disable Ethernet Learning Feature
- * - * @param swConfigType IxFeatureCtrlSwConfig [in] - the type of a software configuration - * defined in IxFeatureCtrlSwConfig enumeration. - * @param enabled BOOL [in] - To enable(TRUE) / disable (FALSE) the specified software - * configuration. - * - * @return none - * - */ -PUBLIC void -ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled); - -/** - * @ingroup IxFeatureCtrlAPI - * - * @fn void ixFeatureCtrlIxp400SwVersionShow (void) - * - * @brief This function shows the current software release information for IXP400 - * - * @return none - * - */ -PUBLIC void -ixFeatureCtrlIxp400SwVersionShow (void); - -#endif /* IXFEATURECTRL_H */ - -/** - * @} defgroup IxFeatureCtrlAPI - */ diff --git a/arch/arm/cpu/ixp/npe/include/IxHssAcc.h b/arch/arm/cpu/ixp/npe/include/IxHssAcc.h deleted file mode 100644 index 07bb119..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxHssAcc.h +++ /dev/null @@ -1,1316 +0,0 @@ -/** - * @file IxHssAcc.h - * - * @date 07-DEC-2001 - * - * @brief This file contains the public API of the IXP400 HSS Access - * component - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/* ------------------------------------------------------ - Doxygen group definitions - ------------------------------------------------------ */ -/** - * @defgroup IxHssAccAPI IXP400 HSS Access (IxHssAcc) API - * - * @brief The public API for the IXP400 HssAccess component - * - * IxHssAcc is the access layer to the HSS packetised and channelised - * services - * - * Design Notes
- *
    - *
  • When a packet-pipe is configured for 56Kbps RAW mode, byte alignment of - * the transmitted data is not preserved. All raw data that is transmitted - * will be received in proper order by the receiver, but the first bit of - * the packet may be seen at any offset within a byte; all subsequent bytes - * will have the same offset for the duration of the packet. The same offset - * also applies to all subsequent packets received on the packet-pipe too. - * (Similar results will occur for data received from remote end.) While - * this behavior will also occur for 56Kbps HDLC mode, the HDLC - * encoding/decoding will preserve the original byte alignment at the - * receiver end. - *
- * - * 56Kbps Packetised Service Bandwidth Limitation
- *
    - *
  • IxHssAcc supports 56Kbps packetised service at a maximum aggregate rate - * for all HSS ports/HDLC channels of 12.288Mbps[1] in each direction, i.e. - * it supports 56Kbps packetised service on up to 8 T1 trunks. It does - * not support 56Kbps packetised service on 8 E1 trunks (i.e. 4 trunks per - * HSS port) unless those trunks are running 'fractional E1' with maximum - * aggregate rate of 12.288 Mbps in each direction.
    - * [1] 12.288Mbps = 1.536Mbp * 8 T1 - *
- * @{ */ - -#ifndef IXHSSACC_H -#define IXHSSACC_H - -#include "IxOsal.h" - -/* - * #defines for function return types, etc. - */ - -/** - * @def IX_HSSACC_TSLOTS_PER_HSS_PORT - * - * @brief The max number of TDM timeslots supported per HSS port - 4E1's = - * 32x4 = 128 - */ -#define IX_HSSACC_TSLOTS_PER_HSS_PORT 128 - -/* ----------------------------------------------------------- - The following are HssAccess return values returned through - service interfaces. The globally defined IX_SUCCESS (0) and - IX_FAIL (1) in IxOsalTypes.h are also used. - ----------------------------------------------------------- */ -/** - * @def IX_HSSACC_PARAM_ERR - * - * @brief HssAccess function return value for a parameter error - */ -#define IX_HSSACC_PARAM_ERR 2 - -/** - * @def IX_HSSACC_RESOURCE_ERR - * - * @brief HssAccess function return value for a resource error - */ -#define IX_HSSACC_RESOURCE_ERR 3 - -/** - * @def IX_HSSACC_PKT_DISCONNECTING - * - * @brief Indicates that a disconnect call is progressing and will - * disconnect soon - */ -#define IX_HSSACC_PKT_DISCONNECTING 4 - -/** - * @def IX_HSSACC_Q_WRITE_OVERFLOW - * - * @brief Indicates that an attempt to Tx or to replenish an - * RxFree Q failed due to Q overflow. - */ -#define IX_HSSACC_Q_WRITE_OVERFLOW 5 - -/* ------------------------------------------------------------------- - The following errors are HSS/NPE errors returned on error retrieval - ------------------------------------------------------------------- */ -/** - * @def IX_HSSACC_NO_ERROR - * - * @brief HSS port no error present - */ -#define IX_HSSACC_NO_ERROR 0 - -/** - * @def IX_HSSACC_TX_FRM_SYNC_ERR - * - * @brief HSS port TX Frame Sync error - */ -#define IX_HSSACC_TX_FRM_SYNC_ERR 1 - -/** - * @def IX_HSSACC_TX_OVER_RUN_ERR - * - * @brief HSS port TX over-run error - */ -#define IX_HSSACC_TX_OVER_RUN_ERR 2 - -/** - * @def IX_HSSACC_CHANNELISED_SW_TX_ERR - * - * @brief NPE software error in channelised TX - */ -#define IX_HSSACC_CHANNELISED_SW_TX_ERR 3 - -/** - * @def IX_HSSACC_PACKETISED_SW_TX_ERR - * - * @brief NPE software error in packetised TX - */ -#define IX_HSSACC_PACKETISED_SW_TX_ERR 4 - -/** - * @def IX_HSSACC_RX_FRM_SYNC_ERR - * - * @brief HSS port RX Frame Sync error - */ -#define IX_HSSACC_RX_FRM_SYNC_ERR 5 - -/** - * @def IX_HSSACC_RX_OVER_RUN_ERR - * - * @brief HSS port RX over-run error - */ -#define IX_HSSACC_RX_OVER_RUN_ERR 6 - -/** - * @def IX_HSSACC_CHANNELISED_SW_RX_ERR - * - * @brief NPE software error in channelised RX - */ -#define IX_HSSACC_CHANNELISED_SW_RX_ERR 7 - -/** - * @def IX_HSSACC_PACKETISED_SW_RX_ERR - * - * @brief NPE software error in packetised TX - */ -#define IX_HSSACC_PACKETISED_SW_RX_ERR 8 - -/* ----------------------------------- - Packetised service specific defines - ----------------------------------- */ - -/** - * @def IX_HSSACC_PKT_MIN_RX_MBUF_SIZE - * - * @brief Minimum size of the Rx mbuf in bytes which the client must supply - * to the component. - */ -#define IX_HSSACC_PKT_MIN_RX_MBUF_SIZE 64 - -/* -------------------------------------------------------------------- - Enumerated Types - these enumerated values may be used in setting up - the contents of hardware registers - -------------------------------------------------------------------- */ -/** - * @enum IxHssAccHssPort - * @brief The HSS port ID - There are two identical ports (0-1). - * - */ -typedef enum -{ - IX_HSSACC_HSS_PORT_0, /**< HSS Port 0 */ - IX_HSSACC_HSS_PORT_1, /**< HSS Port 1 */ - IX_HSSACC_HSS_PORT_MAX /**< Delimiter for error checks */ -} IxHssAccHssPort; - -/** - * @enum IxHssAccHdlcPort - * @brief The HDLC port ID - There are four identical HDLC ports (0-3) per - * HSS port and they correspond to the 4 E1/T1 trunks. - * - */ -typedef enum -{ - IX_HSSACC_HDLC_PORT_0, /**< HDLC Port 0 */ - IX_HSSACC_HDLC_PORT_1, /**< HDLC Port 1 */ - IX_HSSACC_HDLC_PORT_2, /**< HDLC Port 2 */ - IX_HSSACC_HDLC_PORT_3, /**< HDLC Port 3 */ - IX_HSSACC_HDLC_PORT_MAX /**< Delimiter for error checks */ -} IxHssAccHdlcPort; - -/** - * @enum IxHssAccTdmSlotUsage - * @brief The HSS TDM stream timeslot assignment types - * - */ -typedef enum -{ - IX_HSSACC_TDMMAP_UNASSIGNED, /**< Unassigned */ - IX_HSSACC_TDMMAP_HDLC, /**< HDLC - packetised */ - IX_HSSACC_TDMMAP_VOICE56K, /**< Voice56K - channelised */ - IX_HSSACC_TDMMAP_VOICE64K, /**< Voice64K - channelised */ - IX_HSSACC_TDMMAP_MAX /**< Delimiter for error checks */ -} IxHssAccTdmSlotUsage; - -/** - * @enum IxHssAccFrmSyncType - * @brief The HSS frame sync pulse type - * - */ -typedef enum -{ - IX_HSSACC_FRM_SYNC_ACTIVE_LOW, /**< Frame sync is sampled low */ - IX_HSSACC_FRM_SYNC_ACTIVE_HIGH, /**< sampled high */ - IX_HSSACC_FRM_SYNC_FALLINGEDGE, /**< sampled on a falling edge */ - IX_HSSACC_FRM_SYNC_RISINGEDGE, /**< sampled on a rising edge */ - IX_HSSACC_FRM_SYNC_TYPE_MAX /**< Delimiter for error checks */ -} IxHssAccFrmSyncType; - -/** - * @enum IxHssAccFrmSyncEnable - * @brief The IxHssAccFrmSyncEnable determines how the frame sync pulse is - * used - * */ -typedef enum -{ - IX_HSSACC_FRM_SYNC_INPUT, /**< Frame sync is sampled as an input */ - IX_HSSACC_FRM_SYNC_INVALID_VALUE, /**< 1 is not used */ - IX_HSSACC_FRM_SYNC_OUTPUT_FALLING, /**< Frame sync is an output generated - off a falling clock edge */ - IX_HSSACC_FRM_SYNC_OUTPUT_RISING, /**< Frame sync is an output generated - off a rising clock edge */ - IX_HSSACC_FRM_SYNC_ENABLE_MAX /**< Delimiter for error checks */ -} IxHssAccFrmSyncEnable; - -/** - * @enum IxHssAccClkEdge - * @brief IxHssAccClkEdge is used to determine the clk edge to use for - * framing and data - * - */ -typedef enum -{ - IX_HSSACC_CLK_EDGE_FALLING, /**< Clock sampled off a falling edge */ - IX_HSSACC_CLK_EDGE_RISING, /**< Clock sampled off a rising edge */ - IX_HSSACC_CLK_EDGE_MAX /**< Delimiter for error checks */ -} IxHssAccClkEdge; - -/** - * @enum IxHssAccClkDir - * @brief The HSS clock direction - * - */ -typedef enum -{ - IX_HSSACC_SYNC_CLK_DIR_INPUT, /**< Clock is an input */ - IX_HSSACC_SYNC_CLK_DIR_OUTPUT, /**< Clock is an output */ - IX_HSSACC_SYNC_CLK_DIR_MAX /**< Delimiter for error checks */ -} IxHssAccClkDir; - -/** - * @enum IxHssAccFrmPulseUsage - * @brief The HSS frame pulse usage - * - */ -typedef enum -{ - IX_HSSACC_FRM_PULSE_ENABLED, /**< Generate/Receive frame pulses */ - IX_HSSACC_FRM_PULSE_DISABLED, /**< Disregard frame pulses */ - IX_HSSACC_FRM_PULSE_MAX /**< Delimiter for error checks */ -} IxHssAccFrmPulseUsage; - -/** - * @enum IxHssAccDataRate - * @brief The HSS Data rate in relation to the clock - * - */ -typedef enum -{ - IX_HSSACC_CLK_RATE, /**< Data rate is at the configured clk speed */ - IX_HSSACC_HALF_CLK_RATE, /**< Data rate is half the configured clk speed */ - IX_HSSACC_DATA_RATE_MAX /**< Delimiter for error checks */ -} IxHssAccDataRate; - -/** - * @enum IxHssAccDataPolarity - * @brief The HSS data polarity type - * - */ -typedef enum -{ - IX_HSSACC_DATA_POLARITY_SAME, /**< Don't invert data between NPE and - HSS FIFOs */ - IX_HSSACC_DATA_POLARITY_INVERT, /**< Invert data between NPE and HSS - FIFOs */ - IX_HSSACC_DATA_POLARITY_MAX /**< Delimiter for error checks */ -} IxHssAccDataPolarity; - -/** - * @enum IxHssAccBitEndian - * @brief HSS Data endianness - * - */ -typedef enum -{ - IX_HSSACC_LSB_ENDIAN, /**< TX/RX Least Significant Bit first */ - IX_HSSACC_MSB_ENDIAN, /**< TX/RX Most Significant Bit first */ - IX_HSSACC_ENDIAN_MAX /**< Delimiter for the purposes of error checks */ -} IxHssAccBitEndian; - - -/** - * @enum IxHssAccDrainMode - * @brief Tx pin open drain mode - * - */ -typedef enum -{ - IX_HSSACC_TX_PINS_NORMAL, /**< Normal mode */ - IX_HSSACC_TX_PINS_OPEN_DRAIN, /**< Open Drain mode */ - IX_HSSACC_TX_PINS_MAX /**< Delimiter for error checks */ -} IxHssAccDrainMode; - -/** - * @enum IxHssAccSOFType - * @brief HSS start of frame types - * - */ -typedef enum -{ - IX_HSSACC_SOF_FBIT, /**< Framing bit transmitted and expected on rx */ - IX_HSSACC_SOF_DATA, /**< Framing bit not transmitted nor expected on rx */ - IX_HSSACC_SOF_MAX /**< Delimiter for error checks */ -} IxHssAccSOFType; - -/** - * @enum IxHssAccDataEnable - * @brief IxHssAccDataEnable is used to determine whether or not to drive - * the data pins - * - */ -typedef enum -{ - IX_HSSACC_DE_TRI_STATE, /**< TRI-State the data pins */ - IX_HSSACC_DE_DATA, /**< Push data out the data pins */ - IX_HSSACC_DE_MAX /**< Delimiter for error checks */ -} IxHssAccDataEnable; - -/** - * @enum IxHssAccTxSigType - * @brief IxHssAccTxSigType is used to determine how to drive the data pins - * - */ -typedef enum -{ - IX_HSSACC_TXSIG_LOW, /**< Drive the data pins low */ - IX_HSSACC_TXSIG_HIGH, /**< Drive the data pins high */ - IX_HSSACC_TXSIG_HIGH_IMP, /**< Drive the data pins with high impedance */ - IX_HSSACC_TXSIG_MAX /**< Delimiter for error checks */ -} IxHssAccTxSigType; - -/** - * @enum IxHssAccFbType - * @brief IxHssAccFbType determines how to drive the Fbit - * - * @warning This will only be used for T1 @ 1.544MHz - * - */ -typedef enum -{ - IX_HSSACC_FB_FIFO, /**< Fbit is dictated in FIFO */ - IX_HSSACC_FB_HIGH_IMP, /**< Fbit is high impedance */ - IX_HSSACC_FB_MAX /**< Delimiter for error checks */ -} IxHssAccFbType; - -/** - * @enum IxHssAcc56kEndianness - * @brief 56k data endianness when using the 56k type - * - */ -typedef enum -{ - IX_HSSACC_56KE_BIT_7_UNUSED, /**< High bit is unused */ - IX_HSSACC_56KE_BIT_0_UNUSED, /**< Low bit is unused */ - IX_HSSACC_56KE_MAX /**< Delimiter for error checks */ -} IxHssAcc56kEndianness; - -/** - * @enum IxHssAcc56kSel - * @brief 56k data transmission type when using the 56k type - * - */ -typedef enum -{ - IX_HSSACC_56KS_32_8_DATA, /**< 32/8 bit data */ - IX_HSSACC_56KS_56K_DATA, /**< 56K data */ - IX_HSSACC_56KS_MAX /**< Delimiter for error checks */ -} IxHssAcc56kSel; - - -/** - * @enum IxHssAccClkSpeed - * @brief IxHssAccClkSpeed represents the HSS clock speeds available - * - */ -typedef enum -{ - IX_HSSACC_CLK_SPEED_512KHZ, /**< 512KHz */ - IX_HSSACC_CLK_SPEED_1536KHZ, /**< 1.536MHz */ - IX_HSSACC_CLK_SPEED_1544KHZ, /**< 1.544MHz */ - IX_HSSACC_CLK_SPEED_2048KHZ, /**< 2.048MHz */ - IX_HSSACC_CLK_SPEED_4096KHZ, /**< 4.096MHz */ - IX_HSSACC_CLK_SPEED_8192KHZ, /**< 8.192MHz */ - IX_HSSACC_CLK_SPEED_MAX /**< Delimiter for error checking */ -} IxHssAccClkSpeed; - -/** - * @enum IxHssAccPktStatus - * @brief Indicates the status of packets passed to the client - * - */ -typedef enum -{ - IX_HSSACC_PKT_OK, /**< Error free.*/ - IX_HSSACC_STOP_SHUTDOWN_ERROR, /**< Errored due to stop or shutdown - occurrance.*/ - IX_HSSACC_HDLC_ALN_ERROR, /**< HDLC alignment error */ - IX_HSSACC_HDLC_FCS_ERROR, /**< HDLC Frame Check Sum error.*/ - IX_HSSACC_RXFREE_Q_EMPTY_ERROR, /**< RxFree Q became empty - while receiving this packet.*/ - IX_HSSACC_HDLC_MAX_FRAME_SIZE_EXCEEDED, /**< HDLC frame size - received is greater than - max specified at connect.*/ - IX_HSSACC_HDLC_ABORT_ERROR, /**< HDLC frame received is invalid due to an - abort sequence received.*/ - IX_HSSACC_DISCONNECT_IN_PROGRESS /**< Packet returned - because a disconnect is in progress */ -} IxHssAccPktStatus; - - -/** - * @enum IxHssAccPktCrcType - * @brief HDLC CRC type - * - */ -typedef enum -{ - IX_HSSACC_PKT_16_BIT_CRC = 16, /**< 16 bit CRC is being used */ - IX_HSSACC_PKT_32_BIT_CRC = 32 /**< 32 bit CRC is being used */ -} IxHssAccPktCrcType; - -/** - * @enum IxHssAccPktHdlcIdleType - * @brief HDLC idle transmission type - * - */ -typedef enum -{ - IX_HSSACC_HDLC_IDLE_ONES, /**< idle tx/rx will be a succession of ones */ - IX_HSSACC_HDLC_IDLE_FLAGS /**< idle tx/rx will be repeated flags */ -} IxHssAccPktHdlcIdleType; - -/** - * @brief Structure containing HSS port configuration parameters - * - * Note: All of these are used for TX. Only some are specific to RX. - * - */ -typedef struct -{ - IxHssAccFrmSyncType frmSyncType; /**< frame sync pulse type (tx/rx) */ - IxHssAccFrmSyncEnable frmSyncIO; /**< how the frame sync pulse is - used (tx/rx) */ - IxHssAccClkEdge frmSyncClkEdge; /**< frame sync clock edge type - (tx/rx) */ - IxHssAccClkEdge dataClkEdge; /**< data clock edge type (tx/rx) */ - IxHssAccClkDir clkDirection; /**< clock direction (tx/rx) */ - IxHssAccFrmPulseUsage frmPulseUsage; /**< whether to use the frame sync - pulse or not (tx/rx) */ - IxHssAccDataRate dataRate; /**< data rate in relation to the - clock (tx/rx) */ - IxHssAccDataPolarity dataPolarity; /**< data polarity type (tx/rx) */ - IxHssAccBitEndian dataEndianness; /**< data endianness (tx/rx) */ - IxHssAccDrainMode drainMode; /**< tx pin open drain mode (tx) */ - IxHssAccSOFType fBitUsage; /**< start of frame types (tx/rx) */ - IxHssAccDataEnable dataEnable; /**< whether or not to drive the data - pins (tx) */ - IxHssAccTxSigType voice56kType; /**< how to drive the data pins for - voice56k type (tx) */ - IxHssAccTxSigType unassignedType; /**< how to drive the data pins for - unassigned type (tx) */ - IxHssAccFbType fBitType; /**< how to drive the Fbit (tx) */ - IxHssAcc56kEndianness voice56kEndian;/**< 56k data endianness when using - the 56k type (tx) */ - IxHssAcc56kSel voice56kSel; /**< 56k data transmission type when - using the 56k type (tx) */ - unsigned frmOffset; /**< frame pulse offset in bits wrt - the first timeslot (0-1023) (tx/rx) */ - unsigned maxFrmSize; /**< frame size in bits (1-1024) - (tx/rx) */ -} IxHssAccPortConfig; - -/** - * @brief Structure containing HSS configuration parameters - * - */ -typedef struct -{ - IxHssAccPortConfig txPortConfig; /**< HSS tx port configuration */ - IxHssAccPortConfig rxPortConfig; /**< HSS rx port configuration */ - unsigned numChannelised; /**< The number of channelised - timeslots (0-32) */ - unsigned hssPktChannelCount; /**< The number of packetised - clients (0 - 4) */ - UINT8 channelisedIdlePattern; /**< The byte to be transmitted on - channelised service when there - is no client data to tx */ - BOOL loopback; /**< The HSS loopback state */ - unsigned packetizedIdlePattern; /**< The data to be transmitted on - packetised service when there is - no client data to tx */ - IxHssAccClkSpeed clkSpeed; /**< The HSS clock speed */ -} IxHssAccConfigParams; - -/** - * @brief This structure contains 56Kbps, HDLC-mode configuration parameters - * - */ -typedef struct -{ - BOOL hdlc56kMode; /**< 56kbps(TRUE)/64kbps(FALSE) HDLC */ - IxHssAcc56kEndianness hdlc56kEndian; /**< 56kbps data endianness - - ignored if hdlc56kMode is FALSE*/ - BOOL hdlc56kUnusedBitPolarity0; /**< The polarity '0'(TRUE)/'1'(FALSE) of the unused - bit while in 56kbps mode - - ignored if hdlc56kMode is FALSE*/ -} IxHssAccHdlcMode; - -/** - * @brief This structure contains information required by the NPE to - * configure the HDLC co-processor - * - */ -typedef struct -{ - IxHssAccPktHdlcIdleType hdlcIdleType; /**< What to transmit when a HDLC port is idle */ - IxHssAccBitEndian dataEndian; /**< The HDLC data endianness */ - IxHssAccPktCrcType crcType; /**< The CRC type to be used for this HDLC port */ -} IxHssAccPktHdlcFraming; - -/** - * @typedef UINT32 IxHssAccPktUserId - * - * @brief The client supplied value which will be supplied as a parameter - * with a given callback. - * - * This value will be passed into the ixHssAccPktPortConnect function once each - * with given callbacks. This value will then be passed back to the client - * as one of the parameters to each of these callbacks, - * when these callbacks are called. - */ -typedef UINT32 IxHssAccPktUserId; - - -/** - * @typedef IxHssAccLastErrorCallback - * @brief Prototype of the clients function to accept notification of the - * last error - * - * This function is registered through the config. The client will initiate - * the last error retrieval. The HssAccess component will send a message to - * the NPE through the NPE Message Handler. When a response to the read is - * received, the NPE Message Handler will callback the HssAccess component - * which will execute this function in the same IxNpeMh context. The client - * will be passed the last error and the related service port (packetised - * 0-3, channelised 0) - * - * @param lastHssError unsigned [in] - The last Hss error registered that - * has been registered. - * @param servicePort unsigned [in] - This is the service port number. - * (packetised 0-3, channelised 0) - * - * @return void - */ -typedef void (*IxHssAccLastErrorCallback) (unsigned lastHssError, - unsigned servicePort); - -/** - * @typedef IxHssAccPktRxCallback - * @brief Prototype of the clients function to accept notification of - * packetised rx - * - * This function is registered through the ixHssAccPktPortConnect. hssPktAcc will pass - * received data in the form of mbufs to the client. The mbuf passed back - * to the client could contain a chain of buffers, depending on the packet - * size received. - * - * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contains the - * payload received. - * @param numHssErrs unsigned [in] - This is the number of hssErrors - * the Npe has received - * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the - * mbuf that has been received. - * @param rxUserId @ref IxHssAccPktUserId [in] - This is the client supplied value - * passed in at ixHssAccPktPortConnect time which is now returned to the client. - * - * @return void - */ -typedef void (*IxHssAccPktRxCallback) (IX_OSAL_MBUF *buffer, - unsigned numHssErrs, - IxHssAccPktStatus pktStatus, - IxHssAccPktUserId rxUserId); - -/** - * @typedef IxHssAccPktRxFreeLowCallback - * @brief Prototype of the clients function to accept notification of - * requirement of more Rx Free buffers - * - * The client can choose to register a callback of this type when - * calling a connecting. This function is registered through the ixHssAccPktPortConnect. - * If defined, the access layer will provide the trigger for - * this callback. The callback will be responsible for supplying mbufs to - * the access layer for use on the receive path from the HSS using - * ixHssPktAccFreeBufReplenish. - * - * @return void - */ -typedef void (*IxHssAccPktRxFreeLowCallback) (IxHssAccPktUserId rxFreeLowUserId); - -/** - * @typedef IxHssAccPktTxDoneCallback - * @brief Prototype of the clients function to accept notification of - * completion with Tx buffers - * - * This function is registered through the ixHssAccPktPortConnect. It enables - * the hssPktAcc to pass buffers back to the client - * when transmission is complete. - * - * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contained - * the payload that was for Tx. - * @param numHssErrs unsigned [in] - This is the number of hssErrors - * the Npe has received - * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the - * mbuf that has been transmitted. - * @param txDoneUserId @ref IxHssAccPktUserId [in] - This is the client supplied value - * passed in at ixHssAccPktPortConnect time which is now returned to the client. - * - * @return void - */ -typedef void (*IxHssAccPktTxDoneCallback) (IX_OSAL_MBUF *buffer, - unsigned numHssErrs, - IxHssAccPktStatus pktStatus, - IxHssAccPktUserId txDoneUserId); - -/** - * @typedef IxHssAccChanRxCallback - * @brief Prototype of the clients function to accept notification of - * channelised rx - * - * This callback, if defined by the client in the connect, will get called - * in the context of an IRQ. The IRQ will be triggered when the hssSyncQMQ - * is not empty. The queued entry will be dequeued and this function will - * be executed. - * - * @param hssPortId @ref IxHssAccHssPort - The HSS port Id. There are two - * identical ports (0-1). - * @param txOffset unsigned [in] - an offset indicating from where within - * the txPtrList the NPE is currently transmitting from. - * @param rxOffset unsigned [in] - an offset indicating where within the - * receive buffers the NPE has just written the received data to. - * @param numHssErrs unsigned [in] - This is the number of hssErrors - * the Npe has received - * - * @return void - */ -typedef void (*IxHssAccChanRxCallback) (IxHssAccHssPort hssPortId, - unsigned rxOffset, - unsigned txOffset, - unsigned numHssErrs); - -/* - * Prototypes for interface functions. - */ - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccPortInit (IxHssAccHssPort hssPortId, - IxHssAccConfigParams *configParams, - IxHssAccTdmSlotUsage *tdmMap, - IxHssAccLastErrorCallback lastHssErrorCallback) - * - * @brief Initialise a HSS port. No channelised or packetised connections - * should exist in the HssAccess layer while this interface is being called. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param *configParams @ref IxHssAccConfigParams [in] - A pointer to the HSS - * configuration structure - * @param *tdmMap @ref IxHssAccTdmSlotUsage [in] - A pointer to an array of size - * IX_HSSACC_TSLOTS_PER_HSS_PORT, defining the slot usage over the HSS port - * @param lastHssErrorCallback @ref IxHssAccLastErrorCallback [in] - Client - * callback to report last error - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccPortInit (IxHssAccHssPort hssPortId, - IxHssAccConfigParams *configParams, - IxHssAccTdmSlotUsage *tdmMap, - IxHssAccLastErrorCallback lastHssErrorCallback); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccLastErrorRetrievalInitiate ( - IxHssAccHssPort hssPortId) - * - * @brief Initiate the retrieval of the last HSS error. The HSS port - * should be configured before attempting to call this interface. - * - * @param hssPortId @ref IxHssAccHssPort [in] - the HSS port ID - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccLastErrorRetrievalInitiate (IxHssAccHssPort hssPortId); - - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccInit () - * - * @brief This function is responsible for initialising resources for use - * by the packetised and channelised clients. It should be called after - * HSS NPE image has been downloaded into NPE-A and before any other - * HssAccess interface is called. - * No other HssAccPacketised interface should be called while this interface - * is being processed. - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due - * to a resource error - */ -PUBLIC IX_STATUS -ixHssAccInit (void); - - -/** - * - * @ingroup IxHssAccAPI - * - * @fn ixHssAccPktPortConnect (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - BOOL hdlcFraming, - IxHssAccHdlcMode hdlcMode, - BOOL hdlcBitInvert, - unsigned blockSizeInWords, - UINT32 rawIdleBlockPattern, - IxHssAccPktHdlcFraming hdlcTxFraming, - IxHssAccPktHdlcFraming hdlcRxFraming, - unsigned frmFlagStart, - IxHssAccPktRxCallback rxCallback, - IxHssAccPktUserId rxUserId, - IxHssAccPktRxFreeLowCallback rxFreeLowCallback, - IxHssAccPktUserId rxFreeLowUserId, - IxHssAccPktTxDoneCallback txDoneCallback, - IxHssAccPktUserId txDoneUserId) - * - * @brief This function is responsible for connecting a client to one of - * the 4 available HDLC ports. The HSS port should be configured before - * attempting a connect. No other HssAccPacketised interface should be - * called while this connect is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port and - * it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 - * @param hdlcFraming BOOL [in] - This value determines whether the service - * will use HDLC data or the debug, raw data type i.e. no HDLC processing - * @param hdlcMode @ref IxHssAccHdlcMode [in] - This structure contains 56Kbps, HDLC-mode - * configuration parameters - * @param hdlcBitInvert BOOL [in] - This value determines whether bit inversion - * will occur between HDLC and HSS co-processors i.e. post-HDLC processing for - * transmit and pre-HDLC processing for receive, for the specified HDLC Termination - * Point - * @param blockSizeInWords unsigned [in] - The max tx/rx block size - * @param rawIdleBlockPattern UINT32 [in] - Tx idle pattern in raw mode - * @param hdlcTxFraming @ref IxHssAccPktHdlcFraming [in] - This structure contains - * the following information required by the NPE to configure the HDLC - * co-processor for TX - * @param hdlcRxFraming @ref IxHssAccPktHdlcFraming [in] - This structure contains - * the following information required by the NPE to configure the HDLC - * co-processor for RX - * @param frmFlagStart unsigned - Number of flags to precede to - * transmitted flags (0-2). - * @param rxCallback @ref IxHssAccPktRxCallback [in] - Pointer to - * the clients packet receive function. - * @param rxUserId @ref IxHssAccPktUserId [in] - The client supplied rx value - * to be passed back as an argument to the supplied rxCallback - * @param rxFreeLowCallback @ref IxHssAccPktRxFreeLowCallback [in] - Pointer to - * the clients Rx free buffer request function. If NULL, assume client will - * trigger independently. - * @param rxFreeLowUserId @ref IxHssAccPktUserId [in] - The client supplied RxFreeLow value - * to be passed back as an argument to the supplied rxFreeLowCallback - * @param txDoneCallback @ref IxHssAccPktTxDoneCallback [in] - Pointer to the - * clients Tx done callback function - * @param txDoneUserId @ref IxHssAccPktUserId [in] - The client supplied txDone value - * to be passed back as an argument to the supplied txDoneCallback - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due - * to a resource error - */ -PUBLIC IX_STATUS -ixHssAccPktPortConnect (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - BOOL hdlcFraming, - IxHssAccHdlcMode hdlcMode, - BOOL hdlcBitInvert, - unsigned blockSizeInWords, - UINT32 rawIdleBlockPattern, - IxHssAccPktHdlcFraming hdlcTxFraming, - IxHssAccPktHdlcFraming hdlcRxFraming, - unsigned frmFlagStart, - IxHssAccPktRxCallback rxCallback, - IxHssAccPktUserId rxUserId, - IxHssAccPktRxFreeLowCallback rxFreeLowCallback, - IxHssAccPktUserId rxFreeLowUserId, - IxHssAccPktTxDoneCallback txDoneCallback, - IxHssAccPktUserId txDoneUserId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccPktPortEnable (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId) - * - * @brief This function is responsible for enabling a packetised service - * for the specified HSS/HDLC port combination. It enables the RX flow. The - * client must have already connected to a packetised service and is responsible - * for ensuring an adequate amount of RX mbufs have been supplied to the access - * component before enabling the packetised service. This function must be called - * on a given port before any call to ixHssAccPktPortTx on the same port. - * No other HssAccPacketised interface should be called while this interface is - * being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to enable the service - * on. - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccPktPortEnable (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId); - -/** - * @fn IX_STATUS ixHssAccPktPortDisable (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId) - * - * @brief This function is responsible for disabling a packetised service - * for the specified HSS/HDLC port combination. It disables the RX flow. - * The client must have already connected to and enabled a packetised service - * for the specified HDLC port. This disable interface can be called before a - * disconnect, but is not required to. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to disable - * the service on. - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccPktPortDisable (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId) - * - * @brief This function is responsible for disconnecting a client from one - * of the 4 available HDLC ports. It is not required that the Rx Flow - * has been disabled before calling this function. If the RX Flow has not been - * disabled, the disconnect will disable it before proceeding with the - * disconnect. No other HssAccPacketised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port - * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PKT_DISCONNECTING The function has initiated the disconnecting - * procedure but it has not completed yet. - */ -PUBLIC IX_STATUS -ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn BOOL ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId) - * - * @brief This function is called to check if a given HSS/HDLC port - * combination is in a connected state or not. This function may be called - * at any time to determine a ports state. No other HssAccPacketised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port - * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 - * - * @return - * - TRUE The state of this HSS/HDLC port combination is disconnected, - * so if a disconnect was called, it is now completed. - * - FALSE The state of this HSS/HDLC port combination is connected, - * so if a disconnect was called, it is not yet completed. - */ -PUBLIC BOOL -ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId); - - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - IX_OSAL_MBUF *buffer) - * - * @brief Function which the client calls at regular intervals to provide - * mbufs to the access component for RX. A connection should exist for - * the specified hssPortId/hdlcPortId combination before attempting to call this - * interface. Also, the connection should not be in a disconnecting state. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port - * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 - * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a free mbuf to filled with payload. - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due - * to a resource error - * - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q - * overflow - */ -PUBLIC IX_STATUS -ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - IX_OSAL_MBUF *buffer); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccPktPortTx (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - IX_OSAL_MBUF *buffer) - * - * @brief Function which the client calls when it wants to transmit - * packetised data. An enabled connection should exist on the specified - * hssPortId/hdlcPortId combination before attempting to call this interface. - * No other HssAccPacketised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port - * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 - * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a chain of mbufs which the - * client has filled with the payload - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due - * to a resource error. See note. - * - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q - * overflow - * - * @note IX_HSSACC_RESOURCE_ERR is returned when a free descriptor cannot be - * obtained to send the chain of mbufs to the NPE. This is a normal scenario. - * HssAcc has a pool of descriptors and this error means that they are currently - * all in use. - * The recommended approach to this is to retry until a descriptor becomes free - * and the packet is successfully transmitted. - * Alternatively, the user could wait until the next IxHssAccPktTxDoneCallback - * callback is triggered, and then retry, as it is this event that causes a - * transmit descriptor to be freed. - */ -PUBLIC IX_STATUS -ixHssAccPktPortTx (IxHssAccHssPort hssPortId, - IxHssAccHdlcPort hdlcPortId, - IX_OSAL_MBUF *buffer); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccChanConnect (IxHssAccHssPort hssPortId, - unsigned bytesPerTSTrigger, - UINT8 *rxCircular, - unsigned numRxBytesPerTS, - UINT32 *txPtrList, - unsigned numTxPtrLists, - unsigned numTxBytesPerBlk, - IxHssAccChanRxCallback rxCallback) - * - * @brief This function allows the client to connect to the Tx/Rx NPE - * Channelised Service. There can only be one client per HSS port. The - * client is responsible for ensuring that the HSS port is configured - * appropriately before its connect request. No other HssAccChannelised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param bytesPerTSTrigger unsigned [in] - The NPE will trigger the access - * component after bytesPerTSTrigger have been received for all trunk - * timeslots. This figure is a multiple of 8 e.g. 8 for 1ms trigger, 16 for - * 2ms trigger. - * @param *rxCircular UINT8 [in] - A pointer to memory allocated by the - * client to be filled by data received. The buffer at this address is part - * of a pool of buffers to be accessed in a circular fashion. This address - * will be written to by the NPE. Therefore, it needs to be a physical address. - * @param numRxBytesPerTS unsigned [in] - The number of bytes allocated per - * timeslot within the receive memory. This figure will depend on the - * latency of the system. It needs to be deep enough for data to be read by - * the client before the NPE re-writes over that memory e.g. if the client - * samples at a rate of 40bytes per timeslot, numRxBytesPerTS may need to - * be 40bytes * 3. This would give the client 3 * 5ms of time before - * received data is over-written. - * @param *txPtrList UINT32 [in] - The address of an area of contiguous - * memory allocated by the client to be populated with pointers to data for - * transmission. Each pointer list contains a pointer per active channel. - * The txPtrs will point to data to be transmitted by the NPE. Therefore, - * they must point to physical addresses. - * @param numTxPtrLists unsigned [in] - The number of pointer lists in - * txPtrList. This figure is dependent on jitter. - * @param numTxBytesPerBlk unsigned [in] - The size of the Tx data, in - * bytes, that each pointer within the PtrList points to. - * @param rxCallback @ref IxHssAccChanRxCallback [in] - A client function - * pointer to be called back to handle the actual tx/rx of channelised - * data. If this is not NULL, an ISR will call this function. If this - * pointer is NULL, it implies that the client will use a polling mechanism - * to detect when the tx and rx of channelised data is to occur. The client - * will use hssChanAccStatus for this. - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ - -PUBLIC IX_STATUS -ixHssAccChanConnect (IxHssAccHssPort hssPortId, - unsigned bytesPerTSTrigger, - UINT8 *rxCircular, - unsigned numRxBytesPerTS, - UINT32 *txPtrList, - unsigned numTxPtrLists, - unsigned numTxBytesPerBlk, - IxHssAccChanRxCallback rxCallback); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccChanPortEnable (IxHssAccHssPort hssPortId) - * - * @brief This function is responsible for enabling a channelised service - * for the specified HSS port. It enables the NPE RX flow. The client must - * have already connected to a channelised service before enabling the - * channelised service. No other HssAccChannelised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccChanPortEnable (IxHssAccHssPort hssPortId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccChanPortDisable (IxHssAccHssPort hssPortId) - * - * @brief This function is responsible for disabling a channelised service - * for the specified HSS port. It disables the NPE RX flow. The client must - * have already connected to and enabled a channelised service for the - * specified HSS port. This disable interface can be called before a - * disconnect, but is not required to. No other HssAccChannelised - * interface should be called while this interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccChanPortDisable (IxHssAccHssPort hssPortId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccChanDisconnect (IxHssAccHssPort hssPortId) - * - * @brief This function allows the client to Disconnect from a channelised - * service. If the NPE RX Flow has not been disabled, the disconnect will - * disable it before proceeding with other disconnect functionality. - * No other HssAccChannelised interface should be called while this - * interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccChanDisconnect (IxHssAccHssPort hssPortId); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn IX_STATUS ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId, - BOOL *dataRecvd, - unsigned *rxOffset, - unsigned *txOffset, - unsigned *numHssErrs) - * - * @brief This function is called by the client to query whether or not - * channelised data has been received. If there is, hssChanAcc will return - * the details in the output parameters. An enabled connection should - * exist on the specified hssPortId before attempting to call this interface. - * No other HssAccChannelised interface should be called while this - * interface is being processed. - * - * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two - * identical ports (0-1). - * @param *dataRecvd BOOL [out] - This BOOL indicates to the client whether - * or not the access component has read any data for the client. If - * FALSE, the other output parameters will not have been written to. - * @param *rxOffset unsigned [out] - An offset to indicate to the client - * where within the receive buffers the NPE has just written the received - * data to. - * @param *txOffset unsigned [out] - An offset to indicate to the client - * from where within the txPtrList the NPE is currently transmitting from - * @param *numHssErrs unsigned [out] - The total number of HSS port errors - * since initial port configuration - * - * - * @return - * - IX_SUCCESS The function executed successfully - * - IX_FAIL The function did not execute successfully - * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a - * parameter error - */ -PUBLIC IX_STATUS -ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId, - BOOL *dataRecvd, - unsigned *rxOffset, - unsigned *txOffset, - unsigned *numHssErrs); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn void ixHssAccShow (void) - * - * @brief This function will display the current state of the IxHssAcc - * component. The output is sent to stdout. - * - * @return void - */ -PUBLIC void -ixHssAccShow (void); - -/** - * - * @ingroup IxHssAccAPI - * - * @fn void ixHssAccStatsInit (void) - * - * @brief This function will reset the IxHssAcc statistics. - * - * @return void - */ -PUBLIC void -ixHssAccStatsInit (void); - -#endif /* IXHSSACC_H */ - -/** - * @} defgroup IxHssAcc - */ diff --git a/arch/arm/cpu/ixp/npe/include/IxI2cDrv.h b/arch/arm/cpu/ixp/npe/include/IxI2cDrv.h deleted file mode 100644 index 92c6b24..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxI2cDrv.h +++ /dev/null @@ -1,867 +0,0 @@ -/** - * @file IxI2cDrv.h - * - * @brief Header file for the IXP400 I2C Driver (IxI2cDrv) - * - * @version $Revision: 0.1 $ - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @defgroup IxI2cDrv IXP400 I2C Driver(IxI2cDrv) API - * - * @brief IXP400 I2C Driver Public API - * - * @{ - */ -#ifndef IXI2CDRV_H -#define IXI2CDRV_H - -#ifdef __ixp46X -#include "IxOsal.h" - -/* - * Section for #define - */ - -/** - * @ingroup IxI2cDrv - * @brief The interval of micro/mili seconds the IXP will wait before it polls for - * status from the ixI2cIntrXferStatus; Every 20us is 1 byte @ - * 400Kbps and 4 bytes @ 100Kbps. This is dependent on delay type selected - * through the API ixI2cDrvDelayTypeSelect. - */ -#define IX_I2C_US_POLL_FOR_XFER_STATUS 20 - -/** - * @ingroup IxI2cDrv - * @brief The number of tries that will be attempted to call a callback - * function if the callback does not or is unable to resolve the - * issue it is called to resolve - */ -#define IX_I2C_NUM_OF_TRIES_TO_CALL_CALLBACK_FUNC 10 - - -/** - * @ingroup IxI2cDrv - * @brief Number of tries slave will poll the IDBR Rx full bit before it - * gives up - */ -#define IX_I2C_NUM_TO_POLL_IDBR_RX_FULL 0x100 - -/** - * @ingroup IxI2cDrv - * @brief Number of tries slave will poll the IDBR Tx empty bit before it - * gives up - */ -#define IX_I2C_NUM_TO_POLL_IDBR_TX_EMPTY 0x100 - -/* - * Section for enum - */ - -/** - * @ingroup IxI2cDrv - * - * @enum IxI2cMasterStatus - * - * @brief The master status - transfer complete, bus error or arbitration loss - */ -typedef enum -{ - IX_I2C_MASTER_XFER_COMPLETE = IX_SUCCESS, - IX_I2C_MASTER_XFER_BUS_ERROR, - IX_I2C_MASTER_XFER_ARB_LOSS -} IxI2cMasterStatus; - - -/** - * @ingroup IxI2cDrv - * - * @enum IX_I2C_STATUS - * - * @brief The status that can be returned in a I2C driver initialization - */ -typedef enum -{ - IX_I2C_SUCCESS = IX_SUCCESS, /**< Success status */ - IX_I2C_FAIL, /**< Fail status */ - IX_I2C_NOT_SUPPORTED, /**< hardware does not have dedicated I2C hardware */ - IX_I2C_NULL_POINTER, /**< parameter passed in is NULL */ - IX_I2C_INVALID_SPEED_MODE_ENUM_VALUE, /**< speed mode selected is invalid */ - IX_I2C_INVALID_FLOW_MODE_ENUM_VALUE, /**< flow mode selected is invalid */ - IX_I2C_SLAVE_ADDR_CB_MISSING, /**< slave callback is NULL */ - IX_I2C_GEN_CALL_CB_MISSING, /**< general callback is NULL */ - IX_I2C_INVALID_SLAVE_ADDR, /**< invalid slave address specified */ - IX_I2C_INT_BIND_FAIL, /**< interrupt bind fail */ - IX_I2C_INT_UNBIND_FAIL, /**< interrupt unbind fail */ - IX_I2C_NOT_INIT, /**< I2C is not initialized yet */ - IX_I2C_MASTER_BUS_BUSY, /**< master detected a I2C bus busy */ - IX_I2C_MASTER_ARB_LOSS, /**< master experienced arbitration loss */ - IX_I2C_MASTER_XFER_ERROR, /**< master experienced a transfer error */ - IX_I2C_MASTER_BUS_ERROR, /**< master detected a I2C bus error */ - IX_I2C_MASTER_NO_BUFFER, /**< no buffer provided for master transfer */ - IX_I2C_MASTER_INVALID_XFER_MODE, /**< xfer mode selected is invalid */ - IX_I2C_SLAVE_ADDR_NOT_DETECTED, /**< polled slave addr not detected */ - IX_I2C_GEN_CALL_ADDR_DETECTED, /**< polling detected general call */ - IX_I2C_SLAVE_READ_DETECTED, /**< polling detected slave read request */ - IX_I2C_SLAVE_WRITE_DETECTED, /**< polling detected slave write request */ - IX_I2C_SLAVE_NO_BUFFER, /**< no buffer provided for slave transfers */ - IX_I2C_DATA_SIZE_ZERO, /**< data size transfer is zero - invalid */ - IX_I2C_SLAVE_WRITE_BUFFER_EMPTY, /**< slave buffer is used till empty */ - IX_I2C_SLAVE_WRITE_ERROR, /**< slave write experienced an error */ - IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL, /**< slave buffer is filled up */ - IX_I2C_SLAVE_OR_GEN_READ_ERROR /**< slave read experienced an error */ -} IX_I2C_STATUS; - -/** - * @ingroup IxI2cDrv - * - * @enum IxI2cSpeedMode - * - * @brief Type of speed modes supported by the I2C hardware. - */ -typedef enum -{ - IX_I2C_NORMAL_MODE = 0x0, - IX_I2C_FAST_MODE -} IxI2cSpeedMode; - -/** - * @ingroup IxI2cDrv - * - * @enum IxI2cXferMode - * - * @brief Used for indicating it is a repeated start or normal transfer - */ -typedef enum -{ - IX_I2C_NORMAL = 0x0, - IX_I2C_REPEATED_START -} IxI2cXferMode; - -/** - * @ingroup IxI2cDrv - * - * @enum IxI2cFlowMode - * - * @brief Used for indicating it is a poll or interrupt mode - */ -typedef enum -{ - IX_I2C_POLL_MODE = 0x0, - IX_I2C_INTERRUPT_MODE -} IxI2cFlowMode; - -/** - * @ingroup IxI2cDrv - * - * @enum IxI2cDelayMode - * - * @brief Used for selecting looping delay or OS scheduler delay - */ -typedef enum -{ - IX_I2C_LOOP_DELAY = 1, /**< delay in microseconds */ - IX_I2C_SCHED_DELAY /**< delay in miliseconds */ -} IxI2cDelayMode; - -/** - * @ingroup IxI2cDrv - * - * @brief The pointer to the function that will be called when the master - * has completed its receive. The parameter that is passed will - * provide the status of the read (success, arb loss, or bus - * error), the transfer mode (normal or repeated start, the - * buffer pointer and number of bytes transferred. - */ -typedef void (*IxI2cMasterReadCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32); - -/** - * @ingroup IxI2cDrv - * - * @brief The pointer to the function that will be called when the master - * has completed its transmit. The parameter that is passed will - * provide the status of the write (success, arb loss, or buss - * error), the transfer mode (normal or repeated start), the - * buffer pointer and number of bytes transferred. - */ -typedef void (*IxI2cMasterWriteCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32); - -/** - * @ingroup IxI2cDrv - * - * @brief The pointer to the function that will be called when a slave - * address detected in interrupt mode for a read. The parameters - * that is passed will provide the read status, buffer pointer, - * buffer size, and the bytes received. When a start of a read - * is initiated there will be no buffer allocated and this callback - * will be called to request for a buffer. While receiving, if the - * buffer gets filled, this callback will be called to request for - * a new buffer while sending the filled buffer's pointer and size, - * and data size received. When the receive is complete, this - * callback will be called to process the data and free the memory - * by passing the buffer's pointer and size, and data size received. - */ -typedef void (*IxI2cSlaveReadCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); - -/** - * @ingroup IxI2cDrv - * - * @brief The pointer to the function that will be called when a slave - * address detected in interrupt mode for a write. The parameters - * that is passed will provide the write status, buffer pointer, - * buffer size, and the bytes received. When a start of a write is - * initiated there will be no buffer allocated and this callback - * will be called to request for a buffer and to fill it with data. - * While transmitting, if the data in the buffer empties, this - * callback will be called to request for more data to be filled in - * the same or new buffer. When the transmit is complete, this - * callback will be called to free the memory or other actions to - * be taken. - */ -typedef void (*IxI2cSlaveWriteCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); - -/** - * @ingroup IxI2cDrv - * - * @brief The pointer to the function that will be called when a general - * call detected in interrupt mode for a read. The parameters that - * is passed will provide the read status, buffer pointer, buffer - * size, and the bytes received. When a start of a read is - * initiated there will be no buffer allocated and this callback - * will be called to request for a buffer. While receiving, if the - * buffer gets filled, this callback will be called to request for - * a new buffer while sending the filled buffer's pointer and size, - * and data size received. When the receive is complete, this - * callback will be called to process the data and free the memory - * by passing the buffer's pointer and size, and data size received. - */ -typedef void (*IxI2cGenCallCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); - -/* - * Section for struct - */ - -/** - * @brief contains all the variables required to initialize the I2C unit - * - * Structure to be filled and used for calling initialization - */ -typedef struct -{ - IxI2cSpeedMode I2cSpeedSelect; /** - * NOTE: 1) An individual callback is to be registered for each Slave and Master - * Auxiliary Time Stamp registers. Thus to register for both Master and Slave time - * stamp interrupts either the same callback or two separate callbacks the API has - * to be invoked twice. - * 2) On the IXDP465 Development Platform, the Auxiliary Timestamp signal for - * slave mode is tied to GPIO 8 pin. This signal is software routed by default to - * PCI for backwards compatibility with the IXDP425 Development Platform. This - * routing must be disabled for the auxiliary slave time stamp register to work - * properly. The following commands may be used to accomplish this. However, refer - * to the IXDP465 Development Platform Users Guide or the BSP/LSP documentation for - * more specific information. - * - * For Linux (at the Redboot prompt i.e., before loading zImage): - * mfill -b 0x54100000 -1 -l 1 -p 8 - * mfill -b 0x54100001 -1 -l 1 -p 0x7f - * For vxWorks, at the prompt: - * intDisable(25) - * ixdp400FpgaIODetach(8) - * - * - * @li Re-entrant : no - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for callback or - invalid auxiliary snapshot mode - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccAuxTimeInterruptEnable(IxTimeSyncAccAuxMode auxMode, - IxTimeSyncAccAuxTimeCallback auxTimeCallback); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimeInterruptDisable( - IxTimeSyncAccAuxMode auxMode) - * - * @brief Disables the interrupt for the indicated mode of Auxiliary Time Stamp - * in the IEEE 1588 hardware assist block - * - * @param auxMode [in] - Auxiliary time stamp mode (slave or master) using which - * the interrupt will be disabled. - * - * This API will disable the Auxiliary Time Stamp Interrupt (Master or Slave) - * - * @li Re-entrant : yes - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccAuxTimeInterruptDisable(IxTimeSyncAccAuxMode auxMode); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimePoll( - IxTimeSyncAccAuxMode auxMode, - BOOL *auxPollFlag, - IxTimeSyncAccTimeValue *auxTime) - * - * @brief Poll for the Auxiliary Time Stamp captured for the mode indicated - * (Master or Slave) - * - * @param auxMode [in] - Auxiliary Snapshot Register (Slave or Master) to be checked - * @param auxPollFlag [out] - TRUE if the time stamp captured in auxiliary - snapshot register - * FALSE if the time stamp not captured in - auxiliary snapshot register - * @param auxTime [out] - Copy the current Auxiliary Snapshot Register value into the - * client provided buffer - * - * Polls for the Time stamp in the appropriate Auxiliary Snapshot Registers based - * on the mode specified. Return true and the contents of the Auxiliary snapshot, - * if it is available else return false. - * - * Please refer to the note #2 of the API @ref ixTimeSyncAccAuxTimeInterruptEnable - * for more information for Auxiliary Slave mode. - * - * @li Re-entrant : yes - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for auxPollFlag, - callback or invalid auxiliary snapshot mode - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - * @li IX_TIMESYNCACC_INTERRUPTMODEINUSE - Interrupt mode in use - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccAuxTimePoll(IxTimeSyncAccAuxMode auxMode, - BOOL *auxPollFlag, - IxTimeSyncAccTimeValue *auxTime); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn IxTimeSyncAccStatus ixTimeSyncAccReset(void) - * - * @brief Resets the IEEE 1588 hardware assist block - * - * Sets the reset bit in the IEEE1588 silicon which fully resets the silicon block - * - * @li Reentrant : yes - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccReset(void); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn IxTimeSyncAccStatus ixTimeSyncAccStatsGet(IxTimeSyncAccStats - *timeSyncStats) - * - * @brief Returns the IxTimeSyncAcc Statistics in the client supplied buffer - * - * @param timeSyncStats [out] - TimeSync statistics counter values - * - * This API will return the statistics of the received or transmitted messages. - * - * NOTE: 1) These counters are updated only when the client polls for the time - * stamps or interrupt are enabled. This is because the IxTimeSyncAcc module - * does not either transmit or receive messages and does only run the code - * when explicit requests received by client application. - * - * 2) These statistics reflect the number of valid PTP messages exchanged - * in Master and Slave modes but includes all the messages (including valid - * non-PTP messages) while operating in the Any mode. - * - * @li Reentrant : no - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_INVALIDPARAM - NULL parameter passed - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccStatsGet(IxTimeSyncAccStats *timeSyncStats); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn void ixTimeSyncAccStatsReset(void) - * - * @brief Reset Time Sync statistics - * - * This API will reset the statistics counters of the TimeSync access layer. - * - * @li Reentrant : yes - * @li ISR Callable: no - * - * @return @li None - */ -PUBLIC void -ixTimeSyncAccStatsReset(void); - -/** - * @ingroup IxTimeSyncAcc - * - * @fn IxTimeSyncAccStatus ixTimeSyncAccShow(void) - * - * @brief Displays the Time Sync current status - * - * This API will display status on the current configuration of the IEEE - * 1588 hardware assist block, contents of the various time stamp registers, - * outstanding interrupts and/or events. - * - * Note that this is intended for debug only, and in contrast to the other - * functions, it does not clear the any of the status bits associated with - * active timestamps and so is passive in its nature. - * - * @li Reentrant : yes - * @li ISR Callable : no - * - * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful - * @li IX_TIMESYNCACC_FAILED - Internal error occurred - */ -PUBLIC IxTimeSyncAccStatus -ixTimeSyncAccShow(void); - -#endif /* __ixp46X */ -#endif /* IXTIMESYNCACC_H */ - -/** - * @} defgroup IxTimeSyncAcc - */ - diff --git a/arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h b/arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h deleted file mode 100644 index 669dd3e..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxTimerCtrl.h +++ /dev/null @@ -1,263 +0,0 @@ -/** - * @file IxTimerCtrl.h - * @brief - * This is the header file for the Timer Control component. - * - * The timer callback control component provides a mechanism by which different - * client components can start a timer and have a supplied callback function - * invoked when the timer expires. - * The callbacks are all dispatched from one thread inside this component. - * Any component that needs to be called periodically should use this facility - * rather than create its own task with a sleep loop. - * - * @par - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/** - * @defgroup IxTimerCtrl IXP400 Timer Control (IxTimerCtrl) API - * - * @brief The public API for the IXP400 Timer Control Component. - * - * @{ - */ - -#ifndef IxTimerCtrl_H -#define IxTimerCtrl_H - - -#include "IxTypes.h" -/* #include "Ossl.h" */ - -/* - * #defines and macros used in this file. - */ - -/** - * @ingroup IxTimerCtrl - * - * @def IX_TIMERCTRL_NO_FREE_TIMERS - * - * @brief Timer schedule return code. - * - * Indicates that the request to start a timer failed because - * all available timer resources are used. - */ -#define IX_TIMERCTRL_NO_FREE_TIMERS 2 - - -/** - * @ingroup IxTimerCtrl - * - * @def IX_TIMERCTRL_PARAM_ERROR - * - * @brief Timer schedule return code. - * - * Indicates that the request to start a timer failed because - * the client has supplied invalid parameters. - */ -#define IX_TIMERCTRL_PARAM_ERROR 3 - - -/* - * Typedefs whose scope is limited to this file. - */ - -/** - * @ingroup IxTimerCtrl - * - * @brief A typedef for a pointer to a timer callback function. - * @para void * - This parameter is supplied by the client when the - * timer is started and passed back to the client in the callback. - * @note in general timer callback functions should not block or - * take longer than 100ms. This constraint is required to ensure that - * higher priority callbacks are not held up. - * All callbacks are called from the same thread. - * This thread is a shared resource. - * The parameter passed is provided when the timer is scheduled. - */ -typedef void (*IxTimerCtrlTimerCallback)(void *userParam); - - -/** - * @ingroup IxTimerCtrl - * - * @brief List used to identify the users of timers. - * @note The order in this list indicates priority. Components appearing - * higher in the list will be given priority over components lower in the - * list. When adding components, please insert at an appropriate position - * for priority ( i.e values should be less than IxTimerCtrlMaxPurpose ) . - */ -typedef enum -{ - IxTimerCtrlAdslPurpose, - /* Insert new purposes above this line only - */ - IxTimerCtrlMaxPurpose -} -IxTimerCtrlPurpose; - - -/* - * Function definition - */ - -/** - * @ingroup IxTimerCtrl - * - * @fn ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func, - void *userParam, - IxTimerCtrlPurpose purpose, - UINT32 relativeTime, - unsigned *timerId ) - * - * @brief Schedules a callback function to be called after a period of "time". - * The callback function should not block or run for more than 100ms. - * This function - * - * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called. - * @param userParam void [in] - a parameter to send to the callback function, can be NULL. - * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will - * decide the priority of callbacks with different purpose. - * @param relativeTime UINT32 [in] - time relative to now in milliseconds after which the callback - * will be called. The time must be greater than the duration of one OS tick. - * @param *timerId unsigned [out] - An id for the callback scheduled. - * This id can be used to cancel the callback. - * @return - * @li IX_SUCCESS - The timer was started successfully. - * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number - * of running timers has been exceeded. - * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied - * a NULL callback func, or the requested timeout is less than one OS tick. - * @note This function is re-entrant. The function accesses a list of running timers - * and may suspend the calling thread if this list is being accesed by another thread. - */ -PUBLIC IX_STATUS -ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func, - void *userParam, - IxTimerCtrlPurpose purpose, - UINT32 relativeTime, - unsigned *timerId ); - - -/** - * @ingroup IxTimerCtrl - * - * @fn ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func, - void *param, - IxTimerCtrlPurpose purpose, - UINT32 interval, - unsigned *timerId ) - * - * @brief Schedules a callback function to be called after a period of "time". - * The callback function should not block or run for more than 100ms. - * - * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called. - * @param userParam void [in] - a parameter to send to the callback function, can be NULL. - * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will - * decide the priority of callbacks with different purpose. - * @param interval UINT32 [in] - the interval in milliseconds between calls to func. - * @param timerId unsigned [out] - An id for the callback scheduled. - * This id can be used to cancel the callback. - * @return - * @li IX_SUCCESS - The timer was started successfully. - * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number - * of running timers has been exceeded. - * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied - * a NULL callback func, or the requested timeout is less than one OS tick. - * @note This function is re-entrant. The function accesses a list of running timers - * and may suspend the calling thread if this list is being accesed by another thread. - */ -PUBLIC IX_STATUS -ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func, - void *param, - IxTimerCtrlPurpose purpose, - UINT32 interval, - unsigned *timerId ); - -/** - * @ingroup IxTimerCtrl - * - * @fn ixTimerCtrlCancel (unsigned id) - * - * @brief Cancels a scheduled callback. - * - * @param id unsigned [in] - the id of the callback to be cancelled. - * @return - * @li IX_SUCCESS - The timer was successfully stopped. - * @li IX_FAIL - The id parameter did not corrrespond to any running timer.. - * @note This function is re-entrant. The function accesses a list of running timers - * and may suspend the calling thread if this list is being accesed by another thread. - */ -PUBLIC IX_STATUS -ixTimerCtrlCancel (unsigned id); - -/** - * @ingroup IxTimerCtrl - * - * @fn ixTimerCtrlInit(void) - * - * @brief Initialise the Timer Control Component. - * @return - * @li IX_SUCCESS - The timer control component initialized successfully. - * @li IX_FAIL - The timer control component initialization failed, - * or the component was already initialized. - * @note This must be done before any other API function is called. - * This function should be called once only and is not re-entrant. - */ -PUBLIC IX_STATUS -ixTimerCtrlInit(void); - - -/** - * @ingroup IxTimerCtrl - * - * @fn ixTimerCtrlShow( void ) - * - * @brief Display the status of the Timer Control Component. - * @return void - * @note Displays a list of running timers. - * This function is not re-entrant. This function does not suspend the calling thread. - */ -PUBLIC void -ixTimerCtrlShow( void ); - -#endif /* IXTIMERCTRL_H */ - diff --git a/arch/arm/cpu/ixp/npe/include/IxTypes.h b/arch/arm/cpu/ixp/npe/include/IxTypes.h deleted file mode 100644 index c4c5a2d..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxTypes.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @file IxTypes.h (Replaced by OSAL) - * - * @date 28-NOV-2001 - - * @brief This file contains basic types used by the IXP400 software - * - * Design Notes: - * This file shall only include fundamental types and definitions to be - * shared by all the IXP400 components. - * Please DO NOT add component-specific types here. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @defgroup IxTypes IXP400 Types (IxTypes) - * - * @brief Basic data types used by the IXP400 project - * - * @{ - */ - -#ifndef IxTypes_H - -#ifndef __doxygen_HIDE - -#define IxTypes_H - -#endif /* __doxygen_HIDE */ - - -/* WR51880: Undefined data types workaround for backward compatibility */ -#ifdef __linux -#ifndef __INCvxTypesOldh -typedef int (*FUNCPTR)(void); -typedef int STATUS; -#define OK (0) -#define ERROR (-1) -#endif -#endif - -#include "IxOsalBackward.h" - -#endif /* IxTypes_H */ - -/** - * @} addtogroup IxTypes - */ diff --git a/arch/arm/cpu/ixp/npe/include/IxUART.h b/arch/arm/cpu/ixp/npe/include/IxUART.h deleted file mode 100644 index 03a4444..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxUART.h +++ /dev/null @@ -1,458 +0,0 @@ -/** - * @file IxUART.h - * - * @date 12-OCT-01 - * - * @brief Public header for the Intel IXP400 internal UART, generic driver. - * - * Design Notes: - * This driver allows you to perform the following functions: - * Device Initialization, - * send/receive characters. - * - * Perform Uart IOCTL for the following: - * Set/Get the current baud rate, - * set parity, - * set the number of Stop bits, - * set the character Length (5,6,7,8), - * enable/disable Hardware flow control. - * - * Only Polled mode is supported for now. - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- -*/ - -/** - * @defgroup IxUARTAccAPI IXP400 UART Access (IxUARTAcc) API - * - * @brief IXP400 UARTAcc Driver Public API - * - * @{ - */ - - -/* Defaults */ - -/** - * @defgroup DefaultDefines Defines for Default Values - * - * @brief Default values which can be used for UART configuration - * - * @sa ixUARTDev - */ - -/** - * @def IX_UART_DEF_OPTS - * - * @brief The default hardware options to set the UART to - - * no flow control, 8 bit word, 1 stop bit, no parity - * - * @ingroup DefaultDefines - */ -#define IX_UART_DEF_OPTS (CLOCAL | CS8) - -/** - * @def IX_UART_DEF_XMIT - * - * @brief The default UART FIFO size - must be no bigger than 64 - * - * @ingroup DefaultDefines - */ -#define IX_UART_DEF_XMIT 64 - -/** - * @def IX_UART_DEF_BAUD - * - * @brief The default UART baud rate - 9600 - * - * @ingroup DefaultDefines - */ -#define IX_UART_DEF_BAUD 9600 - -/** - * @def IX_UART_MIN_BAUD - * - * @brief The minimum UART baud rate - 9600 - * - * @ingroup DefaultDefines - */ -#define IX_UART_MIN_BAUD 9600 - -/** - * @def IX_UART_MAX_BAUD - * - * @brief The maximum UART baud rate - 926100 - * - * @ingroup DefaultDefines - */ -#define IX_UART_MAX_BAUD 926100 - -/** - * @def IX_UART_XTAL - * - * @brief The UART clock speed - * - * @ingroup DefaultDefines - */ -#define IX_UART_XTAL 14745600 - - - -/* IOCTL commands (Request codes) */ - -/** - * @defgroup IoctlCommandDefines Defines for IOCTL Commands - * - * @brief IOCTL Commands (Request codes) which can be used - * with @ref ixUARTIoctl - */ - - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_BAUD_SET - * - * @brief Set the baud rate - */ -#define IX_BAUD_SET 0 - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_BAUD_GET - * - * @brief Get the baud rate - */ -#define IX_BAUD_GET 1 - -/** - * @ingroup IoctlCommandDefines - * @def IX_MODE_SET - * @brief Set the UART mode of operation - */ -#define IX_MODE_SET 2 - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_MODE_GET - * - * @brief Get the current UART mode of operation - */ -#define IX_MODE_GET 3 - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_OPTS_SET - * - * @brief Set the UART device options - */ -#define IX_OPTS_SET 4 - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_OPTS_GET - * - * @brief Get the UART device options - */ -#define IX_OPTS_GET 5 - -/** - * @ingroup IoctlCommandDefines - * - * @def IX_STATS_GET - * - * @brief Get the UART statistics - */ -#define IX_STATS_GET 6 - - -/* POSIX style ioctl arguments */ - -/** - * @defgroup IoctlArgDefines Defines for IOCTL Arguments - * - * @brief POSIX style IOCTL arguments which can be used - * with @ref ixUARTIoctl - * - * @sa ixUARTMode - */ - - -/** - * @ingroup IoctlArgDefines - * - * @def CLOCAL - * - * @brief Software flow control - */ -#ifdef CLOCAL -#undef CLOCAL -#endif -#define CLOCAL 0x1 - -/** - * @ingroup IoctlArgDefines - * - * @def CREAD - * - * @brief Enable interrupt receiver - */ -#ifdef CREAD -#undef CREAD -#endif -#define CREAD 0x2 - -/** - * @ingroup IoctlArgDefines - * - * @def CSIZE - * - * @brief Characters size - */ -#ifdef CSIZE -#undef CSIZE -#endif -#define CSIZE 0xc - -/** - * @ingroup IoctlArgDefines - * - * @def CS5 - * - * @brief 5 bits - */ -#ifdef CS5 -#undef CS5 -#endif -#define CS5 0x0 - -/** - * @ingroup IoctlArgDefines - * - * @def CS6 - * - * @brief 6 bits - */ -#ifdef CS6 -#undef CS6 -#endif -#define CS6 0x4 - -/** - * @ingroup IoctlArgDefines - * - * @def CS7 - * - * @brief 7 bits - */ -#ifdef CS7 -#undef CS7 -#endif -#define CS7 0x8 - -/** - * @ingroup IoctlArgDefines - * - * @def CS8 - * - * @brief 8 bits - */ -#ifdef CS8 -#undef CS8 -#endif -#define CS8 0xc - -/** - * @ingroup IoctlArgDefines - * - * @def STOPB - * - * @brief Send two stop bits (else one) - */ -#define STOPB 0x20 - -/** - * @ingroup IoctlArgDefines - * - * @def PARENB - * - * @brief Parity detection enabled (else disabled) - */ -#ifdef PARENB -#undef PARENB -#endif -#define PARENB 0x40 - -/** - * @ingroup IoctlArgDefines - * - * @def PARODD - * - * @brief Odd parity (else even) - */ -#ifdef PARODD -#undef PARODD -#endif -#define PARODD 0x80 - -/** - * @enum ixUARTMode - * @brief The mode to set to UART to. - */ -typedef enum -{ - INTERRUPT=0, /**< Interrupt mode */ - POLLED, /**< Polled mode */ - LOOPBACK /**< Loopback mode */ -} ixUARTMode; - -/** - * @struct ixUARTStats - * @brief Statistics for the UART. - */ -typedef struct -{ - UINT32 rxCount; - UINT32 txCount; - UINT32 overrunErr; - UINT32 parityErr; - UINT32 framingErr; - UINT32 breakErr; -} ixUARTStats; - -/** - * @struct ixUARTDev - * @brief Device descriptor for the UART. - */ -typedef struct -{ - UINT8 *addr; /**< device base address */ - ixUARTMode mode; /**< interrupt, polled or loopback */ - int baudRate; /**< baud rate */ - int freq; /**< UART clock frequency */ - int options; /**< hardware options */ - int fifoSize; /**< FIFO xmit size */ - - ixUARTStats stats; /**< device statistics */ -} ixUARTDev; - -/** - * @ingroup IxUARTAccAPI - * - * @fn IX_STATUS ixUARTInit(ixUARTDev* pUART) - * - * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. - * - * @brief Initialise the UART. This puts the chip in a quiescent state. - * - * @pre The base address for the UART must contain a valid value. - * Also the baud rate and hardware options must contain sensible values - * otherwise the defaults will be used as defined in ixUART.h - * - * @post UART is initialized and ready to send and receive data. - * - * @note This function should only be called once per device. - * - * @retval IX_SUCCESS - UART device successfully initialised. - * @retval IX_FAIL - Critical error, device not initialised. - ***************************************************************************/ -PUBLIC IX_STATUS ixUARTInit(ixUARTDev* pUART); - -/** - * @ingroup IxUARTAccAPI - * - * @fn IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar) - * - * @param pUART @ref ixUARTDev [out] - pointer to UART structure describing our device. - * @param outChar int [out] - character to transmit. - * - * @brief Transmit a character in polled mode. - * - * @pre UART device must be initialised. - * - * @retval IX_SUCCESS - character was successfully transmitted. - * @retval IX_FAIL - output buffer is full (try again). - ***************************************************************************/ -PUBLIC IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar); - -/** - * @ingroup IxUARTAccAPI - * - * @fn IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar) - * - * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. - * @param *inChar char [in] - character read from the device. - * - * @brief Receive a character in polled mode. - * - * @pre UART device must be initialised. - * - * @retval IX_SUCCESS - character was successfully read. - * @retval IX_FAIL - input buffer empty (try again). - ***************************************************************************/ -PUBLIC IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar); - -/** - * @ingroup IxUARTAccAPI - * - * @fn IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg) - * - * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. - * @param cmd int [in] - an ioctl request code. - * @param arg void* [in] - optional argument used to set the device mode, - * baud rate, and hardware options. - * - * @brief Perform I/O control routines on the device. - * - * @retval IX_SUCCESS - requested feature was set/read successfully. - * @retval IX_FAIL - error setting/reading the requested feature. - * - * @sa IoctlCommandDefines - * @sa IoctlArgDefines - ***************************************************************************/ -PUBLIC IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg); - -/** - * @} defgroup IxUARTAcc - */ diff --git a/arch/arm/cpu/ixp/npe/include/IxVersionId.h b/arch/arm/cpu/ixp/npe/include/IxVersionId.h deleted file mode 100644 index 27796ed..0000000 --- a/arch/arm/cpu/ixp/npe/include/IxVersionId.h +++ /dev/null @@ -1,155 +0,0 @@ -/** - * @file IxVersionId.h - * - * @date 22-Aug-2002 - * - * @brief This file contains the IXP400 Software version identifier - * - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - */ - -/** - * @defgroup IxVersionId IXP400 Version ID (IxVersionId) - * - * @brief Version Identifiers - * - * @{ - */ - -#ifndef IXVERSIONID_H -#define IXVERSIONID_H - -/** - * @brief Version Identifier String - * - * This string will be updated with each customer release of the IXP400 - * Software. - */ -#define IX_VERSION_ID "2_0" - -/** - * This string will be updated with each customer release of the IXP400 - * ADSL driver package. - */ -#define IX_VERSION_ADSL_ID "1_12" - - -/** - * This string will be updated with each customer release of the IXP400 - * USB Client driver package. - */ -#define IX_VERSION_USBRNDIS_ID "1_9" - -/** - * This string will be updated with each customer release of the IXP400 - * I2C Linux driver package. - */ -#define IX_VERSION_I2C_LINUX_ID "1_0" - -/** - * @brief Linux Ethernet Driver Patch Version Identifier String - * - * This string will be updated with each release of Linux Ethernet Patch - */ -#define LINUX_ETHERNET_DRIVER_PATCH_ID "1_4" - -/** - * @brief Linux Integration Patch Version Identifier String - * - * This String will be updated with each release of Linux Integration Patch - */ -#define LINUX_INTEGRATION_PATCH_ID "1_3" - -/** - * @brief Linux Ethernet Readme version Identifier String - * - * This string will be updated with each release of Linux Ethernet Readme - */ -#define LINUX_ETHERNET_README_ID "1_3" - -/** - * @brief Linux Integration Readme version Identifier String - * - * This string will be updated with each release of Linux Integration Readme - */ - -#define LINUX_INTEGRATION_README_ID "1_3" - -/** - * @brief Linux I2C driver Readme version Identifier String - * - * This string will be updated with each release of Linux I2C Driver Readme - */ -#define LINUX_I2C_DRIVER_README_ID "1_0" - -/** - * @brief ixp425_eth_update_nf_bridge.patch version Identifier String - * - * This string will be updated with each release of ixp425_eth_update_nf_bridge. -patch - * - */ - -#define IXP425_ETH_UPDATE_NF_BRIDGE_ID "1_3" - -/** - * @brief Internal Release Identifier String - * - * This string will be updated with each internal release (SQA drop) - * of the IXP400 Software. - */ -#define IX_VERSION_INTERNAL_ID "SQA3_5" - -/** - * @brief Compatible Tornado Version Identifier - */ -#define IX_VERSION_COMPATIBLE_TORNADO "Tornado2_2_1-PNE2_0" - -/** - * @brief Compatible Linux Version Identifier - */ -#define IX_VERSION_COMPATIBLE_LINUX "MVL3_1" - - -#endif /* IXVERSIONID_H */ - -/** - * @} addtogroup IxVersionId - */ diff --git a/arch/arm/cpu/ixp/npe/include/ix_error.h b/arch/arm/cpu/ixp/npe/include/ix_error.h deleted file mode 100644 index d32ace2..0000000 --- a/arch/arm/cpu/ixp/npe/include/ix_error.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = FILENAME - * ix_error.h (Replaced by OSAL) - * - * = DESCRIPTION - * This file will describe the basic error type and support functions that - * will be used by the IXA SDK Framework API. - * - * = AUTHOR - * Intel Corporation - * - * = CHANGE HISTORY - * 4/22/2002 4:19:03 PM - creation time - * ============================================================================ - */ - -#if !defined(__IX_ERROR_H__) -#define __IX_ERROR_H__ - -#include "IxOsalBackward.h" - -#endif /* end !defined(__IX_ERROR_H__) */ - diff --git a/arch/arm/cpu/ixp/npe/include/ix_macros.h b/arch/arm/cpu/ixp/npe/include/ix_macros.h deleted file mode 100644 index 53f5942..0000000 --- a/arch/arm/cpu/ixp/npe/include/ix_macros.h +++ /dev/null @@ -1,266 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = FILENAME - * ix_macros.h - * - * = DESCRIPTION - * This file will define the basic preprocessor macros that are going to be used - * the IXA SDK Framework API. - * - * = AUTHOR - * Intel Corporation - * - * = CHANGE HISTORY - * 4/22/2002 4:41:05 PM - creation time - * ============================================================================ - */ - -#if !defined(__IX_MACROS_H__) -#define __IX_MACROS_H__ - - -#if defined(__cplusplus) -extern "C" -{ -#endif /* end defined(__cplusplus) */ - - -/** - * MACRO NAME: IX_BIT_FIELD_MASK16 - * - * DESCRIPTION: Builds the mask required to extract the bit field from a 16 bit unsigned integer value. - * - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns a 16 bit mask that will extract the bit field from a 16 bit unsigned integer value. - */ -#define IX_BIT_FIELD_MASK16( \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - ((ix_bit_mask16)((((ix_uint16)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \ - (ix_uint16)1) << arg_FieldLSBBit)) - - - -/** - * MACRO NAME: IX_GET_BIT_FIELD16 - * - * DESCRIPTION: Extracts a bit field from 16 bit unsigned integer. The returned value is normalized in - * in the sense that will be right aligned. - * - * @Param: - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 - - * arg_FieldLSBBit)) - 1. - */ -#define IX_GET_BIT_FIELD16( \ - arg_PackedData16, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (((ix_uint16)(arg_PackedData16) & IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) >> \ - arg_FieldLSBBit) - - -/** - * MACRO NAME: IX_MAKE_BIT_FIELD16 - * - * DESCRIPTION: This macro will create a temporary 16 bit value with the bit field - * desired set to the desired value. - * - * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to - * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns a temporary ix_uint16 value that has the bit field set to the appropriate value. - */ -#define IX_MAKE_BIT_FIELD16( \ - arg_BitFieldValue, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (((ix_uint16)(arg_BitFieldValue) << arg_FieldLSBBit) & \ - IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) - -/** - * MACRO NAME: IX_SET_BIT_FIELD16 - * - * DESCRIPTION: Sets a new value for a bit field from a 16 bit unsigned integer. - * - * @Param: - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest. - * @Param: - IN arg_BitFieldValue is the new vale of the bit field. The value can be from 0 to - * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns the updated value of arg_PackedData16. - */ -#define IX_SET_BIT_FIELD16( \ - arg_PackedData16, \ - arg_BitFieldValue, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (arg_PackedData16 = (((ix_uint16)(arg_PackedData16) & \ - ~(IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit))) | \ - IX_MAKE_BIT_FIELD16(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit))) - - -/** - * MACRO NAME: IX_BIT_FIELD_MASK32 - * - * DESCRIPTION: Builds the mask required to extract the bit field from a 32 bit unsigned integer value. - * - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns a 32 bit mask that will extract the bit field from a 32 bit unsigned integer value. - */ -#define IX_BIT_FIELD_MASK32( \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - ((ix_bit_mask32)((((ix_uint32)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \ - (ix_uint32)1) << arg_FieldLSBBit)) - - - -/** - * MACRO NAME: IX_GET_BIT_FIELD32 - * - * DESCRIPTION: Extracts a bit field from 32 bit unsigned integer. The returned value is normalized in - * in the sense that will be right aligned. - * - * @Param: - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 - - * arg_FieldLSBBit)) - 1. - */ -#define IX_GET_BIT_FIELD32( \ - arg_PackedData32, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (((ix_uint32)(arg_PackedData32) & IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit)) >> \ - arg_FieldLSBBit) - - - - -/** - * MACRO NAME: IX_MAKE_BIT_FIELD32 - * - * DESCRIPTION: This macro will create a temporary 32 bit value with the bit field - * desired set to the desired value. - * - * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to - * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns a temporary ix_uint32 value that has the bit field set to the appropriate value. - */ -#define IX_MAKE_BIT_FIELD32( \ - arg_BitFieldValue, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (((ix_uint32)(arg_BitFieldValue) << arg_FieldLSBBit) & \ - IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit)) - - -/** - * MACRO NAME: IX_SET_BIT_FIELD32 - * - * DESCRIPTION: Sets a new value for a bit field from a 32 bit unsigned integer. - * - * @Param: - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest. - * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to - * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. - * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant - * bit of the bit field. - * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant - * bit of the bit field. - * - * @Return: Returns the updated value of arg_PackedData32. - */ -#define IX_SET_BIT_FIELD32( \ - arg_PackedData32, \ - arg_BitFieldValue, \ - arg_FieldLSBBit, \ - arg_FieldMSBBit \ - ) \ - (arg_PackedData32 = (((ix_uint32)(arg_PackedData32) & \ - ~(IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit))) | \ - IX_MAKE_BIT_FIELD32(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit))) - - - -#if defined(__cplusplus) -} -#endif /* end defined(__cplusplus) */ - -#endif /* end !defined(__IX_MACROS_H__) */ diff --git a/arch/arm/cpu/ixp/npe/include/ix_os_type.h b/arch/arm/cpu/ixp/npe/include/ix_os_type.h deleted file mode 100644 index 8575096..0000000 --- a/arch/arm/cpu/ixp/npe/include/ix_os_type.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = FILENAME - * ix_os_type.h (Replaced by OSAL) - * - * = DESCRIPTION - * This file provides protable symbol definitions for the current OS type. - * - * = AUTHOR - * Intel Corporation - * - * = CHANGE HISTORY - * 4/22/2002 4:43:30 PM - creation time - * ============================================================================ - */ - -#if !defined(__IX_OS_TYPE_H__) -#define __IX_OS_TYPE_H__ - -#include "IxOsalBackward.h" - -#endif /* end !defined(__IX_OS_TYPE_H__) */ - diff --git a/arch/arm/cpu/ixp/npe/include/ix_ossl.h b/arch/arm/cpu/ixp/npe/include/ix_ossl.h deleted file mode 100644 index b59f7d0..0000000 --- a/arch/arm/cpu/ixp/npe/include/ix_ossl.h +++ /dev/null @@ -1,160 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = LIBRARY - * OSSL - Operating System Services Library - * - * = MODULE - * OSSL Abstraction layer header file - * - * = FILENAME - * ix_ossl.h (Replaced by OSAL) - * - * = DESCRIPTION - * This file contains the prototypes of OS-independent wrapper - * functions which allow the programmer not to be tied to a specific - * operating system. The OSSL functions can be divided into three classes: - * - * 1) synchronization-related wrapper functions around thread system calls - * 2) thread-related wrapper functions around thread calls - * 3) transactor/workbench osapi calls -- defined in osApi.h - * - * Both 1 and 2 classes of functions provide Thread Management, Thread - * Synchronization, Mutual Exclusion and Timer primitives. Namely, - * creation and deletion functions as well as the standard "wait" and - * "exit". Additionally, a couple of utility functions which enable to - * pause the execution of a thread are also provided. - * - * The 3rd class provides a slew of other OSAPI functions to handle - * Transactor/WorkBench OS calls. - * - * - * OSSL Thread APIs: - * The OSSL thread functions that allow for thread creation, - * get thread id, thread deletion and set thread priroity. - * - * ix_ossl_thread_create - * ix_ossl_thread_get_id - * ix_ossl_thread_exit - * ix_ossl_thread_kill - * ix_ossl_thread_set_priority - * ix_ossl_thread__delay - * - * OSSL Semaphore APIs: - * The OSSL semaphore functions that allow for initialization, - * posting, waiting and deletion of semaphores. - * - * ix_ossl_sem_init - * ix_ossl_sem_fini - * ix_ossl_sem_take - * ix_ossl_sem_give - * ix_ossl_sem_flush - * - * OSSL Mutex APIs: - * The OSSL wrapper functions that allow for initialization, - * posting, waiting and deletion of mutexes. - * - * ix_ossl_mutex_init - * ix_ossl_mutex_fini - * ix_ossl_mutex_lock - * ix_ossl_mutex_unlock - * - * OSSL Timer APIs: - * The timer APIs provide sleep and get time functions. - * - * ix_ossl_sleep - * ix_ossl_sleep_tick - * ix_ossl_time_get - * - * OSAPIs for Transactor/WorkBench: - * These OSAPI functions are used for transator OS calls. - * They are defined in osApi.h. - * - * Sem_Init - * Sem_Destroy - * Sem_Wait - * Sem_Wait - * Thread_Create - * Thread_Cancel - * Thread_SetPriority - * delayMs - * delayTick - * - * - * - ********************************************************************** - * - * - * = AUTHOR - * Intel Corporation - * - * = ACKNOWLEDGEMENTS - * - * - * = CREATION TIME - * 1/8/2002 1:53:42 PM - * - * = CHANGE HISTORY - * 02/22/2002 : Renamed osapi.h os_api.h - * Moved OS header file includes from OSSL.h to os_api.h - * Moved OS specific datatypes to os_api.h - * Modified data types, macros and functions as per - * 'C' coding guidelines. - * - * - * ============================================================================ - */ - -#ifndef _IX_OSSL_H -#ifndef __doxygen_hide -#define _IX_OSSL_H -#endif /* __doxygen_hide */ - -#include "IxOsalBackward.h" - -#endif /* _IX_OSSL_H */ - -/** - * @} defgroup IxOSSL - */ diff --git a/arch/arm/cpu/ixp/npe/include/ix_symbols.h b/arch/arm/cpu/ixp/npe/include/ix_symbols.h deleted file mode 100644 index f7bb029..0000000 --- a/arch/arm/cpu/ixp/npe/include/ix_symbols.h +++ /dev/null @@ -1,106 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = FILENAME - * ix_symbols.h - * - * = DESCRIPTION - * This file declares all the global preprocessor symbols required by - * the IXA SDK Framework API. - * - * = AUTHOR - * Intel Corporation - * - * = CHANGE HISTORY - * 4/23/2002 10:41:13 AM - creation time - * ============================================================================ - */ - -#if !defined(__IX_SYMBOLS_H__) -#define __IX_SYMBOLS_H__ - - -#if defined(__cplusplus) -extern "C" -{ -#endif /* end defined(__cplusplus) */ - -/** - * The IX_EXPORT_FUNCTION symbol will be used for compilation on different platforms. - * We are planning to provide a simulation version of the library that should work - * with the Transactor rather than the hardware. This implementation will be done on - * WIN32 in the form of a DLL that will need to export functions and symbols. - */ -#if (_IX_OS_TYPE_ == _IX_OS_WIN32_) -# if defined(_IX_LIB_INTERFACE_IMPLEMENTATION_) -# define IX_EXPORT_FUNCTION __declspec( dllexport ) -# elif defined(_IX_LIB_INTERFACE_IMPORT_DLL_) -# define IX_EXPORT_FUNCTION __declspec( dllimport ) -# else -# define IX_EXPORT_FUNCTION extern -# endif -#elif (_IX_OS_TYPE_ == _IX_OS_WINCE_) -# define IX_EXPORT_FUNCTION __declspec(dllexport) -#else -# define IX_EXPORT_FUNCTION extern -#endif - - -/** - * This symbols should be defined when we want to build for a multithreaded environment - */ -#define _IX_MULTI_THREADED_ 1 - - -/** - * This symbol should be defined in the case we to buils for a multithreaded environment - * but we want that our modules to work as if they are used in a single threaded environment. - */ -/* #define _IX_RM_EXPLICIT_SINGLE_THREADED_ 1 */ - -#if defined(__cplusplus) -} -#endif /* end defined(__cplusplus) */ - -#endif /* end !defined(__IX_SYMBOLS_H__) */ diff --git a/arch/arm/cpu/ixp/npe/include/ix_types.h b/arch/arm/cpu/ixp/npe/include/ix_types.h deleted file mode 100644 index fc7b1e9..0000000 --- a/arch/arm/cpu/ixp/npe/include/ix_types.h +++ /dev/null @@ -1,208 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = FILENAME - * ix_types.h - * - * = DESCRIPTION - * This file will define generic types that will guarantee the protability - * between different architectures and compilers. It should be used the entire - * IXA SDK Framework API. - * - * = AUTHOR - * Intel Corporation - * - * = CHANGE HISTORY - * 4/22/2002 4:44:17 PM - creation time - * ============================================================================ - */ - -#if !defined(__IX_TYPES_H__) -#define __IX_TYPES_H__ - - -#if defined(__cplusplus) -extern "C" -{ -#endif /* end defined(__cplusplus) */ - - -/** - * Define generic integral data types that will guarantee the size. - */ - -/** - * TYPENAME: ix_int8 - * - * DESCRIPTION: This type defines an 8 bit signed integer value. - * - */ -typedef signed char ix_int8; - - -/** - * TYPENAME: ix_uint8 - * - * DESCRIPTION: This type defines an 8 bit unsigned integer value. - * - */ -typedef unsigned char ix_uint8; - - -/** - * TYPENAME: ix_int16 - * - * DESCRIPTION: This type defines an 16 bit signed integer value. - * - */ -typedef signed short int ix_int16; - - -/** - * TYPENAME: ix_uint16 - * - * DESCRIPTION: This type defines an 16 bit unsigned integer value. - * - */ -typedef unsigned short int ix_uint16; - - -/** - * TYPENAME: ix_int32 - * - * DESCRIPTION: This type defines an 32 bit signed integer value. - * - */ -typedef signed int ix_int32; - - -/** - * TYPENAME: ix_uint32 - * - * DESCRIPTION: This type defines an 32 bit unsigned integer value. - * - */ -#ifndef __wince -typedef unsigned int ix_uint32; -#else -typedef unsigned long ix_uint32; -#endif - -/** - * TYPENAME: ix_int64 - * - * DESCRIPTION: This type defines an 64 bit signed integer value. - * - */ -#ifndef __wince -__extension__ typedef signed long long int ix_int64; -#endif - -/** - * TYPENAME: ix_uint64 - * - * DESCRIPTION: This type defines an 64 bit unsigned integer value. - * - */ -#ifndef __wince -__extension__ typedef unsigned long long int ix_uint64; -#endif - - -/** - * TYPENAME: ix_bit_mask8 - * - * DESCRIPTION: This is a generic type for a 8 bit mask. - */ -typedef ix_uint8 ix_bit_mask8; - - -/** - * TYPENAME: ix_bit_mask16 - * - * DESCRIPTION: This is a generic type for a 16 bit mask. - */ -typedef ix_uint16 ix_bit_mask16; - - -/** - * TYPENAME: ix_bit_mask32 - * - * DESCRIPTION: This is a generic type for a 32 bit mask. - */ -typedef ix_uint32 ix_bit_mask32; - - -/** - * TYPENAME: ix_bit_mask64 - * - * DESCRIPTION: This is a generic type for a 64 bit mask. - */ -#ifndef __wince -typedef ix_uint64 ix_bit_mask64; -#endif - - -/** - * TYPENAME: ix_handle - * - * DESCRIPTION: This type defines a generic handle. - * - */ -typedef ix_uint32 ix_handle; - - - -/** - * DESCRIPTION: This symbol defines a NULL handle - * - */ -#define IX_NULL_HANDLE ((ix_handle)0) - - -#if defined(__cplusplus) -} -#endif /* end defined(__cplusplus) */ - -#endif /* end !defined(__IX_TYPES_H__) */ diff --git a/arch/arm/cpu/ixp/npe/include/npe.h b/arch/arm/cpu/ixp/npe/include/npe.h deleted file mode 100644 index b5eef86..0000000 --- a/arch/arm/cpu/ixp/npe/include/npe.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * (C) Copyright 2005 - * Stefan Roese, DENX Software Engineering, sr@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef NPE_H -#define NPE_H - -/* - * defines... - */ -#define CONFIG_SYS_NPE_NUMS 1 -#ifdef CONFIG_HAS_ETH1 -#undef CONFIG_SYS_NPE_NUMS -#define CONFIG_SYS_NPE_NUMS 2 -#endif - -#define NPE_NUM_PORTS 3 -#define ACTIVE_PORTS 1 - -#define NPE_PKT_SIZE 1600 - -#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS 64 -#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS 2 - -#define NPE_MBUF_POOL_SIZE \ - ((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS + \ - CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) * \ - sizeof(IX_OSAL_MBUF) * ACTIVE_PORTS) - -#define NPE_PKT_POOL_SIZE \ - ((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS + \ - CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) * \ - NPE_PKT_SIZE * ACTIVE_PORTS) - -#define NPE_MEM_POOL_SIZE (NPE_MBUF_POOL_SIZE + NPE_PKT_POOL_SIZE) - -#define PHY_AUTONEGOTIATE_TIMEOUT 4000 /* 4000 ms autonegotiate timeout */ - -/* - * structs... - */ -struct npe { - u8 active; /* NPE active */ - u8 eth_id; /* IX_ETH_PORT_1 or IX_ETH_PORT_2 */ - u8 phy_no; /* which PHY (0 - 31) */ - u8 mac_address[6]; - - IX_OSAL_MBUF *rxQHead; - IX_OSAL_MBUF *txQHead; - - u8 *tx_pkts; - u8 *rx_pkts; - IX_OSAL_MBUF *rx_mbufs; - IX_OSAL_MBUF *tx_mbufs; - - int print_speed; - - int rx_read; - int rx_write; - int rx_len[PKTBUFSRX]; -}; - -/* - * prototypes... - */ -extern int npe_miiphy_read (const char *devname, unsigned char addr, - unsigned char reg, unsigned short *value); -extern int npe_miiphy_write (const char *devname, unsigned char addr, - unsigned char reg, unsigned short value); - -#endif /* ifndef NPE_H */ diff --git a/arch/arm/cpu/ixp/npe/include/os_datatypes.h b/arch/arm/cpu/ixp/npe/include/os_datatypes.h deleted file mode 100644 index 4387b2a..0000000 --- a/arch/arm/cpu/ixp/npe/include/os_datatypes.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * ============================================================================ - * = COPYRIGHT - * - * @par - * IXP400 SW Release version 2.0 - * - * -- Copyright Notice -- - * - * @par - * Copyright 2001-2005, Intel Corporation. - * All rights reserved. - * - * @par - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * @par - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @par - * -- End of Copyright Notice -- - * = PRODUCT - * Intel(r) IXP425 Software Release - * - * = LIBRARY - * OSSL - Operating System Services Library - * - * = MODULE - * OS Specific Data Types header file - * - * = FILENAME - * OSSL.h (Replaced by OSAL) - * - * = DESCRIPTION - * This file contains definitions and encapsulations for OS specific data types. These - * encapsulated data types are used by OSSL header files and OS API functions. - * - * - ********************************************************************** - * - * - * = AUTHOR - * Intel Corporation - * - * = AKNOWLEDGEMENTS - * - * - * = CREATION TIME - * 1/8/2002 1:53:42 PM - * - * = CHANGE HISTORY - - * ============================================================================ - */ - -#ifndef _OS_DATATYPES_H -#define _OS_DATATYPES_H - -#include "IxOsalBackward.h" - -#endif /* _OS_DATATYPES_H */ - diff --git a/arch/arm/cpu/ixp/npe/miiphy.c b/arch/arm/cpu/ixp/npe/miiphy.c deleted file mode 100644 index a04779a..0000000 --- a/arch/arm/cpu/ixp/npe/miiphy.c +++ /dev/null @@ -1,120 +0,0 @@ -/*-----------------------------------------------------------------------------+ - | This source code is dual-licensed. You may use it under the terms of the - | GNU General Public License version 2, or under the license below. - | - | This source code has been made available to you by IBM on an AS-IS - | basis. Anyone receiving this source is licensed under IBM - | copyrights to use it in any way he or she deems fit, including - | copying it, modifying it, compiling it, and redistributing it either - | with or without modifications. No license under IBM patents or - | patent applications is to be implied by the copyright license. - | - | Any user of this software should understand that IBM cannot provide - | technical support for this software and will not be responsible for - | any consequences resulting from the use of this software. - | - | Any person who transfers this source code or any derivative work - | must include the IBM copyright notice, this paragraph, and the - | preceding two paragraphs in the transferred software. - | - | COPYRIGHT I B M CORPORATION 1995 - | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M - +-----------------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------+ - | - | File Name: miiphy.c - | - | Function: This module has utilities for accessing the MII PHY through - | the EMAC3 macro. - | - | Author: Mark Wisner - | - | Change Activity- - | - | Date Description of Change BY - | --------- --------------------- --- - | 05-May-99 Created MKW - | 01-Jul-99 Changed clock setting of sta_reg from 66MHz to 50MHz to - | better match OPB speed. Also modified delay times. JWB - | 29-Jul-99 Added Full duplex support MKW - | 24-Aug-99 Removed printf from dp83843_duplex() JWB - | 19-Jul-00 Ported to esd cpci405 sr - | 23-Dec-03 Ported from miiphy.c to 440GX Travis Sawyer TBS - | - | - +-----------------------------------------------------------------------------*/ - -#include -#include -#include "IxOsal.h" -#include "IxEthAcc.h" -#include "IxEthAcc_p.h" -#include "IxEthAccMac_p.h" -#include "IxEthAccMii_p.h" - -/***********************************************************/ -/* Dump out to the screen PHY regs */ -/***********************************************************/ - -void miiphy_dump (char *devname, unsigned char addr) -{ - unsigned long i; - unsigned short data; - - - for (i = 0; i < 0x1A; i++) { - if (miiphy_read (devname, addr, i, &data)) { - printf ("read error for reg %lx\n", i); - return; - } - printf ("Phy reg %lx ==> %4x\n", i, data); - - /* jump to the next set of regs */ - if (i == 0x07) - i = 0x0f; - - } /* end for loop */ -} /* end dump */ - - -/***********************************************************/ -/* (Re)start autonegotiation */ -/***********************************************************/ -int phy_setup_aneg (char *devname, unsigned char addr) -{ - unsigned short ctl, adv; - - /* Setup standard advertise */ - miiphy_read (devname, addr, MII_ADVERTISE, &adv); - adv |= (LPA_LPACK | LPA_RFAULT | LPA_100BASE4 | - LPA_100FULL | LPA_100HALF | LPA_10FULL | - LPA_10HALF); - miiphy_write (devname, addr, MII_ADVERTISE, adv); - - /* Start/Restart aneg */ - miiphy_read (devname, addr, MII_BMCR, &ctl); - ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); - miiphy_write (devname, addr, MII_BMCR, ctl); - - return 0; -} - - -int npe_miiphy_read (const char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - u16 val; - - ixEthAccMiiReadRtn(addr, reg, &val); - *value = val; - - return 0; -} /* phy_read */ - - -int npe_miiphy_write (const char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - ixEthAccMiiWriteRtn(addr, reg, value); - return 0; -} /* phy_write */ diff --git a/arch/arm/cpu/ixp/npe/npe.c b/arch/arm/cpu/ixp/npe/npe.c deleted file mode 100644 index 1fe3a95..0000000 --- a/arch/arm/cpu/ixp/npe/npe.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * (C) Copyright 2005-2006 - * Stefan Roese, DENX Software Engineering, sr@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#if 0 -#define DEBUG /* define for debug output */ -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static IxQMgrDispatcherFuncPtr qDispatcherFunc = NULL; -static int npe_exists[NPE_NUM_PORTS]; -static int npe_used[NPE_NUM_PORTS]; - -/* A little extra so we can align to cacheline. */ -static u8 npe_alloc_pool[NPE_MEM_POOL_SIZE + CONFIG_SYS_CACHELINE_SIZE - 1]; -static u8 *npe_alloc_end; -static u8 *npe_alloc_free; - -static void *npe_alloc(int size) -{ - static int count = 0; - void *p = NULL; - - size = (size + (CONFIG_SYS_CACHELINE_SIZE-1)) & ~(CONFIG_SYS_CACHELINE_SIZE-1); - count++; - - if ((npe_alloc_free + size) < npe_alloc_end) { - p = npe_alloc_free; - npe_alloc_free += size; - } else { - printf("npe_alloc: failed (count=%d, size=%d)!\n", count, size); - } - return p; -} - -/* Not interrupt safe! */ -static void mbuf_enqueue(IX_OSAL_MBUF **q, IX_OSAL_MBUF *new) -{ - IX_OSAL_MBUF *m = *q; - - IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(new) = NULL; - - if (m) { - while(IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m)) - m = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m); - IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = new; - } else - *q = new; -} - -/* Not interrupt safe! */ -static IX_OSAL_MBUF *mbuf_dequeue(IX_OSAL_MBUF **q) -{ - IX_OSAL_MBUF *m = *q; - if (m) - *q = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m); - return m; -} - -static void reset_tx_mbufs(struct npe* p_npe) -{ - IX_OSAL_MBUF *m; - int i; - - p_npe->txQHead = NULL; - - for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS; i++) { - m = &p_npe->tx_mbufs[i]; - - memset(m, 0, sizeof(*m)); - - IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->tx_pkts[i * NPE_PKT_SIZE]; - IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; - mbuf_enqueue(&p_npe->txQHead, m); - } -} - -static void reset_rx_mbufs(struct npe* p_npe) -{ - IX_OSAL_MBUF *m; - int i; - - p_npe->rxQHead = NULL; - - HAL_DCACHE_INVALIDATE(p_npe->rx_pkts, NPE_PKT_SIZE * - CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); - - for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS; i++) { - m = &p_npe->rx_mbufs[i]; - - memset(m, 0, sizeof(*m)); - - IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->rx_pkts[i * NPE_PKT_SIZE]; - IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; - - if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) { - printf("ixEthAccPortRxFreeReplenish failed for port %d\n", p_npe->eth_id); - break; - } - } -} - -static void init_rx_mbufs(struct npe* p_npe) -{ - p_npe->rxQHead = NULL; - - p_npe->rx_pkts = npe_alloc(NPE_PKT_SIZE * - CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); - if (p_npe->rx_pkts == NULL) { - printf("alloc of packets failed.\n"); - return; - } - - p_npe->rx_mbufs = (IX_OSAL_MBUF *) - npe_alloc(sizeof(IX_OSAL_MBUF) * - CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); - if (p_npe->rx_mbufs == NULL) { - printf("alloc of mbufs failed.\n"); - return; - } - - reset_rx_mbufs(p_npe); -} - -static void init_tx_mbufs(struct npe* p_npe) -{ - p_npe->tx_pkts = npe_alloc(NPE_PKT_SIZE * - CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS); - if (p_npe->tx_pkts == NULL) { - printf("alloc of packets failed.\n"); - return; - } - - p_npe->tx_mbufs = (IX_OSAL_MBUF *) - npe_alloc(sizeof(IX_OSAL_MBUF) * - CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS); - if (p_npe->tx_mbufs == NULL) { - printf("alloc of mbufs failed.\n"); - return; - } - - reset_tx_mbufs(p_npe); -} - -/* Convert IX_ETH_PORT_n to IX_NPEMH_NPEID_NPEx */ -static int __eth_to_npe(int eth_id) -{ - switch(eth_id) { - case IX_ETH_PORT_1: - return IX_NPEMH_NPEID_NPEB; - - case IX_ETH_PORT_2: - return IX_NPEMH_NPEID_NPEC; - - case IX_ETH_PORT_3: - return IX_NPEMH_NPEID_NPEA; - } - return 0; -} - -/* Poll the CSR machinery. */ -static void npe_poll(int eth_id) -{ - if (qDispatcherFunc != NULL) { - ixNpeMhMessagesReceive(__eth_to_npe(eth_id)); - (*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP); - } -} - -/* ethAcc RX callback */ -static void npe_rx_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid) -{ - struct npe* p_npe = (struct npe *)cbTag; - - if (IX_OSAL_MBUF_MLEN(m) > 0) { - mbuf_enqueue(&p_npe->rxQHead, m); - - if (p_npe->rx_write == ((p_npe->rx_read-1) & (PKTBUFSRX-1))) { - debug("Rx overflow: rx_write=%d rx_read=%d\n", - p_npe->rx_write, p_npe->rx_read); - } else { - debug("Received message #%d (len=%d)\n", p_npe->rx_write, - IX_OSAL_MBUF_MLEN(m)); - memcpy((void *)NetRxPackets[p_npe->rx_write], IX_OSAL_MBUF_MDATA(m), - IX_OSAL_MBUF_MLEN(m)); - p_npe->rx_len[p_npe->rx_write] = IX_OSAL_MBUF_MLEN(m); - p_npe->rx_write++; - if (p_npe->rx_write == PKTBUFSRX) - p_npe->rx_write = 0; - -#ifdef CONFIG_PRINT_RX_FRAMES - { - u8 *ptr = IX_OSAL_MBUF_MDATA(m); - int i; - - for (i=0; i<60; i++) { - debug("%02x ", *ptr++); - } - debug("\n"); - } -#endif - } - - m = mbuf_dequeue(&p_npe->rxQHead); - } else { - debug("Received frame with length 0!!!\n"); - m = mbuf_dequeue(&p_npe->rxQHead); - } - - /* Now return mbuf to NPE */ - IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL; - IX_OSAL_MBUF_FLAGS(m) = 0; - - if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) { - debug("npe_rx_callback: Error returning mbuf.\n"); - } -} - -/* ethAcc TX callback */ -static void npe_tx_callback(u32 cbTag, IX_OSAL_MBUF *m) -{ - struct npe* p_npe = (struct npe *)cbTag; - - debug("%s\n", __FUNCTION__); - - IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; - IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL; - IX_OSAL_MBUF_FLAGS(m) = 0; - - mbuf_enqueue(&p_npe->txQHead, m); -} - - -static int npe_set_mac_address(struct eth_device *dev) -{ - struct npe *p_npe = (struct npe *)dev->priv; - IxEthAccMacAddr npeMac; - - debug("%s\n", __FUNCTION__); - - /* Set MAC address */ - memcpy(npeMac.macAddress, dev->enetaddr, 6); - - if (ixEthAccPortUnicastMacAddressSet(p_npe->eth_id, &npeMac) != IX_ETH_ACC_SUCCESS) { - printf("Error setting unicast address! %02x:%02x:%02x:%02x:%02x:%02x\n", - npeMac.macAddress[0], npeMac.macAddress[1], - npeMac.macAddress[2], npeMac.macAddress[3], - npeMac.macAddress[4], npeMac.macAddress[5]); - return 0; - } - - return 1; -} - -/* Boot-time CSR library initialization. */ -static int npe_csr_load(void) -{ - int i; - - if (ixQMgrInit() != IX_SUCCESS) { - debug("Error initialising queue manager!\n"); - return 0; - } - - ixQMgrDispatcherLoopGet(&qDispatcherFunc); - - if(ixNpeMhInitialize(IX_NPEMH_NPEINTERRUPTS_YES) != IX_SUCCESS) { - printf("Error initialising NPE Message handler!\n"); - return 0; - } - - if (npe_used[IX_ETH_PORT_1] && npe_exists[IX_ETH_PORT_1] && - ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS) - != IX_SUCCESS) { - printf("Error downloading firmware to NPE-B!\n"); - return 0; - } - - if (npe_used[IX_ETH_PORT_2] && npe_exists[IX_ETH_PORT_2] && - ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS) - != IX_SUCCESS) { - printf("Error downloading firmware to NPE-C!\n"); - return 0; - } - - /* don't need this for U-Boot */ - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, FALSE); - - if (ixEthAccInit() != IX_ETH_ACC_SUCCESS) { - printf("Error initialising Ethernet access driver!\n"); - return 0; - } - - for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) { - if (!npe_used[i] || !npe_exists[i]) - continue; - if (ixEthAccPortInit(i) != IX_ETH_ACC_SUCCESS) { - printf("Error initialising Ethernet port%d!\n", i); - } - if (ixEthAccTxSchedulingDisciplineSet(i, FIFO_NO_PRIORITY) != IX_ETH_ACC_SUCCESS) { - printf("Error setting scheduling discipline for port %d.\n", i); - } - if (ixEthAccPortRxFrameAppendFCSDisable(i) != IX_ETH_ACC_SUCCESS) { - printf("Error disabling RX FCS for port %d.\n", i); - } - if (ixEthAccPortTxFrameAppendFCSEnable(i) != IX_ETH_ACC_SUCCESS) { - printf("Error enabling TX FCS for port %d.\n", i); - } - } - - return 1; -} - -static int npe_init(struct eth_device *dev, bd_t * bis) -{ - struct npe *p_npe = (struct npe *)dev->priv; - int i; - u16 reg_short; - int speed; - int duplex; - - debug("%s: 1\n", __FUNCTION__); - -#ifdef CONFIG_MII_NPE0_FIXEDLINK - if (0 == p_npe->eth_id) { - speed = CONFIG_MII_NPE0_SPEED; - duplex = CONFIG_MII_NPE0_FULLDUPLEX ? FULL : HALF; - } else -#endif -#ifdef CONFIG_MII_NPE1_FIXEDLINK - if (1 == p_npe->eth_id) { - speed = CONFIG_MII_NPE1_SPEED; - duplex = CONFIG_MII_NPE1_FULLDUPLEX ? FULL : HALF; - } else -#endif - { - miiphy_read(dev->name, p_npe->phy_no, MII_BMSR, ®_short); - - /* - * Wait if PHY is capable of autonegotiation and - * autonegotiation is not complete - */ - if ((reg_short & BMSR_ANEGCAPABLE) && - !(reg_short & BMSR_ANEGCOMPLETE)) { - puts("Waiting for PHY auto negotiation to complete"); - i = 0; - while (!(reg_short & BMSR_ANEGCOMPLETE)) { - /* - * Timeout reached ? - */ - if (i > PHY_AUTONEGOTIATE_TIMEOUT) { - puts(" TIMEOUT !\n"); - break; - } - - if ((i++ % 1000) == 0) { - putc('.'); - miiphy_read(dev->name, p_npe->phy_no, - MII_BMSR, ®_short); - } - udelay(1000); /* 1 ms */ - } - puts(" done\n"); - /* another 500 ms (results in faster booting) */ - udelay(500000); - } - speed = miiphy_speed(dev->name, p_npe->phy_no); - duplex = miiphy_duplex(dev->name, p_npe->phy_no); - } - - if (p_npe->print_speed) { - p_npe->print_speed = 0; - printf ("ENET Speed is %d Mbps - %s duplex connection\n", - (int) speed, (duplex == HALF) ? "HALF" : "FULL"); - } - - npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool); - npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool + - CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1)); - - /* initialize mbuf pool */ - init_rx_mbufs(p_npe); - init_tx_mbufs(p_npe); - - if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_callback, - (u32)p_npe) != IX_ETH_ACC_SUCCESS) { - printf("can't register RX callback!\n"); - return -1; - } - - if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_callback, - (u32)p_npe) != IX_ETH_ACC_SUCCESS) { - printf("can't register TX callback!\n"); - return -1; - } - - npe_set_mac_address(dev); - - if (ixEthAccPortEnable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) { - printf("can't enable port!\n"); - return -1; - } - - p_npe->active = 1; - - return 0; -} - -#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */ -/* Uninitialize CSR library. */ -static void npe_csr_unload(void) -{ - ixEthAccUnload(); - ixEthDBUnload(); - ixNpeMhUnload(); - ixQMgrUnload(); -} - -/* callback which is used by ethAcc to recover RX buffers when stopping */ -static void npe_rx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid) -{ - debug("%s\n", __FUNCTION__); -} - -/* callback which is used by ethAcc to recover TX buffers when stopping */ -static void npe_tx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m) -{ - debug("%s\n", __FUNCTION__); -} -#endif - -static void npe_halt(struct eth_device *dev) -{ - struct npe *p_npe = (struct npe *)dev->priv; - int i; - - debug("%s\n", __FUNCTION__); - - /* Delay to give time for recovery of mbufs */ - for (i = 0; i < 100; i++) { - npe_poll(p_npe->eth_id); - udelay(100); - } - -#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */ - if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_stop_callback, - (u32)p_npe) != IX_ETH_ACC_SUCCESS) { - debug("Error registering rx callback!\n"); - } - - if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_stop_callback, - (u32)p_npe) != IX_ETH_ACC_SUCCESS) { - debug("Error registering tx callback!\n"); - } - - if (ixEthAccPortDisable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) { - debug("npe_stop: Error disabling NPEB!\n"); - } - - /* Delay to give time for recovery of mbufs */ - for (i = 0; i < 100; i++) { - npe_poll(p_npe->eth_id); - udelay(10000); - } - - /* - * For U-Boot only, we are probably launching Linux or other OS that - * needs a clean slate for its NPE library. - */ -#if 0 /* test-only */ - for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) { - if (npe_used[i] && npe_exists[i]) - if (ixNpeDlNpeStopAndReset(__eth_to_npe(i)) != IX_SUCCESS) - printf("Failed to stop and reset NPE B.\n"); - } -#endif - -#endif - p_npe->active = 0; -} - - -static int npe_send(struct eth_device *dev, void *packet, int len) -{ - struct npe *p_npe = (struct npe *)dev->priv; - u8 *dest; - int err; - IX_OSAL_MBUF *m; - - debug("%s\n", __FUNCTION__); - m = mbuf_dequeue(&p_npe->txQHead); - dest = IX_OSAL_MBUF_MDATA(m); - IX_OSAL_MBUF_PKT_LEN(m) = IX_OSAL_MBUF_MLEN(m) = len; - IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = NULL; - - memcpy(dest, (char *)packet, len); - - if ((err = ixEthAccPortTxFrameSubmit(p_npe->eth_id, m, IX_ETH_ACC_TX_DEFAULT_PRIORITY)) - != IX_ETH_ACC_SUCCESS) { - printf("npe_send: Can't submit frame. err[%d]\n", err); - mbuf_enqueue(&p_npe->txQHead, m); - return 0; - } - -#ifdef DEBUG_PRINT_TX_FRAMES - { - u8 *ptr = IX_OSAL_MBUF_MDATA(m); - int i; - - for (i=0; ieth_id); - - return len; -} - -static int npe_rx(struct eth_device *dev) -{ - struct npe *p_npe = (struct npe *)dev->priv; - - debug("%s\n", __FUNCTION__); - npe_poll(p_npe->eth_id); - - debug("%s: rx_write=%d rx_read=%d\n", __FUNCTION__, p_npe->rx_write, p_npe->rx_read); - while (p_npe->rx_write != p_npe->rx_read) { - debug("Reading message #%d\n", p_npe->rx_read); - NetReceive(NetRxPackets[p_npe->rx_read], p_npe->rx_len[p_npe->rx_read]); - p_npe->rx_read++; - if (p_npe->rx_read == PKTBUFSRX) - p_npe->rx_read = 0; - } - - return 0; -} - -int npe_initialize(bd_t * bis) -{ - static int virgin = 0; - struct eth_device *dev; - int eth_num = 0; - struct npe *p_npe = NULL; - uchar enetaddr[6]; - - for (eth_num = 0; eth_num < CONFIG_SYS_NPE_NUMS; eth_num++) { - - /* See if we can actually bring up the interface, otherwise, skip it */ -#ifdef CONFIG_HAS_ETH1 - if (eth_num == 1) { - if (!eth_getenv_enetaddr("eth1addr", enetaddr)) - continue; - } else -#endif - if (!eth_getenv_enetaddr("ethaddr", enetaddr)) - continue; - - /* Allocate device structure */ - dev = (struct eth_device *)malloc(sizeof(*dev)); - if (dev == NULL) { - printf ("%s: Cannot allocate eth_device %d\n", __FUNCTION__, eth_num); - return -1; - } - memset(dev, 0, sizeof(*dev)); - - /* Allocate our private use data */ - p_npe = (struct npe *)malloc(sizeof(struct npe)); - if (p_npe == NULL) { - printf("%s: Cannot allocate private hw data for eth_device %d", - __FUNCTION__, eth_num); - free(dev); - return -1; - } - memset(p_npe, 0, sizeof(struct npe)); - - p_npe->eth_id = eth_num; - memcpy(dev->enetaddr, enetaddr, 6); -#ifdef CONFIG_HAS_ETH1 - if (eth_num == 1) - p_npe->phy_no = CONFIG_PHY1_ADDR; - else -#endif - p_npe->phy_no = CONFIG_PHY_ADDR; - - sprintf(dev->name, "NPE%d", eth_num); - dev->priv = (void *)p_npe; - dev->init = npe_init; - dev->halt = npe_halt; - dev->send = npe_send; - dev->recv = npe_rx; - - p_npe->print_speed = 1; - - if (0 == virgin) { - virgin = 1; - - if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X) { - switch (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) { - case IX_FEATURE_CTRL_SILICON_TYPE_B0: - default: /* newer than B0 */ - /* - * If it is B0 or newer Silicon, we - * only enable port when its - * corresponding Eth Coprocessor is - * available. - */ - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == - IX_FEATURE_CTRL_COMPONENT_ENABLED) - npe_exists[IX_ETH_PORT_1] = TRUE; - - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == - IX_FEATURE_CTRL_COMPONENT_ENABLED) - npe_exists[IX_ETH_PORT_2] = TRUE; - break; - case IX_FEATURE_CTRL_SILICON_TYPE_A0: - /* - * If it is A0 Silicon, we enable both as both Eth Coprocessors - * are available. - */ - npe_exists[IX_ETH_PORT_1] = TRUE; - npe_exists[IX_ETH_PORT_2] = TRUE; - break; - } - } else if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X) { - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == - IX_FEATURE_CTRL_COMPONENT_ENABLED) - npe_exists[IX_ETH_PORT_1] = TRUE; - - if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == - IX_FEATURE_CTRL_COMPONENT_ENABLED) - npe_exists[IX_ETH_PORT_2] = TRUE; - } - - npe_used[IX_ETH_PORT_1] = 1; - npe_used[IX_ETH_PORT_2] = 1; - - npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool); - npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool + - CONFIG_SYS_CACHELINE_SIZE - 1) - & ~(CONFIG_SYS_CACHELINE_SIZE - 1)); - - if (!npe_csr_load()) - return 0; - } - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - miiphy_register(dev->name, npe_miiphy_read, npe_miiphy_write); -#endif - - } /* end for each supported device */ - - return 1; -} diff --git a/drivers/net/npe/IxEthAcc.c b/drivers/net/npe/IxEthAcc.c new file mode 100644 index 0000000..20d3d9e --- /dev/null +++ b/drivers/net/npe/IxEthAcc.c @@ -0,0 +1,261 @@ +/** + * @file IxEthAcc.c + * + * @author Intel Corporation + * @date 20-Feb-2001 + * + * @brief This file contains the implementation of the IXP425 Ethernet Access Component + * + * Design Notes: + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + + + +#include "IxEthAcc.h" +#ifdef CONFIG_IXP425_COMPONENT_ETHDB +#include "IxEthDB.h" +#endif +#include "IxFeatureCtrl.h" + +#include "IxEthAcc_p.h" +#include "IxEthAccMac_p.h" +#include "IxEthAccMii_p.h" + +/** + * @addtogroup IxEthAcc + *@{ + */ + + +/** + * @brief System-wide information data strucure. + * + * @ingroup IxEthAccPri + * + */ + +IxEthAccInfo ixEthAccDataInfo; +extern PUBLIC IxEthAccMacState ixEthAccMacState[]; +extern PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex; + +/** + * @brief System-wide information + * + * @ingroup IxEthAccPri + * + */ +BOOL ixEthAccServiceInit = FALSE; + +/* global filtering bit mask */ +PUBLIC UINT32 ixEthAccNewSrcMask; + +/** + * @brief Per port information data strucure. + * + * @ingroup IxEthAccPri + * + */ + +IxEthAccPortDataInfo ixEthAccPortData[IX_ETH_ACC_NUMBER_OF_PORTS]; + +PUBLIC IxEthAccStatus ixEthAccInit() +{ +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + /* + * Initialize Control plane + */ + if (ixEthDBInit() != IX_ETH_DB_SUCCESS) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccInit: EthDB init failed\n", 0, 0, 0, 0, 0, 0); + + return IX_ETH_ACC_FAIL; + } +#endif + + if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING)) + { + ixEthAccNewSrcMask = (~0); /* want all the bits */ + } + else + { + ixEthAccNewSrcMask = (~IX_ETHACC_NE_NEWSRCMASK); /* want all but the NewSrc bit */ + } + + /* + * Initialize Data plane + */ + if ( ixEthAccInitDataPlane() != IX_ETH_ACC_SUCCESS ) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccInit: data plane init failed\n", 0, 0, 0, 0, 0, 0); + + return IX_ETH_ACC_FAIL; + } + + + if ( ixEthAccQMgrQueuesConfig() != IX_ETH_ACC_SUCCESS ) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccInit: queue config failed\n", 0, 0, 0, 0, 0, 0); + + return IX_ETH_ACC_FAIL; + } + + /* + * Initialize MII + */ + if ( ixEthAccMiiInit() != IX_ETH_ACC_SUCCESS ) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mii init failed\n", 0, 0, 0, 0, 0, 0); + + return IX_ETH_ACC_FAIL; + } + + /* + * Initialize MAC I/O memory + */ + if (ixEthAccMacMemInit() != IX_ETH_ACC_SUCCESS) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Mac init failed\n", 0, 0, 0, 0, 0, 0); + + return IX_ETH_ACC_FAIL; + } + + /* + * Initialize control plane interface lock + */ + if (ixOsalMutexInit(&ixEthAccControlInterfaceMutex) != IX_SUCCESS) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccInit: Control plane interface lock initialization failed\n", 0, 0, 0, 0, 0, 0); + + return IX_ETH_ACC_FAIL; + } + + /* initialiasation is complete */ + ixEthAccServiceInit = TRUE; + + return IX_ETH_ACC_SUCCESS; + +} + +PUBLIC void ixEthAccUnload(void) +{ + IxEthAccPortId portId; + + if ( IX_ETH_ACC_IS_SERVICE_INITIALIZED() ) + { + /* check none of the port is still active */ + for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + if ( IX_ETH_IS_PORT_INITIALIZED(portId) ) + { + if (ixEthAccMacState[portId].portDisableState == ACTIVE) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccUnload: port %u still active, bail out\n", portId, 0, 0, 0, 0, 0); + return; + } + } + } + + /* unmap the memory areas */ + ixEthAccMiiUnload(); + ixEthAccMacUnload(); + + /* set all ports as uninitialized */ + for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + ixEthAccPortData[portId].portInitialized = FALSE; + } + + /* uninitialize the service */ + ixEthAccServiceInit = FALSE; + } +} + +PUBLIC IxEthAccStatus ixEthAccPortInit( IxEthAccPortId portId) +{ + + IxEthAccStatus ret=IX_ETH_ACC_SUCCESS; + + if ( ! IX_ETH_ACC_IS_SERVICE_INITIALIZED() ) + { + return(IX_ETH_ACC_FAIL); + } + + /* + * Check for valid port + */ + + if ( ! IX_ETH_ACC_IS_PORT_VALID(portId) ) + { + return (IX_ETH_ACC_INVALID_PORT); + } + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Eth port.\n",(INT32) portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if ( IX_ETH_IS_PORT_INITIALIZED(portId) ) + { + /* Already initialized */ + return(IX_ETH_ACC_FAIL); + } + + if(ixEthAccMacInit(portId)!=IX_ETH_ACC_SUCCESS) + { + return IX_ETH_ACC_FAIL; + } + + /* + * Set the port init flag. + */ + + ixEthAccPortData[portId].portInitialized = TRUE; + +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + /* init learning/filtering database structures for this port */ + ixEthDBPortInit(portId); +#endif + + return(ret); +} + + diff --git a/drivers/net/npe/IxEthAccCommon.c b/drivers/net/npe/IxEthAccCommon.c new file mode 100644 index 0000000..211203d --- /dev/null +++ b/drivers/net/npe/IxEthAccCommon.c @@ -0,0 +1,1049 @@ +/** + * @file IxEthAccCommon.c + * + * @author Intel Corporation + * @date 12-Feb-2002 + * + * @brief This file contains the implementation common support routines for the component + * + * Design Notes: + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/* + * Component header files + */ + +#include "IxOsal.h" +#include "IxEthAcc.h" +#include "IxEthDB.h" +#include "IxNpeMh.h" +#include "IxEthDBPortDefs.h" +#include "IxFeatureCtrl.h" +#include "IxEthAcc_p.h" +#include "IxEthAccQueueAssign_p.h" + +#include "IxEthAccDataPlane_p.h" +#include "IxEthAccMii_p.h" + +/** + * @addtogroup IxEthAccPri + *@{ + */ + +extern IxEthAccInfo ixEthAccDataInfo; + +/** + * + * @brief Maximum number of RX queues set to be the maximum number + * of traffic calsses. + * + */ +#define IX_ETHACC_MAX_RX_QUEUES \ + (IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY \ + - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY \ + + 1) + +/** + * + * @brief Maximum number of 128 entry RX queues + * + */ +#define IX_ETHACC_MAX_LARGE_RX_QUEUES 4 + +/** + * + * @brief Data structure template for Default RX Queues + * + */ +IX_ETH_ACC_PRIVATE +IxEthAccQregInfo ixEthAccQmgrRxDefaultTemplate = + { + IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */ + "Eth Rx Q", + ixEthRxFrameQMCallback, /**< Functional callback */ + (IxQMgrCallbackId) 0, /**< Callback tag */ + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + TRUE, /**< Enable Q notification at startup */ + IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */ + }; + +/** + * + * @brief Data structure template for Small RX Queues + * + */ +IX_ETH_ACC_PRIVATE +IxEthAccQregInfo ixEthAccQmgrRxSmallTemplate = + { + IX_ETH_ACC_RX_FRAME_ETH_Q, /**< Queue ID */ + "Eth Rx Q", + ixEthRxFrameQMCallback, /**< Functional callback */ + (IxQMgrCallbackId) 0, /**< Callback tag */ + IX_QMGR_Q_SIZE64, /**< Allocate Smaller Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + TRUE, /**< Enable Q notification at startup */ + IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE,/**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL1, /**< Q High water mark - needed by NPE */ + }; + + +/** + * + * @brief Data structure used to register & initialize the Queues + * + */ +IX_ETH_ACC_PRIVATE +IxEthAccQregInfo ixEthAccQmgrStaticInfo[]= +{ + { + IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q, + "Eth Rx Fr Q 1", + ixEthRxFreeQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_1, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + FALSE, /**< Disable Q notification at startup */ + IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /***< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ + }, + + { + IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q, + "Eth Rx Fr Q 2", + ixEthRxFreeQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_2, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + FALSE, /**< Disable Q notification at startup */ + IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ + }, +#ifdef __ixp46X + { + IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q, + "Eth Rx Fr Q 3", + ixEthRxFreeQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_3, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + FALSE, /**< Disable Q notification at startup */ + IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ + }, +#endif + { + IX_ETH_ACC_TX_FRAME_ENET0_Q, + "Eth Tx Q 1", + ixEthTxFrameQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_1, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + FALSE, /**< Disable Q notification at startup */ + IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ + }, + + { + IX_ETH_ACC_TX_FRAME_ENET1_Q, + "Eth Tx Q 2", + ixEthTxFrameQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_2, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + FALSE, /**< Disable Q notification at startup */ + IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL64, /**< Q High water mark */ + }, +#ifdef __ixp46X + { + IX_ETH_ACC_TX_FRAME_ENET2_Q, + "Eth Tx Q 3", + ixEthTxFrameQMCallback, + (IxQMgrCallbackId) IX_ETH_PORT_3, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /** Queue Entry Sizes - all Q entries are single ord entries */ + FALSE, /** Disable Q notification at startup */ + IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE, /** Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /* No queues use almost empty */ + IX_QMGR_Q_WM_LEVEL64, /** Q High water mark - needed used */ + }, +#endif + { + IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, + "Eth Tx Done Q", + ixEthTxFrameDoneQMCallback, + (IxQMgrCallbackId) 0, + IX_QMGR_Q_SIZE128, /**< Allocate Max Size Q */ + IX_QMGR_Q_ENTRY_SIZE1, /**< Queue Entry Sizes - all Q entries are single word entries */ + TRUE, /**< Enable Q notification at startup */ + IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE, /**< Q Condition to drive callback */ + IX_QMGR_Q_WM_LEVEL0, /**< Q Low water mark */ + IX_QMGR_Q_WM_LEVEL2, /**< Q High water mark - needed by NPE */ + }, + + { /* Null Termination entry + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + } + +}; + +/** + * + * @brief Data structure used to register & initialize the Queues + * + * The structure will be filled at run time depending on the NPE + * image already loaded and the QoS configured in ethDB. + * + */ +IX_ETH_ACC_PRIVATE +IxEthAccQregInfo ixEthAccQmgrRxQueuesInfo[IX_ETHACC_MAX_RX_QUEUES+1]= +{ + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* PlaceHolder for rx queues + * depending on the QoS configured + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + }, + + { /* Null Termination entry + */ + (IxQMgrQId)0, + (char *) NULL, + (IxQMgrCallback) NULL, + (IxQMgrCallbackId) 0, + 0, + 0, + 0, + 0, + 0, + 0 + } + +}; + +/* forward declarations */ +IX_ETH_ACC_PRIVATE IxEthAccStatus +ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes); + +/** + * @fn ixEthAccQMgrQueueSetup(void) + * + * @brief Setup one queue and its event, and register the callback required + * by this component to the QMgr + * + * @internal + */ +IX_ETH_ACC_PRIVATE IxEthAccStatus +ixEthAccQMgrQueueSetup(IxEthAccQregInfo *qInfoDes) +{ + /* + * Configure each Q. + */ + if ( ixQMgrQConfig( qInfoDes->qName, + qInfoDes->qId, + qInfoDes->qSize, + qInfoDes->qWords) != IX_SUCCESS) + { + return IX_ETH_ACC_FAIL; + } + + if ( ixQMgrWatermarkSet( qInfoDes->qId, + qInfoDes->AlmostEmptyThreshold, + qInfoDes->AlmostFullThreshold + ) != IX_SUCCESS) + { + return IX_ETH_ACC_FAIL; + } + + /* + * Set dispatcher priority. + */ + if ( ixQMgrDispatcherPrioritySet( qInfoDes->qId, + IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY) + != IX_SUCCESS) + { + return IX_ETH_ACC_FAIL; + } + + /* + * Register callbacks for each Q. + */ + if ( ixQMgrNotificationCallbackSet(qInfoDes->qId, + qInfoDes->qCallback, + qInfoDes->callbackTag) + != IX_SUCCESS ) + { + return IX_ETH_ACC_FAIL; + } + + /* + * Set notification condition for Q + */ + if ( qInfoDes->qNotificationEnableAtStartup == TRUE ) + { + if ( ixQMgrNotificationEnable(qInfoDes->qId, + qInfoDes->qConditionSource) + != IX_SUCCESS ) + { + return IX_ETH_ACC_FAIL; + } + } + + return(IX_ETH_ACC_SUCCESS); +} + +/** + * @fn ixEthAccQMgrQueuesConfig(void) + * + * @brief Setup all the queues and register all callbacks required + * by this component to the QMgr + * + * The RxFree queues, tx queues, rx queues are configured statically + * + * Rx queues configuration is driven by QoS setup. + * Many Rx queues may be required when QoS is enabled (this depends + * on IxEthDB setup and the images being downloaded). The configuration + * of the rxQueues is done in many steps as follows: + * + * @li select all Rx queues as configured by ethDB for all ports + * @li sort the queues by traffic class + * @li build the priority dependency for all queues + * @li fill the configuration for all rx queues + * @li configure all statically configured queues + * @li configure all dynamically configured queues + * + * @param none + * + * @return IxEthAccStatus + * + * @internal + */ +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccQMgrQueuesConfig(void) +{ + struct + { + int npeCount; + UINT32 npeId; + IxQMgrQId qId; + IxEthDBProperty trafficClass; + } rxQueues[IX_ETHACC_MAX_RX_QUEUES]; + + UINT32 rxQueue = 0; + UINT32 rxQueueCount = 0; + IxQMgrQId ixQId =IX_QMGR_MAX_NUM_QUEUES; + IxEthDBStatus ixEthDBStatus = IX_ETH_DB_SUCCESS; + IxEthDBPortId ixEthDbPortId = 0; + IxEthAccPortId ixEthAccPortId = 0; + UINT32 ixNpeId = 0; + UINT32 ixHighestNpeId = 0; + UINT32 sortIterations = 0; + IxEthAccStatus ret = IX_ETH_ACC_SUCCESS; + IxEthAccQregInfo *qInfoDes = NULL; + IxEthDBProperty ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; + IxEthDBPropertyType ixEthDBPropertyType = IX_ETH_DB_INTEGER_PROPERTY; + UINT32 ixEthDBParameter = 0; + BOOL completelySorted = FALSE; + + /* Fill the corspondance between ports and queues + * This defines the mapping from port to queue Ids. + */ + + ixEthAccPortData[IX_ETH_PORT_1].ixEthAccRxData.rxFreeQueue + = IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q; + ixEthAccPortData[IX_ETH_PORT_2].ixEthAccRxData.rxFreeQueue + = IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q; +#ifdef __ixp46X + ixEthAccPortData[IX_ETH_PORT_3].ixEthAccRxData.rxFreeQueue + = IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q; +#endif + ixEthAccPortData[IX_ETH_PORT_1].ixEthAccTxData.txQueue + = IX_ETH_ACC_TX_FRAME_ENET0_Q; + ixEthAccPortData[IX_ETH_PORT_2].ixEthAccTxData.txQueue + = IX_ETH_ACC_TX_FRAME_ENET1_Q; +#ifdef __ixp46X + ixEthAccPortData[IX_ETH_PORT_3].ixEthAccTxData.txQueue + = IX_ETH_ACC_TX_FRAME_ENET2_Q; +#endif + /* Fill the corspondance between ports and NPEs + * This defines the mapping from port to npeIds. + */ + + ixEthAccPortData[IX_ETH_PORT_1].npeId = IX_NPEMH_NPEID_NPEB; + ixEthAccPortData[IX_ETH_PORT_2].npeId = IX_NPEMH_NPEID_NPEC; +#ifdef __ixp46X + ixEthAccPortData[IX_ETH_PORT_3].npeId = IX_NPEMH_NPEID_NPEA; +#endif + /* set the default rx scheduling discipline */ + ixEthAccDataInfo.schDiscipline = FIFO_NO_PRIORITY; + + /* + * Queue Selection step: + * + * The following code selects all the queues and build + * a temporary array which contains for each queue + * - the queue Id, + * - the highest traffic class (in case of many + * priorities configured for the same queue on different + * ports) + * - the number of different Npes which are + * configured to write to this queue. + * + * The output of this loop is a temporary array of RX queues + * in any order. + * + */ +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + for (ixEthAccPortId = 0; + (ixEthAccPortId < IX_ETH_ACC_NUMBER_OF_PORTS) + && (ret == IX_ETH_ACC_SUCCESS); + ixEthAccPortId++) + { + /* map between ethDb and ethAcc port Ids */ + ixEthDbPortId = (IxEthDBPortId)ixEthAccPortId; + + /* map between npeId and ethAcc port Ids */ + ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId); + + /* Iterate thru the different priorities */ + for (ixEthDBTrafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; + ixEthDBTrafficClass <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY; + ixEthDBTrafficClass++) + { + ixEthDBStatus = ixEthDBFeaturePropertyGet( + ixEthDbPortId, + IX_ETH_DB_VLAN_QOS, + ixEthDBTrafficClass, + &ixEthDBPropertyType, + (void *)&ixEthDBParameter); + + if (ixEthDBStatus == IX_ETH_DB_SUCCESS) + { + /* This port and QoS class are mapped to + * a RX queue. + */ + if (ixEthDBPropertyType == IX_ETH_DB_INTEGER_PROPERTY) + { + /* remember the highest npe Id supporting ethernet */ + if (ixNpeId > ixHighestNpeId) + { + ixHighestNpeId = ixNpeId; + } + + /* search the queue in the list of queues + * already used by an other port or QoS + */ + for (rxQueue = 0; + rxQueue < rxQueueCount; + rxQueue++) + { + if (rxQueues[rxQueue].qId == (IxQMgrQId)ixEthDBParameter) + { + /* found an existing setup, update the number of ports + * for this queue if the port maps to + * a different NPE. + */ + if (rxQueues[rxQueue].npeId != ixNpeId) + { + rxQueues[rxQueue].npeCount++; + rxQueues[rxQueue].npeId = ixNpeId; + } + /* get the highest traffic class for this queue */ + if (rxQueues[rxQueue].trafficClass > ixEthDBTrafficClass) + { + rxQueues[rxQueue].trafficClass = ixEthDBTrafficClass; + } + break; + } + } + if (rxQueue == rxQueueCount) + { + /* new queue not found in the current list, + * add a new entry. + */ + IX_OSAL_ASSERT(rxQueueCount < IX_ETHACC_MAX_RX_QUEUES); + rxQueues[rxQueueCount].qId = ixEthDBParameter; + rxQueues[rxQueueCount].npeCount = 1; + rxQueues[rxQueueCount].npeId = ixNpeId; + rxQueues[rxQueueCount].trafficClass = ixEthDBTrafficClass; + rxQueueCount++; + } + } + else + { + /* unexpected property type (not Integer) */ + ret = IX_ETH_ACC_FAIL; + + IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: unexpected property type returned by EthDB\n", 0, 0, 0, 0, 0, 0); + + /* no point to continue to iterate */ + break; + } + } + else + { + /* No Rx queue configured for this port + * and this traffic class. Do nothing. + */ + } + } + + /* notify EthDB that queue initialization is complete and traffic class allocation is frozen */ + ixEthDBFeaturePropertySet(ixEthDbPortId, + IX_ETH_DB_VLAN_QOS, + IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE, + NULL /* ignored */); + } + +#else + + ixNpeId = IX_ETH_ACC_PORT_TO_NPE_ID(ixEthAccPortId); + rxQueues[0].qId = 4; + rxQueues[0].npeCount = 1; + rxQueues[0].npeId = ixNpeId; + rxQueues[0].trafficClass = IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; + rxQueueCount++; + +#endif + + /* check there is at least 1 rx queue : there is no point + * to continue if there is no rx queue configured + */ + if ((rxQueueCount == 0) || (ret == IX_ETH_ACC_FAIL)) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: no queues configured, bailing out\n", 0, 0, 0, 0, 0, 0); + return (IX_ETH_ACC_FAIL); + } + + /* Queue sort step: + * + * Re-order the array of queues by decreasing traffic class + * using a bubble sort. (trafficClass 0 is the lowest + * priority traffic, trafficClass 7 is the highest priority traffic) + * + * Primary sort order is traffic class + * Secondary sort order is npeId + * + * Note that a bubble sort algorithm is not very efficient when + * the number of queues grows . However, this is not a very bad choice + * considering the very small number of entries to sort. Also, bubble + * sort is extremely fast when the list is already sorted. + * + * The output of this loop is a sorted array of queues. + * + */ + sortIterations = 0; + do + { + sortIterations++; + completelySorted = TRUE; + for (rxQueue = 0; + rxQueue < rxQueueCount - sortIterations; + rxQueue++) + { + /* compare adjacent elements */ + if ((rxQueues[rxQueue].trafficClass < + rxQueues[rxQueue+1].trafficClass) + || ((rxQueues[rxQueue].trafficClass == + rxQueues[rxQueue+1].trafficClass) + &&(rxQueues[rxQueue].npeId < + rxQueues[rxQueue+1].npeId))) + { + /* swap adjacent elements */ + int npeCount = rxQueues[rxQueue].npeCount; + UINT32 npeId = rxQueues[rxQueue].npeId; + IxQMgrQId qId = rxQueues[rxQueue].qId; + IxEthDBProperty trafficClass = rxQueues[rxQueue].trafficClass; + rxQueues[rxQueue].npeCount = rxQueues[rxQueue+1].npeCount; + rxQueues[rxQueue].npeId = rxQueues[rxQueue+1].npeId; + rxQueues[rxQueue].qId = rxQueues[rxQueue+1].qId; + rxQueues[rxQueue].trafficClass = rxQueues[rxQueue+1].trafficClass; + rxQueues[rxQueue+1].npeCount = npeCount; + rxQueues[rxQueue+1].npeId = npeId; + rxQueues[rxQueue+1].qId = qId; + rxQueues[rxQueue+1].trafficClass = trafficClass; + completelySorted = FALSE; + } + } + } + while (!completelySorted); + + /* Queue traffic class list: + * + * Fill an array of rx queues linked by ascending traffic classes. + * + * If the queues are configured as follows + * qId 6 -> traffic class 0 (lowest) + * qId 7 -> traffic class 0 + * qId 8 -> traffic class 6 + * qId 12 -> traffic class 7 (highest) + * + * Then the output of this loop will be + * + * higherPriorityQueue[6] = 8 + * higherPriorityQueue[7] = 8 + * higherPriorityQueue[8] = 12 + * higherPriorityQueue[12] = Invalid queueId + * higherPriorityQueue[...] = Invalid queueId + * + * Note that this queue ordering does not handle all possibilities + * that could result from different rules associated with different + * ports, and inconsistencies in the rules. In all cases, the + * output of this algorithm is a simple linked list of queues, + * without closed circuit. + + * This list is implemented as an array with invalid values initialized + * with an "invalid" queue id which is the maximum number of queues. + * + */ + + /* + * Initialise the rx queue list. + */ + for (rxQueue = 0; rxQueue < IX_QMGR_MAX_NUM_QUEUES; rxQueue++) + { + ixEthAccDataInfo.higherPriorityQueue[rxQueue] = IX_QMGR_MAX_NUM_QUEUES; + } + + /* build the linked list for this NPE. + */ + for (ixNpeId = 0; + ixNpeId <= ixHighestNpeId; + ixNpeId++) + { + /* iterate thru the sorted list of queues + */ + ixQId = IX_QMGR_MAX_NUM_QUEUES; + for (rxQueue = 0; + rxQueue < rxQueueCount; + rxQueue++) + { + if (rxQueues[rxQueue].npeId == ixNpeId) + { + ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId; + /* iterate thru queues with the same traffic class + * than the current queue. (queues are ordered by descending + * traffic classes and npeIds). + */ + while ((rxQueue < rxQueueCount - 1) + && (rxQueues[rxQueue].trafficClass + == rxQueues[rxQueue+1].trafficClass) + && (ixNpeId == rxQueues[rxQueue].npeId)) + { + rxQueue++; + ixEthAccDataInfo.higherPriorityQueue[rxQueues[rxQueue].qId] = ixQId; + } + ixQId = rxQueues[rxQueue].qId; + } + } + } + + /* point on the first dynamic queue description */ + qInfoDes = ixEthAccQmgrRxQueuesInfo; + + /* update the list of queues with the rx queues */ + for (rxQueue = 0; + (rxQueue < rxQueueCount) && (ret == IX_ETH_ACC_SUCCESS); + rxQueue++) + { + /* Don't utilize more than IX_ETHACC_MAX_LARGE_RX_QUEUES queues + * with the full 128 entries. For the lower priority queues, use + * a smaller number of entries. This ensures queue resources + * remain available for other components. + */ + if( (rxQueueCount > IX_ETHACC_MAX_LARGE_RX_QUEUES) && + (rxQueue < rxQueueCount - IX_ETHACC_MAX_LARGE_RX_QUEUES) ) + { + /* add the small RX Queue setup template to the list of queues */ + memcpy(qInfoDes, &ixEthAccQmgrRxSmallTemplate, sizeof(*qInfoDes)); + } else { + /* add the default RX Queue setup template to the list of queues */ + memcpy(qInfoDes, &ixEthAccQmgrRxDefaultTemplate, sizeof(*qInfoDes)); + } + + /* setup the RxQueue ID */ + qInfoDes->qId = rxQueues[rxQueue].qId; + + /* setup the RxQueue watermark level + * + * Each queue can be filled by many NPEs. To avoid the + * NPEs to write to a full queue, need to set the + * high watermark level for nearly full condition. + * (the high watermark level are a power of 2 + * starting from the top of the queue) + * + * Number of watermark + * ports level + * 1 0 + * 2 1 + * 3 2 + * 4 4 + * 5 4 + * 6 8 + * n approx. 2**ceil(log2(n)) + */ + if (rxQueues[rxQueue].npeCount == 1) + { + qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL0; + } + else if (rxQueues[rxQueue].npeCount == 2) + { + qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL1; + } + else if (rxQueues[rxQueue].npeCount == 3) + { + qInfoDes->AlmostFullThreshold = IX_QMGR_Q_WM_LEVEL2; + } + else + { + /* reach the maximum number for CSR 2.0 */ + IX_ETH_ACC_WARNING_LOG("ixEthAccQMgrQueuesConfig: maximum number of NPEs per queue reached, bailing out\n", 0, 0, 0, 0, 0, 0); + ret = IX_ETH_ACC_FAIL; + break; + } + + /* move to next queue entry */ + ++qInfoDes; + } + + /* configure the static list (RxFree, Tx and TxDone queues) */ + for (qInfoDes = ixEthAccQmgrStaticInfo; + (qInfoDes->qCallback != (IxQMgrCallback) NULL ) + && (ret == IX_ETH_ACC_SUCCESS); + ++qInfoDes) + { + ret = ixEthAccQMgrQueueSetup(qInfoDes); + } + + /* configure the dynamic list (Rx queues) */ + for (qInfoDes = ixEthAccQmgrRxQueuesInfo; + (qInfoDes->qCallback != (IxQMgrCallback) NULL ) + && (ret == IX_ETH_ACC_SUCCESS); + ++qInfoDes) + { + ret = ixEthAccQMgrQueueSetup(qInfoDes); + } + + return(ret); +} + +/** + * @fn ixEthAccQMgrRxQEntryGet(UINT32 *rxQueueEntries) + * + * @brief Add and return the total number of entries in all Rx queues + * + * @param UINT32 rxQueueEntries[in] number of entries in all queues + * + * @return void + * + * @note Rx queues configuration is driven by Qos Setup. There is a + * variable number of rx queues which are set at initialisation. + * + * @internal + */ +IX_ETH_ACC_PUBLIC +void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries) +{ + UINT32 rxQueueLevel; + IxEthAccQregInfo *qInfoDes;; + + *numRxQueueEntries = 0; + + /* iterate thru rx queues */ + for (qInfoDes = ixEthAccQmgrRxQueuesInfo; + qInfoDes->qCallback != (IxQMgrCallback)NULL; + ++qInfoDes) + { + /* retrieve the rx queue level */ + rxQueueLevel = 0; + ixQMgrQNumEntriesGet(qInfoDes->qId, &rxQueueLevel); + (*numRxQueueEntries) += rxQueueLevel; + } +} + +/** + * @fn ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback) + * + * @brief Change the callback registered to all rx queues. + * + * @param IxQMgrCallback ixQMgrCallback[in] QMgr callback to register + * + * @return IxEthAccStatus + * + * @note The user may decide to use different Rx mechanisms + * (e.g. receive many frames at the same time , or receive + * one frame at a time, depending on the overall application + * performances). A different QMgr callback is registered. This + * way, there is no excessive pointer checks in the datapath. + * + * @internal + */ +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback) +{ + IxEthAccQregInfo *qInfoDes; + IxEthAccStatus ret = IX_ETH_ACC_SUCCESS; + + /* parameter check */ + if (NULL == ixQMgrCallback) + { + ret = IX_ETH_ACC_FAIL; + } + + /* iterate thru rx queues */ + for (qInfoDes = ixEthAccQmgrRxQueuesInfo; + (qInfoDes->qCallback != (IxQMgrCallback) NULL ) + && (ret == IX_ETH_ACC_SUCCESS); + ++qInfoDes) + { + /* register the rx callback for all queues */ + if (ixQMgrNotificationCallbackSet(qInfoDes->qId, + ixQMgrCallback, + qInfoDes->callbackTag + ) != IX_SUCCESS) + { + ret = IX_ETH_ACC_FAIL; + } + } + return(ret); +} + +/** + * @fn ixEthAccSingleEthNpeCheck(IxEthAccPortId portId) + * + * @brief Check the npe exists for this port + * + * @param IxEthAccPortId portId[in] port + * + * @return IxEthAccStatus + * + * @internal + */ +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId portId) +{ + + /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */ + if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != + (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) + || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) + { + if ((IX_ETH_PORT_1 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == + IX_FEATURE_CTRL_COMPONENT_ENABLED)) + { + return IX_ETH_ACC_SUCCESS; + } + + if ((IX_ETH_PORT_2 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == + IX_FEATURE_CTRL_COMPONENT_ENABLED)) + { + return IX_ETH_ACC_SUCCESS; + } + + if ((IX_ETH_PORT_3 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) == + IX_FEATURE_CTRL_COMPONENT_ENABLED)) + { + return IX_ETH_ACC_SUCCESS; + } + + return IX_ETH_ACC_FAIL; + } + + return IX_ETH_ACC_SUCCESS; +} + +/** + * @fn ixEthAccStatsShow(void) + * + * @brief Displays all EthAcc stats + * + * @return void + * + */ +void ixEthAccStatsShow(IxEthAccPortId portId) +{ + ixEthAccMdioShow(); + + printf("\nPort %u\nUnicast MAC : ", portId); + ixEthAccPortUnicastAddressShow(portId); + ixEthAccPortMulticastAddressShow(portId); + printf("\n"); + + ixEthAccDataPlaneShow(); +} + + + diff --git a/drivers/net/npe/IxEthAccControlInterface.c b/drivers/net/npe/IxEthAccControlInterface.c new file mode 100644 index 0000000..4432847 --- /dev/null +++ b/drivers/net/npe/IxEthAccControlInterface.c @@ -0,0 +1,533 @@ +/** + * @file IxEthAccControlInterface.c + * + * @author Intel Corporation + * @date + * + * @brief IX_ETH_ACC_PUBLIC wrappers for control plane functions + * + * Design Notes: + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxOsal.h" +#include "IxEthAcc.h" +#include "IxEthAcc_p.h" + +PUBLIC IxOsalMutex ixEthAccControlInterfaceMutex; + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortEnable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + printf("EthAcc: (Mac) cannot enable port %d, service not initialized\n", portId); + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortEnablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortDisable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + /* check the context is iinitialized */ + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortDisablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortEnabledQueryPriv(portId, enabled); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortPromiscuousModeClearPriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortPromiscuousModeSetPriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortUnicastMacAddressSetPriv(portId, macAddr); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId, IxEthAccMacAddr *macAddr) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortUnicastMacAddressGetPriv(portId, macAddr); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId, IxEthAccMacAddr *macAddr) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortMulticastAddressJoinPriv(portId, macAddr); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortMulticastAddressJoinAllPriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId, IxEthAccMacAddr *macAddr) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortMulticastAddressLeavePriv(portId, macAddr); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortMulticastAddressLeaveAllPriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortUnicastAddressShow(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortUnicastAddressShowPriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC void +ixEthAccPortMulticastAddressShow(IxEthAccPortId portId) +{ + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return; + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + ixEthAccPortMulticastAddressShowPriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortDuplexModeSet(IxEthAccPortId portId, IxEthAccDuplexMode mode) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortDuplexModeSetPriv(portId, mode); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortDuplexModeGet(IxEthAccPortId portId, IxEthAccDuplexMode *mode) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortDuplexModeGetPriv(portId, mode); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortTxFrameAppendPaddingEnablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortTxFrameAppendPaddingDisablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortTxFrameAppendFCSEnablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortTxFrameAppendFCSDisablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortRxFrameAppendFCSEnablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortRxFrameAppendFCSDisablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccTxSchedulingDisciplineSetPriv(portId, sched); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccRxSchedulingDisciplineSetPriv(sched); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccNpeLoopbackEnablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortTxEnable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortTxEnablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortRxEnable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortRxEnablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccNpeLoopbackDisablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortTxDisable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortTxDisablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortRxDisable(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortRxDisablePriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} + +IX_ETH_ACC_PUBLIC IxEthAccStatus +ixEthAccPortMacReset(IxEthAccPortId portId) +{ + IxEthAccStatus result; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&ixEthAccControlInterfaceMutex, IX_OSAL_WAIT_FOREVER); + result = ixEthAccPortMacResetPriv(portId); + ixOsalMutexUnlock(&ixEthAccControlInterfaceMutex); + return result; +} diff --git a/drivers/net/npe/IxEthAccDataPlane.c b/drivers/net/npe/IxEthAccDataPlane.c new file mode 100644 index 0000000..b62f0d0 --- /dev/null +++ b/drivers/net/npe/IxEthAccDataPlane.c @@ -0,0 +1,2483 @@ +/** + * @file IxEthDataPlane.c + * + * @author Intel Corporation + * @date 12-Feb-2002 + * + * @brief This file contains the implementation of the IXPxxx + * Ethernet Access Data plane component + * + * Design Notes: + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxNpeMh.h" +#include "IxEthAcc.h" +#include "IxEthDB.h" +#include "IxOsal.h" +#include "IxEthDBPortDefs.h" +#include "IxFeatureCtrl.h" +#include "IxEthAcc_p.h" +#include "IxEthAccQueueAssign_p.h" + +extern PUBLIC IxEthAccMacState ixEthAccMacState[]; +extern PUBLIC UINT32 ixEthAccNewSrcMask; + +/** + * private functions prototype + */ +PRIVATE IX_OSAL_MBUF * +ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask); + +PRIVATE UINT32 +ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf); + +PRIVATE UINT32 +ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf); + +PRIVATE IxEthAccStatus +ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId, + IxEthAccTxPriority *priorityPtr); + +PRIVATE IxEthAccStatus +ixEthAccTxFromSwQ(IxEthAccPortId portId, + IxEthAccTxPriority priority); + +PRIVATE IxEthAccStatus +ixEthAccRxFreeFromSwQ(IxEthAccPortId portId); + +PRIVATE void +ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf); + +PRIVATE void +ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf); + +PRIVATE IX_STATUS +ixEthAccQmgrLockTxWrite(IxEthAccPortId portId, + UINT32 qBuffer); + +PRIVATE IX_STATUS +ixEthAccQmgrLockRxWrite(IxEthAccPortId portId, + UINT32 qBuffer); + +PRIVATE IX_STATUS +ixEthAccQmgrTxWrite(IxEthAccPortId portId, + UINT32 qBuffer, + UINT32 priority); + +/** + * @addtogroup IxEthAccPri + *@{ + */ + +/* increment a counter only when stats are enabled */ +#define TX_STATS_INC(port,field) \ + IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccTxData.stats.field) +#define RX_STATS_INC(port,field) \ + IX_ETH_ACC_STATS_INC(ixEthAccPortData[port].ixEthAccRxData.stats.field) + +/* always increment the counter (mainly used for unexpected errors) */ +#define TX_INC(port,field) \ + ixEthAccPortData[port].ixEthAccTxData.stats.field++ +#define RX_INC(port,field) \ + ixEthAccPortData[port].ixEthAccRxData.stats.field++ + +PRIVATE IxEthAccDataPlaneStats ixEthAccDataStats; + +extern IxEthAccPortDataInfo ixEthAccPortData[]; +extern IxEthAccInfo ixEthAccDataInfo; + +PRIVATE IxOsalFastMutex txWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS]; +PRIVATE IxOsalFastMutex rxWriteMutex[IX_ETH_ACC_NUMBER_OF_PORTS]; + +/** + * + * @brief Mbuf header conversion macros : they implement the + * different conversions using a temporary value. They also double-check + * that the parameters can be converted to/from NPE format. + * + */ +#if defined(__wince) && !defined(IN_KERNEL) +#define PTR_VIRT2NPE(ptrSrc,dst) \ + do { UINT32 temp; \ + IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \ + temp = (UINT32)IX_OSAL_MBUF_MBUF_VIRTUAL_TO_PHYSICAL_TRANSLATION((IX_OSAL_MBUF*)ptrSrc); \ + (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ + while(0) + +#define PTR_NPE2VIRT(type,src,ptrDst) \ + do { void *temp; \ + IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \ + temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \ + (ptrDst) = (type)IX_OSAL_MBUF_MBUF_PHYSICAL_TO_VIRTUAL_TRANSLATION(temp); } \ + while(0) +#else +#define PTR_VIRT2NPE(ptrSrc,dst) \ + do { UINT32 temp; \ + IX_OSAL_ENSURE(sizeof(ptrSrc) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(dst) == sizeof(UINT32), "Wrong parameter type"); \ + temp = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS(ptrSrc); \ + (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ + while(0) + +#define PTR_NPE2VIRT(type,src,ptrDst) \ + do { void *temp; \ + IX_OSAL_ENSURE(sizeof(type) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(src) == sizeof(UINT32), "Wrong parameter type"); \ + IX_OSAL_ENSURE(sizeof(ptrDst) == sizeof(UINT32), "Wrong parameter type"); \ + temp = (void *)IX_OSAL_SWAP_BE_SHARED_LONG(src); \ + (ptrDst) = (type)IX_OSAL_MMU_PHYS_TO_VIRT(temp); } \ + while(0) +#endif + +/** + * + * @brief Mbuf payload pointer conversion macros : Wince has its own + * method to convert the buffer pointers + */ +#if defined(__wince) && !defined(IN_KERNEL) +#define DATAPTR_VIRT2NPE(ptrSrc,dst) \ + do { UINT32 temp; \ + temp = (UINT32)IX_OSAL_MBUF_DATA_VIRTUAL_TO_PHYSICAL_TRANSLATION(ptrSrc); \ + (dst) = IX_OSAL_SWAP_BE_SHARED_LONG(temp); } \ + while(0) + +#else +#define DATAPTR_VIRT2NPE(ptrSrc,dst) PTR_VIRT2NPE(IX_OSAL_MBUF_MDATA(ptrSrc),dst) +#endif + + +/* Flush the shared part of the mbuf header */ +#define IX_ETHACC_NE_CACHE_FLUSH(mbufPtr) \ + do { \ + IX_OSAL_CACHE_FLUSH(IX_ETHACC_NE_SHARED(mbufPtr), \ + sizeof(IxEthAccNe)); \ + } \ + while(0) + +/* Invalidate the shared part of the mbuf header */ +#define IX_ETHACC_NE_CACHE_INVALIDATE(mbufPtr) \ + do { \ + IX_OSAL_CACHE_INVALIDATE(IX_ETHACC_NE_SHARED(mbufPtr), \ + sizeof(IxEthAccNe)); \ + } \ + while(0) + +/* Preload one cache line (shared mbuf headers are aligned + * and their size is 1 cache line) + * + * IX_OSAL_CACHED is defined when the mbuf headers are + * allocated from cached memory. + * + * Other processor on emulation environment may not implement + * preload function + */ +#ifdef IX_OSAL_CACHED + #if (CPU!=SIMSPARCSOLARIS) && !defined (__wince) + #define IX_ACC_DATA_CACHE_PRELOAD(ptr) \ + do { /* preload a cache line (Xscale Processor) */ \ + __asm__ (" pld [%0]\n": : "r" (ptr)); \ + } \ + while(0) + #else + /* preload not implemented on different processor */ + #define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \ + do { /* nothing */ } while (0) + #endif +#else + /* preload not needed if cache is not enabled */ + #define IX_ACC_DATA_CACHE_PRELOAD(mbufPtr) \ + do { /* nothing */ } while (0) +#endif + +/** + * + * @brief function to retrieve the correct pointer from + * a queue entry posted by the NPE + * + * @param qEntry : entry from qmgr queue + * mask : applicable mask for this queue + * (4 most significant bits are used for additional informations) + * + * @return IX_OSAL_MBUF * pointer to mbuf header + * + * @internal + */ +PRIVATE IX_OSAL_MBUF * +ixEthAccEntryFromQConvert(UINT32 qEntry, UINT32 mask) +{ + IX_OSAL_MBUF *mbufPtr; + + if (qEntry != 0) + { + /* mask NPE bits (e.g. priority, port ...) */ + qEntry &= mask; + +#if IX_ACC_DRAM_PHYS_OFFSET != 0 + /* restore the original address pointer (if PHYS_OFFSET is not 0) */ + qEntry |= (IX_ACC_DRAM_PHYS_OFFSET & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); +#endif + /* get the mbuf pointer address from the npe-shared address */ + qEntry -= offsetof(IX_OSAL_MBUF,ix_ne); + + /* phys2virt mbuf */ + mbufPtr = (IX_OSAL_MBUF *)IX_OSAL_MMU_PHYS_TO_VIRT(qEntry); + + /* preload the cacheline shared with NPE */ + IX_ACC_DATA_CACHE_PRELOAD(IX_ETHACC_NE_SHARED(mbufPtr)); + + /* preload the cacheline used by xscale */ + IX_ACC_DATA_CACHE_PRELOAD(mbufPtr); + } + else + { + mbufPtr = NULL; + } + + return mbufPtr; +} + +/* Convert the mbuf header for NPE transmission */ +PRIVATE UINT32 +ixEthAccMbufTxQPrepare(IX_OSAL_MBUF *mbuf) +{ + UINT32 qbuf; + UINT32 len; + + /* endianess swap for tci and flags + note: this is done only once, even for chained buffers */ + IX_ETHACC_NE_FLAGS(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf)); + IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf)); + + /* test for unchained mbufs */ + if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL) + { + /* "best case" scenario : unchained mbufs */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxMBufs); + + /* payload pointer conversion */ + DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf)); + + /* unchained mbufs : the frame length is the mbuf length + * and the 2 identical lengths are stored in the same + * word. + */ + len = IX_OSAL_MBUF_MLEN(mbuf); + + /* set the length in both length and pktLen 16-bits fields */ + len |= (len << IX_ETHNPE_ACC_LENGTH_OFFSET); + IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len); + + /* unchained mbufs : next contains 0 */ + IX_ETHACC_NE_NEXT(mbuf) = 0; + + /* flush shared header after all address conversions */ + IX_ETHACC_NE_CACHE_FLUSH(mbuf); + } + else + { + /* chained mbufs */ + IX_OSAL_MBUF *ptr = mbuf; + IX_OSAL_MBUF *nextPtr; + UINT32 frmLen; + + /* get the frame length from the header of the first buffer */ + frmLen = IX_OSAL_MBUF_PKT_LEN(mbuf); + + do + { + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxMBufs); + + /* payload pointer */ + DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr)); + /* Buffer length and frame length are stored in the same word */ + len = IX_OSAL_MBUF_MLEN(ptr); + len = frmLen | (len << IX_ETHNPE_ACC_LENGTH_OFFSET); + IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len); + + /* get the virtual next chain pointer */ + nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); + if (nextPtr != NULL) + { + /* shared pointer of the next buffer is chained */ + PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr), + IX_ETHACC_NE_NEXT(ptr)); + } + else + { + IX_ETHACC_NE_NEXT(ptr) = 0; + } + + /* flush shared header after all address conversions */ + IX_ETHACC_NE_CACHE_FLUSH(ptr); + + /* move to next buffer */ + ptr = nextPtr; + + /* the frame length field is set only in the first buffer + * and is zeroed in the next buffers + */ + frmLen = 0; + } + while(ptr != NULL); + + } + + /* virt2phys mbuf itself */ + qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS( + IX_ETHACC_NE_SHARED(mbuf)); + + /* Ensure the bits which are reserved to exchange information with + * the NPE are cleared + * + * If the mbuf address is not correctly aligned, or from an + * incompatible memory range, there is no point to continue + */ + IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_TXENET_ADDR_MASK) == 0), + "Invalid address range"); + + return qbuf; +} + +/* Convert the mbuf header for NPE reception */ +PRIVATE UINT32 +ixEthAccMbufRxQPrepare(IX_OSAL_MBUF *mbuf) +{ + UINT32 len; + UINT32 qbuf; + + if (IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) == NULL) + { + /* "best case" scenario : unchained mbufs */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxFreeMBufs); + + /* unchained mbufs : payload pointer */ + DATAPTR_VIRT2NPE(mbuf, IX_ETHACC_NE_DATA(mbuf)); + + /* unchained mbufs : set the buffer length + * and the frame length field is zeroed + */ + len = (IX_OSAL_MBUF_MLEN(mbuf) << IX_ETHNPE_ACC_LENGTH_OFFSET); + IX_ETHACC_NE_LEN(mbuf) = IX_OSAL_SWAP_BE_SHARED_LONG(len); + + /* unchained mbufs : next pointer is null */ + IX_ETHACC_NE_NEXT(mbuf) = 0; + + /* flush shared header after all address conversions */ + IX_ETHACC_NE_CACHE_FLUSH(mbuf); + + /* remove shared header cache line */ + IX_ETHACC_NE_CACHE_INVALIDATE(mbuf); + } + else + { + /* chained mbufs */ + IX_OSAL_MBUF *ptr = mbuf; + IX_OSAL_MBUF *nextPtr; + + do + { + /* chained mbufs */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxFreeMBufs); + + /* we must save virtual next chain pointer */ + nextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); + + if (nextPtr != NULL) + { + /* chaining pointer for NPE */ + PTR_VIRT2NPE(IX_ETHACC_NE_SHARED(nextPtr), + IX_ETHACC_NE_NEXT(ptr)); + } + else + { + IX_ETHACC_NE_NEXT(ptr) = 0; + } + + /* payload pointer */ + DATAPTR_VIRT2NPE(ptr,IX_ETHACC_NE_DATA(ptr)); + + /* buffer length */ + len = (IX_OSAL_MBUF_MLEN(ptr) << IX_ETHNPE_ACC_LENGTH_OFFSET); + IX_ETHACC_NE_LEN(ptr) = IX_OSAL_SWAP_BE_SHARED_LONG(len); + + /* flush shared header after all address conversions */ + IX_ETHACC_NE_CACHE_FLUSH(ptr); + + /* remove shared header cache line */ + IX_ETHACC_NE_CACHE_INVALIDATE(ptr); + + /* next mbuf in the chain */ + ptr = nextPtr; + } + while(ptr != NULL); + } + + /* virt2phys mbuf itself */ + qbuf = (UINT32)IX_OSAL_MMU_VIRT_TO_PHYS( + IX_ETHACC_NE_SHARED(mbuf)); + + /* Ensure the bits which are reserved to exchange information with + * the NPE are cleared + * + * If the mbuf address is not correctly aligned, or from an + * incompatible memory range, there is no point to continue + */ + IX_OSAL_ENSURE(((qbuf & ~IX_ETHNPE_QM_Q_RXENET_ADDR_MASK) == 0), + "Invalid address range"); + + return qbuf; +} + +/* Convert the mbuf header after NPE transmission + * Since there is nothing changed by the NPE, there is no need + * to process anything but the update of internal stats + * when they are enabled +*/ +PRIVATE void +ixEthAccMbufFromTxQ(IX_OSAL_MBUF *mbuf) +{ +#ifndef NDEBUG + /* test for unchained mbufs */ + if (IX_ETHACC_NE_NEXT(mbuf) == 0) + { + /* unchained mbufs : update the stats */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedTxDoneMBufs); + } + else + { + /* chained mbufs : walk the chain and update the stats */ + IX_OSAL_MBUF *ptr = mbuf; + + do + { + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedTxDoneMBufs); + ptr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr); + } + while (ptr != NULL); + } +#endif +} + +/* Convert the mbuf header after NPE reception */ +PRIVATE void +ixEthAccMbufFromRxQ(IX_OSAL_MBUF *mbuf) +{ + UINT32 len; + + /* endianess swap for tci and flags + note: this is done only once, even for chained buffers */ + IX_ETHACC_NE_FLAGS(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_FLAGS(mbuf)); + IX_ETHACC_NE_VLANTCI(mbuf) = IX_OSAL_SWAP_BE_SHARED_SHORT(IX_ETHACC_NE_VLANTCI(mbuf)); + + /* test for unchained mbufs */ + if (IX_ETHACC_NE_NEXT(mbuf) == 0) + { + /* unchained mbufs */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.unchainedRxMBufs); + + /* get the frame length. it is the same than the buffer length */ + len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf)); + len &= IX_ETHNPE_ACC_PKTLENGTH_MASK; + IX_OSAL_MBUF_PKT_LEN(mbuf) = IX_OSAL_MBUF_MLEN(mbuf) = len; + + /* clears the next packet field */ + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mbuf) = NULL; + } + else + { + IX_OSAL_MBUF *ptr = mbuf; + IX_OSAL_MBUF *nextPtr; + UINT32 frmLen; + + /* convert the frame length */ + frmLen = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(mbuf)); + IX_OSAL_MBUF_PKT_LEN(mbuf) = (frmLen & IX_ETHNPE_ACC_PKTLENGTH_MASK); + + /* chained mbufs */ + do + { + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.chainedRxMBufs); + + /* convert the length */ + len = IX_OSAL_SWAP_BE_SHARED_LONG(IX_ETHACC_NE_LEN(ptr)); + IX_OSAL_MBUF_MLEN(ptr) = (len >> IX_ETHNPE_ACC_LENGTH_OFFSET); + + /* get the next pointer */ + PTR_NPE2VIRT(IX_OSAL_MBUF *,IX_ETHACC_NE_NEXT(ptr), nextPtr); + if (nextPtr != NULL) + { + nextPtr = (IX_OSAL_MBUF *)((UINT8 *)nextPtr - offsetof(IX_OSAL_MBUF,ix_ne)); + } + /* set the next pointer */ + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(ptr) = nextPtr; + + /* move to the next buffer */ + ptr = nextPtr; + } + while (ptr != NULL); + } +} + +/* write to qmgr if possible and report an overflow if not possible + * Use a fast lock to protect the queue write. + * This way, the tx feature is reentrant. + */ +PRIVATE IX_STATUS +ixEthAccQmgrLockTxWrite(IxEthAccPortId portId, UINT32 qBuffer) +{ + IX_STATUS qStatus; + if (ixOsalFastMutexTryLock(&txWriteMutex[portId]) == IX_SUCCESS) + { + qStatus = ixQMgrQWrite( + IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), + &qBuffer); +#ifndef NDEBUG + if (qStatus != IX_SUCCESS) + { + TX_STATS_INC(portId, txOverflow); + } +#endif + ixOsalFastMutexUnlock(&txWriteMutex[portId]); + } + else + { + TX_STATS_INC(portId, txLock); + qStatus = IX_QMGR_Q_OVERFLOW; + } + return qStatus; +} + +/* write to qmgr if possible and report an overflow if not possible + * Use a fast lock to protect the queue write. + * This way, the Rx feature is reentrant. + */ +PRIVATE IX_STATUS +ixEthAccQmgrLockRxWrite(IxEthAccPortId portId, UINT32 qBuffer) +{ + IX_STATUS qStatus; + if (ixOsalFastMutexTryLock(&rxWriteMutex[portId]) == IX_SUCCESS) + { + qStatus = ixQMgrQWrite( + IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId), + &qBuffer); +#ifndef NDEBUG + if (qStatus != IX_SUCCESS) + { + RX_STATS_INC(portId, rxFreeOverflow); + } +#endif + ixOsalFastMutexUnlock(&rxWriteMutex[portId]); + } + else + { + RX_STATS_INC(portId, rxFreeLock); + qStatus = IX_QMGR_Q_OVERFLOW; + } + return qStatus; +} + +/* + * Set the priority and write to a qmgr queue. + */ +PRIVATE IX_STATUS +ixEthAccQmgrTxWrite(IxEthAccPortId portId, UINT32 qBuffer, UINT32 priority) +{ + /* fill the priority field */ + qBuffer |= (priority << IX_ETHNPE_QM_Q_FIELD_PRIOR_R); + + return ixEthAccQmgrLockTxWrite(portId, qBuffer); +} + +/** + * + * @brief This function will discover the highest priority S/W Tx Q that + * has entries in it + * + * @param portId - (in) the id of the port whose S/W Tx queues are to be searched + * priorityPtr - (out) the priority of the highest priority occupied q will be written + * here + * + * @return IX_ETH_ACC_SUCCESS if an occupied Q is found + * IX_ETH_ACC_FAIL if no Q has entries + * + * @internal + */ +PRIVATE IxEthAccStatus +ixEthAccTxSwQHighestPriorityGet(IxEthAccPortId portId, + IxEthAccTxPriority *priorityPtr) +{ + if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline + == FIFO_NO_PRIORITY) + { + if(IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. + ixEthAccTxData.txQ[IX_ETH_ACC_TX_DEFAULT_PRIORITY])) + { + return IX_ETH_ACC_FAIL; + } + else + { + *priorityPtr = IX_ETH_ACC_TX_DEFAULT_PRIORITY; + TX_STATS_INC(portId,txPriority[*priorityPtr]); + return IX_ETH_ACC_SUCCESS; + } + } + else + { + IxEthAccTxPriority highestPriority = IX_ETH_ACC_TX_PRIORITY_7; + while(1) + { + if(!IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. + ixEthAccTxData.txQ[highestPriority])) + { + + *priorityPtr = highestPriority; + TX_STATS_INC(portId,txPriority[highestPriority]); + return IX_ETH_ACC_SUCCESS; + + } + if (highestPriority == IX_ETH_ACC_TX_PRIORITY_0) + { + return IX_ETH_ACC_FAIL; + } + highestPriority--; + } + } +} + +/** + * + * @brief This function will take a buffer from a TX S/W Q and attempt + * to add it to the relevant TX H/W Q + * + * @param portId - the port whose TX queue is to be written to + * priority - identifies the queue from which the entry is to be read + * + * @internal + */ +PRIVATE IxEthAccStatus +ixEthAccTxFromSwQ(IxEthAccPortId portId, + IxEthAccTxPriority priority) +{ + IX_OSAL_MBUF *mbuf; + IX_STATUS qStatus; + + IX_OSAL_ENSURE((UINT32)priority <= (UINT32)7, "Invalid priority"); + + IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD( + ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], + mbuf); + + if (mbuf != NULL) + { + /* + * Add the Tx buffer to the H/W Tx Q + * We do not need to flush here as it is already done + * in TxFrameSubmit(). + */ + qStatus = ixEthAccQmgrTxWrite( + portId, + IX_OSAL_MMU_VIRT_TO_PHYS((UINT32)IX_ETHACC_NE_SHARED(mbuf)), + priority); + + if (qStatus == IX_SUCCESS) + { + TX_STATS_INC(portId,txFromSwQOK); + return IX_SUCCESS; + } + else if (qStatus == IX_QMGR_Q_OVERFLOW) + { + /* + * H/W Q overflow, need to save the buffer + * back on the s/w Q. + * we must put it back on the head of the q to avoid + * reordering packet tx + */ + TX_STATS_INC(portId,txFromSwQDelayed); + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( + ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], + mbuf); + + /*enable Q notification*/ + qStatus = ixQMgrNotificationEnable( + IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), + IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId)); + + if (qStatus != IX_SUCCESS && qStatus != IX_QMGR_WARNING) + { + TX_INC(portId,txUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccTxFromSwQ:Unexpected Error: %u\n", + qStatus, 0, 0, 0, 0, 0); + } + } + else + { + TX_INC(portId,txUnexpectedError); + + /* recovery attempt */ + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( + ixEthAccPortData[portId].ixEthAccTxData.txQ[priority], + mbuf); + + IX_ETH_ACC_FATAL_LOG( + "ixEthAccTxFromSwQ:Error: unexpected QM status 0x%08X\n", + qStatus, 0, 0, 0, 0, 0); + } + } + else + { + /* sw queue is empty */ + } + return IX_ETH_ACC_FAIL; +} + +/** + * + * @brief This function will take a buffer from a RXfree S/W Q and attempt + * to add it to the relevant RxFree H/W Q + * + * @param portId - the port whose RXFree queue is to be written to + * + * @internal + */ +PRIVATE IxEthAccStatus +ixEthAccRxFreeFromSwQ(IxEthAccPortId portId) +{ + IX_OSAL_MBUF *mbuf; + IX_STATUS qStatus = IX_SUCCESS; + + IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD( + ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, + mbuf); + if (mbuf != NULL) + { + /* + * Add The Rx Buffer to the H/W Free buffer Q if possible + */ + qStatus = ixEthAccQmgrLockRxWrite(portId, + IX_OSAL_MMU_VIRT_TO_PHYS( + (UINT32)IX_ETHACC_NE_SHARED(mbuf))); + + if (qStatus == IX_SUCCESS) + { + RX_STATS_INC(portId,rxFreeRepFromSwQOK); + /* + * Buffer added to h/w Q. + */ + return IX_SUCCESS; + } + else if (qStatus == IX_QMGR_Q_OVERFLOW) + { + /* + * H/W Q overflow, need to save the buffer back on the s/w Q. + */ + RX_STATS_INC(portId,rxFreeRepFromSwQDelayed); + + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( + ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, + mbuf); + } + else + { + /* unexpected qmgr error */ + RX_INC(portId,rxUnexpectedError); + + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD( + ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, + mbuf); + + IX_ETH_ACC_FATAL_LOG("IxEthAccRxFreeFromSwQ:Error: unexpected QM status 0x%08X\n", + qStatus, 0, 0, 0, 0, 0); + } + } + else + { + /* sw queue is empty */ + } + return IX_ETH_ACC_FAIL; +} + + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccInitDataPlane() +{ + UINT32 portId; + + /* + * Initialize the service and register callback to other services. + */ + + IX_ETH_ACC_MEMSET(&ixEthAccDataStats, + 0, + sizeof(ixEthAccDataStats)); + + for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + ixOsalFastMutexInit(&txWriteMutex[portId]); + ixOsalFastMutexInit(&rxWriteMutex[portId]); + + IX_ETH_ACC_MEMSET(&ixEthAccPortData[portId], + 0, + sizeof(ixEthAccPortData[portId])); + + ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = FIFO_NO_PRIORITY; + } + + return (IX_ETH_ACC_SUCCESS); +} + + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId, + IxEthAccPortTxDoneCallback + txCallbackFn, + UINT32 callbackTag) +{ + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + return (IX_ETH_ACC_INVALID_PORT); + } + +/* HACK: removing this code to enable NPE-A preliminary testing + * if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + * { + * IX_ETH_ACC_WARNING_LOG("ixEthAccPortTxDoneCallbackRegister: Unavailable Eth %d: Cannot register TxDone Callback.\n",(INT32)portId,0,0,0,0,0); + * return IX_ETH_ACC_SUCCESS ; + * } + */ + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + if (txCallbackFn == 0) + /* Check for null function pointer here. */ + { + return (IX_ETH_ACC_INVALID_ARG); + } + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = txCallbackFn; + ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = callbackTag; + return (IX_ETH_ACC_SUCCESS); +} + + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccPortRxCallbackRegister(IxEthAccPortId portId, + IxEthAccPortRxCallback + rxCallbackFn, + UINT32 callbackTag) +{ + IxEthAccPortId port; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + return (IX_ETH_ACC_INVALID_PORT); + } + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccPortRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* Check for null function pointer here. */ + if (rxCallbackFn == NULL) + { + return (IX_ETH_ACC_INVALID_ARG); + } + + /* Check the user is not changing the callback type + * when the port is enabled. + */ + if (ixEthAccMacState[portId].portDisableState == ACTIVE) + { + for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++) + { + if ((ixEthAccMacState[port].portDisableState == ACTIVE) + && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == TRUE)) + { + /* one of the active ports has a different rx callback type. + * Changing the callback type when the port is enabled + * is not safe + */ + return (IX_ETH_ACC_INVALID_ARG); + } + } + } + + /* update the callback pointer : this is done before + * registering the new qmgr callback + */ + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = rxCallbackFn; + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = callbackTag; + + /* update the qmgr callback for rx queues */ + if (ixEthAccQMgrRxCallbacksRegister(ixEthRxFrameQMCallback) + != IX_ETH_ACC_SUCCESS) + { + /* unexpected qmgr error */ + IX_ETH_ACC_FATAL_LOG("ixEthAccPortRxCallbackRegister: unexpected QMgr error, " \ + "could not register Rx single-buffer callback\n", 0, 0, 0, 0, 0, 0); + + RX_INC(portId,rxUnexpectedError); + return (IX_ETH_ACC_INVALID_ARG); + } + + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = FALSE; + + return (IX_ETH_ACC_SUCCESS); +} + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccPortMultiBufferRxCallbackRegister( + IxEthAccPortId portId, + IxEthAccPortMultiBufferRxCallback + rxCallbackFn, + UINT32 callbackTag) +{ + IxEthAccPortId port; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + return (IX_ETH_ACC_INVALID_PORT); + } + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccPortMultiBufferRxCallbackRegister: Unavailable Eth %d: Cannot register Rx Callback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* Check for null function pointer here. */ + if (rxCallbackFn == NULL) + { + return (IX_ETH_ACC_INVALID_ARG); + } + + /* Check the user is not changing the callback type + * when the port is enabled. + */ + if (ixEthAccMacState[portId].portDisableState == ACTIVE) + { + for (port = 0; port < IX_ETH_ACC_NUMBER_OF_PORTS; port++) + { + if ((ixEthAccMacState[port].portDisableState == ACTIVE) + && (ixEthAccPortData[port].ixEthAccRxData.rxMultiBufferCallbackInUse == FALSE)) + { + /* one of the active ports has a different rx callback type. + * Changing the callback type when the port is enabled + * is not safe + */ + return (IX_ETH_ACC_INVALID_ARG); + } + } + } + + /* update the callback pointer : this is done before + * registering the new qmgr callback + */ + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = rxCallbackFn; + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = callbackTag; + + /* update the qmgr callback for rx queues */ + if (ixEthAccQMgrRxCallbacksRegister(ixEthRxMultiBufferQMCallback) + != IX_ETH_ACC_SUCCESS) + { + /* unexpected qmgr error */ + RX_INC(portId,rxUnexpectedError); + + IX_ETH_ACC_FATAL_LOG("ixEthAccPortMultiBufferRxCallbackRegister: unexpected QMgr error, " \ + "could not register Rx multi-buffer callback\n", 0, 0, 0, 0, 0, 0); + + return (IX_ETH_ACC_INVALID_ARG); + } + + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackInUse = TRUE; + + return (IX_ETH_ACC_SUCCESS); +} + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccPortTxFrameSubmit(IxEthAccPortId portId, + IX_OSAL_MBUF *buffer, + IxEthAccTxPriority priority) +{ + IX_STATUS qStatus = IX_SUCCESS; + UINT32 qBuffer; + IxEthAccTxPriority highestPriority; + IxQMgrQStatus txQStatus; + +#ifndef NDEBUG + if (buffer == NULL) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + return (IX_ETH_ACC_INVALID_PORT); + } + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_FATAL_LOG("ixEthAccPortTxFrameSubmit: Unavailable Eth %d: Cannot submit Tx Frame.\n", + (INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_PORT_UNINITIALIZED ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + if ((UINT32)priority > (UINT32)IX_ETH_ACC_TX_PRIORITY_7) + { + return (IX_ETH_ACC_INVALID_ARG); + } +#endif + + /* + * Need to Flush the MBUF and its contents (data) as it may be + * read from the NPE. Convert virtual addresses to physical addresses also. + */ + qBuffer = ixEthAccMbufTxQPrepare(buffer); + + /* + * If no fifo priority set on Xscale ... + */ + if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == + FIFO_NO_PRIORITY) + { + /* + * Add The Tx Buffer to the H/W Tx Q if possible + * (the priority is passed to the NPE, because + * the NPE is able to reorder the frames + * before transmission to the underlying hardware) + */ + qStatus = ixEthAccQmgrTxWrite(portId, + qBuffer, + IX_ETH_ACC_TX_DEFAULT_PRIORITY); + + if (qStatus == IX_SUCCESS) + { + TX_STATS_INC(portId,txQOK); + + /* + * "best case" scenario : Buffer added to h/w Q. + */ + return (IX_SUCCESS); + } + else if (qStatus == IX_QMGR_Q_OVERFLOW) + { + /* + * We were unable to write the buffer to the + * appropriate H/W Q, Save it in the sw Q. + * (use the default priority queue regardless of + * input parameter) + */ + priority = IX_ETH_ACC_TX_DEFAULT_PRIORITY; + } + else + { + /* unexpected qmgr error */ + TX_INC(portId,txUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccPortTxFrameSubmit:Error: qStatus = %u\n", + (UINT32)qStatus, 0, 0, 0, 0, 0); + return (IX_ETH_ACC_FAIL); + } + } + else if (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == + FIFO_PRIORITY) + { + + /* + * For priority transmission, put the frame directly on the H/W queue + * if the H/W queue is empty, otherwise, put it in a S/W Q + */ + ixQMgrQStatusGet(IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), &txQStatus); + if((txQStatus & IX_QMGR_Q_STATUS_E_BIT_MASK) != 0) + { + /*The tx queue is empty, check whether there are buffers on the s/w queues*/ + if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) + !=IX_ETH_ACC_FAIL) + { + /*there are buffers on the s/w queues, submit them*/ + ixEthAccTxFromSwQ(portId, highestPriority); + + /* the queue was empty, 1 buffer is already supplied + * but is likely to be immediately transmitted and the + * hw queue is likely to be empty again, so submit + * more from the sw queues + */ + if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) + !=IX_ETH_ACC_FAIL) + { + ixEthAccTxFromSwQ(portId, highestPriority); + /* + * and force the buffer supplied to be placed + * on a priority queue + */ + qStatus = IX_QMGR_Q_OVERFLOW; + } + else + { + /*there are no buffers in the s/w queues, submit directly*/ + qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority); + } + } + else + { + /*there are no buffers in the s/w queues, submit directly*/ + qStatus = ixEthAccQmgrTxWrite(portId, qBuffer, priority); + } + } + else + { + qStatus = IX_QMGR_Q_OVERFLOW; + } + } + else + { + TX_INC(portId,txUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccPortTxFrameSubmit:Error: wrong schedule discipline setup\n", + 0, 0, 0, 0, 0, 0); + return (IX_ETH_ACC_FAIL); + } + + if(qStatus == IX_SUCCESS ) + { + TX_STATS_INC(portId,txQOK); + return IX_ETH_ACC_SUCCESS; + } + else if(qStatus == IX_QMGR_Q_OVERFLOW) + { + TX_STATS_INC(portId,txQDelayed); + /* + * We were unable to write the buffer to the + * appropriate H/W Q, Save it in a s/w Q. + */ + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL( + ixEthAccPortData[portId]. + ixEthAccTxData.txQ[priority], + buffer); + + qStatus = ixQMgrNotificationEnable( + IX_ETH_ACC_PORT_TO_TX_Q_ID(portId), + IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(portId)); + + if (qStatus != IX_SUCCESS) + { + if (qStatus == IX_QMGR_WARNING) + { + /* notification is enabled for a queue + * which is already empty (the condition is already met) + * and there will be no more queue event to drain the sw queue + */ + TX_STATS_INC(portId,txLateNotificationEnabled); + + /* pull a buffer from the sw queue */ + if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) + !=IX_ETH_ACC_FAIL) + { + /*there are buffers on the s/w queues, submit from them*/ + ixEthAccTxFromSwQ(portId, highestPriority); + } + } + else + { + TX_INC(portId,txUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n", + qStatus, 0, 0, 0, 0, 0); + } + } + } + else + { + TX_INC(portId,txUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccPortTxFrameSubmit: unexpected Error: %u\n", + qStatus, 0, 0, 0, 0, 0); + return (IX_ETH_ACC_FAIL); + } + + return (IX_ETH_ACC_SUCCESS); +} + + +/** + * + * @brief replenish: convert a chain of mbufs to the format + * expected by the NPE + * + */ + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccPortRxFreeReplenish(IxEthAccPortId portId, + IX_OSAL_MBUF *buffer) +{ + IX_STATUS qStatus = IX_SUCCESS; + UINT32 qBuffer; + + /* + * Check buffer is valid. + */ + +#ifndef NDEBUG + /* check parameter value */ + if (buffer == 0) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + return (IX_ETH_ACC_INVALID_PORT); + } + + /* check initialisation is done */ + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_FATAL_LOG(" ixEthAccPortRxFreeReplenish: Unavailable Eth %d: Cannot replenish Rx Free Q.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_PORT_UNINITIALIZED ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + /* check boundaries and constraints */ + if (IX_OSAL_MBUF_MLEN(buffer) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN) + { + return (IX_ETH_ACC_FAIL); + } +#endif + + qBuffer = ixEthAccMbufRxQPrepare(buffer); + + /* + * Add The Rx Buffer to the H/W Free buffer Q if possible + */ + qStatus = ixEthAccQmgrLockRxWrite(portId, qBuffer); + + if (qStatus == IX_SUCCESS) + { + RX_STATS_INC(portId,rxFreeRepOK); + /* + * Buffer added to h/w Q. + */ + return (IX_SUCCESS); + } + else if (qStatus == IX_QMGR_Q_OVERFLOW) + { + RX_STATS_INC(portId,rxFreeRepDelayed); + /* + * We were unable to write the buffer to the approprate H/W Q, + * Save it in a s/w Q. + */ + IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL( + ixEthAccPortData[portId].ixEthAccRxData.freeBufferList, + buffer); + + qStatus = ixQMgrNotificationEnable( + IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId), + IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(portId)); + + if (qStatus != IX_SUCCESS) + { + if (qStatus == IX_QMGR_WARNING) + { + /* notification is enabled for a queue + * which is already empty (the condition is already met) + * and there will be no more queue event to drain the sw queue + * move an entry from the sw queue to the hw queue */ + RX_STATS_INC(portId,rxFreeLateNotificationEnabled); + ixEthAccRxFreeFromSwQ(portId); + } + else + { + RX_INC(portId,rxUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccRxPortFreeReplenish:Error: %u\n", + qStatus, 0, 0, 0, 0, 0); + } + } + } + else + { + RX_INC(portId,rxUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthAccRxPortFreeReplenish:Error: qStatus = %u\n", + (UINT32)qStatus, 0, 0, 0, 0, 0); + return(IX_ETH_ACC_FAIL); + } + return (IX_ETH_ACC_SUCCESS); +} + + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId, + IxEthAccSchedulerDiscipline + sched) +{ + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + return (IX_ETH_ACC_INVALID_PORT); + } + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("ixEthAccTxSchedulingDisciplineSet: Unavailable Eth %d: Cannot set Tx Scheduling Discipline.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY) + { + return (IX_ETH_ACC_INVALID_ARG); + } + + ixEthAccPortData[portId].ixEthAccTxData.schDiscipline = sched; + return (IX_ETH_ACC_SUCCESS); +} + +IX_ETH_ACC_PUBLIC +IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline + sched) +{ + if (sched != FIFO_PRIORITY && sched != FIFO_NO_PRIORITY) + { + return (IX_ETH_ACC_INVALID_ARG); + } + + ixEthAccDataInfo.schDiscipline = sched; + + return (IX_ETH_ACC_SUCCESS); +} + + +/** + * @fn ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr) + * + * @brief process incoming frame : + * + * @param @ref IxQMgrCallback IxQMgrMultiBufferCallback + * + * @return none + * + * @internal + * + */ +IX_ETH_ACC_PRIVATE BOOL +ixEthRxFrameProcess(IxEthAccPortId portId, IX_OSAL_MBUF *mbufPtr) +{ + UINT32 flags; + IxEthDBStatus result; + +#ifndef NDEBUG + /* Prudent to at least check the port is within range */ + if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFrameProcess: Illegal port: %u\n", + (UINT32)portId, 0, 0, 0, 0, 0); + return FALSE; + } +#endif + + /* convert fields from mbuf header */ + ixEthAccMbufFromRxQ(mbufPtr); + + /* check about any special processing for this frame */ + flags = IX_ETHACC_NE_FLAGS(mbufPtr); + if ((flags & (IX_ETHACC_NE_FILTERMASK | IX_ETHACC_NE_NEWSRCMASK)) == 0) + { + /* "best case" scenario : nothing special to do for this frame */ + return TRUE; + } + +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + /* if a new source MAC address is detected by the NPE, + * update IxEthDB with the portId and the MAC address. + */ + if ((flags & IX_ETHACC_NE_NEWSRCMASK & ixEthAccNewSrcMask) != 0) + { + result = ixEthDBFilteringDynamicEntryProvision(portId, + (IxEthDBMacAddr *) IX_ETHACC_NE_SOURCEMAC(mbufPtr)); + + if (result != IX_ETH_DB_SUCCESS && result != IX_ETH_DB_FEATURE_UNAVAILABLE) + { + if ((ixEthAccMacState[portId].portDisableState == ACTIVE) && (result != IX_ETH_DB_BUSY)) + { + RX_STATS_INC(portId, rxUnexpectedError); + IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to add source MAC \ + to the Learning/Filtering database\n", 0, 0, 0, 0, 0, 0); + } + else + { + /* we expect this to fail during PortDisable, as EthDB is disabled for + * that port and will refuse to learn new addresses + */ + } + } + else + { + RX_STATS_INC(portId, rxUnlearnedMacAddress); + } + } +#endif + + /* check if this frame should have been filtered + * by the NPE and take the appropriate action + */ + if (((flags & IX_ETHACC_NE_FILTERMASK) != 0) + && (ixEthAccMacState[portId].portDisableState == ACTIVE)) + { + /* If the mbuf was allocated with a small data size, or the current data pointer is not + * within the allocated data area, then the buffer is non-standard and has to be + * replenished with the minimum size only + */ + if( (IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) < IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN) + || ((UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) > IX_OSAL_MBUF_MDATA(mbufPtr)) + || ((UINT8 *)(IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr) + + IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr)) + < IX_OSAL_MBUF_MDATA(mbufPtr)) ) + { + /* set to minimum length */ + IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) = + IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN; + } + else + { + /* restore original length */ + IX_OSAL_MBUF_MLEN(mbufPtr) = IX_OSAL_MBUF_PKT_LEN(mbufPtr) = + ( IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(mbufPtr) - + (IX_OSAL_MBUF_MDATA(mbufPtr) - (UINT8 *)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(mbufPtr)) ); + } + + /* replenish from here */ + if (ixEthAccPortRxFreeReplenish(portId, mbufPtr) != IX_ETH_ACC_SUCCESS) + { + IX_ETH_ACC_FATAL_LOG("ixEthRxFrameProcess: Failed to replenish with filtered frame\ + on port %d\n", portId, 0, 0, 0, 0, 0); + } + + RX_STATS_INC(portId, rxFiltered); + + /* indicate that frame should not be subjected to further processing */ + return FALSE; + } + + return TRUE; +} + + +/** + * @fn ixEthRxFrameQMCallback + * + * @brief receive callback for Frame receive Q from NPE + * + * Frames are passed one-at-a-time to the user + * + * @param @ref IxQMgrCallback + * + * @return none + * + * @internal + * + * Design note : while processing the entry X, entry X+1 is preloaded + * into memory to reduce the number of stall cycles + * + */ +void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) +{ + IX_OSAL_MBUF *mbufPtr; + IX_OSAL_MBUF *nextMbufPtr; + UINT32 qEntry; + UINT32 nextQEntry; + UINT32 *qEntryPtr; + UINT32 portId; + UINT32 destPortId; + UINT32 npeId; + UINT32 rxQReadStatus; + + /* + * Design note : entries are read in a buffer, This buffer contains + * an extra zeroed entry so the loop will + * always terminate on a null entry, whatever the result of Burst read is. + */ + UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; + + /* + * Indication of the number of times the callback is used. + */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter); + + do + { + /* + * Indication of the number of times the queue is drained + */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead); + + /* ensure the last entry of the array contains a zeroed value */ + qEntryPtr = rxQEntry; + qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0; + + rxQReadStatus = ixQMgrQBurstRead(qId, + IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK, + qEntryPtr); + +#ifndef NDEBUG + if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW) + && (rxQReadStatus != IX_SUCCESS)) + { + ixEthAccDataStats.unexpectedError++; + /*major error*/ + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFrameQMCallback:Error: %u\n", + (UINT32)rxQReadStatus, 0, 0, 0, 0, 0); + return; + } +#endif + + /* convert and preload the next entry + * (the conversion function takes care about null pointers which + * are used to mark the end of the loop) + */ + nextQEntry = *qEntryPtr; + nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, + IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); + + while(nextQEntry != 0) + { + /* get the next entry */ + qEntry = nextQEntry; + mbufPtr = nextMbufPtr; + +#ifndef NDEBUG + if (mbufPtr == NULL) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFrameQMCallback: Null Mbuf Ptr\n", + 0, 0, 0, 0, 0, 0); + return; + } +#endif + + /* convert the next entry + * (the conversion function takes care about null pointers which + * are used to mark the end of the loop) + */ + nextQEntry = *(++qEntryPtr); + nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, + IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); + + /* + * Get Port and Npe ID from message. + */ + npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK & + qEntry) >> IX_ETHNPE_QM_Q_FIELD_NPEID_R); + portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); + + /* process frame, check the return code and skip the remaining of + * the loop if the frame is to be filtered out + */ + if (ixEthRxFrameProcess(portId, mbufPtr)) + { + /* destination portId for this packet */ + destPortId = IX_ETHACC_NE_DESTPORTID(mbufPtr); + + if (destPortId != IX_ETH_DB_UNKNOWN_PORT) + { + destPortId = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(destPortId); + } + + /* test if QoS is enabled in ethAcc + */ + if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY) + { + /* check if there is a higher priority queue + * which may require processing and then process it. + */ + if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES) + { + ixEthRxFrameQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId], + callbackId); + } + } + + /* + * increment priority stats + */ + RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]); + + /* + * increment callback count stats + */ + RX_STATS_INC(portId,rxFrameClientCallback); + + /* + * Call user level callback. + */ + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn( + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag, + mbufPtr, + destPortId); + } + } + } while (rxQReadStatus == IX_SUCCESS); +} + +/** + * @fn ixEthRxMultiBufferQMCallback + * + * @brief receive callback for Frame receive Q from NPE + * + * Frames are passed as an array to the user + * + * @param @ref IxQMgrCallback + * + * @return none + * + * @internal + * + * Design note : while processing the entry X, entry X+1 is preloaded + * into memory to reduce the number of stall cycles + * + */ +void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) +{ + IX_OSAL_MBUF *mbufPtr; + IX_OSAL_MBUF *nextMbufPtr; + UINT32 qEntry; + UINT32 nextQEntry; + UINT32 *qEntryPtr; + UINT32 portId; + UINT32 npeId; + UINT32 rxQReadStatus; + /* + * Design note : entries are read in a static buffer, This buffer contains + * an extra zeroed entry so the loop will + * always terminate on a null entry, whatever the result of Burst read is. + */ + static UINT32 rxQEntry[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; + static IX_OSAL_MBUF *rxMbufPortArray[IX_ETH_ACC_NUMBER_OF_PORTS][IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK + 1]; + IX_OSAL_MBUF **rxMbufPtr[IX_ETH_ACC_NUMBER_OF_PORTS]; + + for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + rxMbufPtr[portId] = rxMbufPortArray[portId]; + } + + /* + * Indication of the number of times the callback is used. + */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackCounter); + + do + { + /* + * Indication of the number of times the queue is drained + */ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.rxCallbackBurstRead); + + /* ensure the last entry of the array contains a zeroed value */ + qEntryPtr = rxQEntry; + qEntryPtr[IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK] = 0; + + rxQReadStatus = ixQMgrQBurstRead(qId, + IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK, + qEntryPtr); + +#ifndef NDEBUG + if ((rxQReadStatus != IX_QMGR_Q_UNDERFLOW) + && (rxQReadStatus != IX_SUCCESS)) + { + ixEthAccDataStats.unexpectedError++; + /*major error*/ + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFrameMultiBufferQMCallback:Error: %u\n", + (UINT32)rxQReadStatus, 0, 0, 0, 0, 0); + return; + } +#endif + + /* convert and preload the next entry + * (the conversion function takes care about null pointers which + * are used to mark the end of the loop) + */ + nextQEntry = *qEntryPtr; + nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, + IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); + + while(nextQEntry != 0) + { + /* get the next entry */ + qEntry = nextQEntry; + mbufPtr = nextMbufPtr; + +#ifndef NDEBUG + if (mbufPtr == NULL) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFrameMultiBufferQMCallback:Error: Null Mbuf Ptr\n", + 0, 0, 0, 0, 0, 0); + return; + } +#endif + + /* convert the next entry + * (the conversion function takes care about null pointers which + * are used to mark the end of the loop) + */ + nextQEntry = *(++qEntryPtr); + nextMbufPtr = ixEthAccEntryFromQConvert(nextQEntry, + IX_ETHNPE_QM_Q_RXENET_ADDR_MASK); + + /* + * Get Port and Npe ID from message. + */ + npeId = ((IX_ETHNPE_QM_Q_RXENET_NPEID_MASK & + qEntry) >> + IX_ETHNPE_QM_Q_FIELD_NPEID_R); + portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); + + /* skip the remaining of the loop if the frame is + * to be filtered out + */ + if (ixEthRxFrameProcess(portId, mbufPtr)) + { + /* store a mbuf pointer in an array */ + *rxMbufPtr[portId]++ = mbufPtr; + + /* + * increment priority stats + */ + RX_STATS_INC(portId,rxPriority[IX_ETHACC_NE_QOS(mbufPtr)]); + } + + /* test for QoS enabled in ethAcc */ + if (ixEthAccDataInfo.schDiscipline == FIFO_PRIORITY) + { + /* check if there is a higher priority queue + * which may require processing and then process it. + */ + if (ixEthAccDataInfo.higherPriorityQueue[qId] < IX_QMGR_MAX_NUM_QUEUES) + { + ixEthRxMultiBufferQMCallback(ixEthAccDataInfo.higherPriorityQueue[qId], + callbackId); + } + } + } + + /* check if any of the the arrays contains any entry */ + for (portId = 0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + if (rxMbufPtr[portId] != rxMbufPortArray[portId]) + { + /* add a last NULL pointer at the end of the + * array of mbuf pointers + */ + *rxMbufPtr[portId] = NULL; + + /* + * increment callback count stats + */ + RX_STATS_INC(portId,rxFrameClientCallback); + + /* + * Call user level callback with an array of + * buffers (NULL terminated) + */ + ixEthAccPortData[portId].ixEthAccRxData. + rxMultiBufferCallbackFn( + ixEthAccPortData[portId].ixEthAccRxData. + rxMultiBufferCallbackTag, + rxMbufPortArray[portId]); + + /* reset the buffer pointer to the beginning of + * the array + */ + rxMbufPtr[portId] = rxMbufPortArray[portId]; + } + } + + } while (rxQReadStatus == IX_SUCCESS); +} + + +/** + * @brief rxFree low event handler + * + */ +void ixEthRxFreeQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) +{ + IxEthAccPortId portId = (IxEthAccPortId) callbackId; + int lockVal; + UINT32 maxQWritesToPerform = IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD; + IX_STATUS qStatus = IX_SUCCESS; + + /* + * We have reached a low threshold on one of the Rx Free Qs + */ + + /*note that due to the fact that we are working off an Empty threshold, this callback + need only write a single entry to the Rx Free queue in order to re-arm the notification + */ + + RX_STATS_INC(portId,rxFreeLowCallback); + + /* + * Get buffers from approprite S/W Rx freeBufferList Q. + */ + +#ifndef NDEBUG + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFreeQMCallback:Error: Invalid Port 0x%08X\n", + portId, 0, 0, 0, 0, 0); + return; + } +#endif + IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); + if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. + ixEthAccRxData.freeBufferList)) + { + /* + * Turn off Q callback notification for Q in Question. + */ + qStatus = ixQMgrNotificationDisable( + IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId)); + + + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); + + if (qStatus != IX_SUCCESS) + { + RX_INC(portId,rxUnexpectedError); + IX_ETH_ACC_FATAL_LOG( + "ixEthRxFreeQMCallback:Error: unexpected QM status 0x%08X\n", + qStatus, 0, 0, 0, 0, 0); + return; + } + } + else + { + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); + /* + * Load the H/W Q with buffers from the s/w Q. + */ + + do + { + /* + * Consume Q entries. - Note Q contains Physical addresss, + * and have already been flushed to memory, + * And endianess converted if required. + */ + if (ixEthAccRxFreeFromSwQ(portId) != IX_SUCCESS) + { + /* + * No more entries in s/w Q. + * Turn off Q callback indication + */ + + IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); + if (IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(ixEthAccPortData[portId]. + ixEthAccRxData.freeBufferList)) + { + qStatus = ixQMgrNotificationDisable( + IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(portId)); + } + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); + break; + } + } + while (--maxQWritesToPerform); + } +} +/** + * @fn Tx queue low event handler + * + */ +void +ixEthTxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) +{ + IxEthAccPortId portId = (IxEthAccPortId) callbackId; + int lockVal; + UINT32 maxQWritesToPerform = IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK; + IX_STATUS qStatus = IX_SUCCESS; + IxEthAccTxPriority highestPriority; + + + /* + * We have reached a low threshold on the Tx Q, and are being asked to + * supply a buffer for transmission from our S/W TX queues + */ + TX_STATS_INC(portId,txLowThreshCallback); + + /* + * Get buffers from approprite Q. + */ + +#ifndef NDEBUG + if (!IX_ETH_ACC_IS_PORT_VALID(portId)) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthTxFrameQMCallback:Error: Invalid Port 0x%08X\n", + portId, 0, 0, 0, 0, 0); + return; + } +#endif + + do + { + /* + * Consume Q entries. - Note Q contains Physical addresss, + * and have already been flushed to memory, + * and endianess already sone if required. + */ + + IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); + + if(ixEthAccTxSwQHighestPriorityGet(portId, &highestPriority) == + IX_ETH_ACC_FAIL) + { + /* + * No more entries in s/w Q. + * Turn off Q callback indication + */ + qStatus = ixQMgrNotificationDisable( + IX_ETH_ACC_PORT_TO_TX_Q_ID(portId)); + + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); + + if (qStatus != IX_SUCCESS) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthTxFrameQMCallback:Error: unexpected QM status 0x%08X\n", + qStatus, 0, 0, 0, 0, 0); + } + + return; + } + else + { + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); + if (ixEthAccTxFromSwQ(portId,highestPriority)!=IX_SUCCESS) + { + /* nothing left in the sw queue or the hw queues are + * full. There is no point to continue to drain the + * sw queues + */ + return; + } + } + } + while (--maxQWritesToPerform); +} + +/** + * @brief TxDone event handler + * + * Design note : while processing the entry X, entry X+1 is preloaded + * into memory to reduce the number of stall cycles + * + */ + +void +ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId) +{ + IX_OSAL_MBUF *mbufPtr; + UINT32 qEntry; + UINT32 *qEntryPtr; + UINT32 txDoneQReadStatus; + UINT32 portId; + UINT32 npeId; + + /* + * Design note : entries are read in a static buffer, This buffer contains + * an extra entyry (which is zeroed by the compiler), so the loop will + * always terminate on a null entry, whatever the result of Burst read is. + */ + static UINT32 txDoneQEntry[IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK + 1]; + + /* + * Indication that Tx frames have been transmitted from the NPE. + */ + + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.txDoneCallbackCounter); + + do{ + qEntryPtr = txDoneQEntry; + txDoneQReadStatus = ixQMgrQBurstRead(IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, + IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK, + qEntryPtr); + +#ifndef NDEBUG + if (txDoneQReadStatus != IX_QMGR_Q_UNDERFLOW + && (txDoneQReadStatus != IX_SUCCESS)) + { + /*major error*/ + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthTxFrameDoneQMCallback:Error: %u\n", + (UINT32)txDoneQReadStatus, 0, 0, 0, 0, 0); + return; + } +#endif + + qEntry = *qEntryPtr; + + while(qEntry != 0) + { + mbufPtr = ixEthAccEntryFromQConvert(qEntry, + IX_ETHNPE_QM_Q_TXENET_ADDR_MASK); + +#ifndef NDEBUG + if (mbufPtr == NULL) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthTxFrameDoneQMCallback:Error: Null Mbuf Ptr\n", + 0, 0, 0, 0, 0, 0); + return; + } +#endif + + /* endianness conversions and stats updates */ + ixEthAccMbufFromTxQ(mbufPtr); + + /* + * Get NPE id from message, then convert to portId. + */ + npeId = ((IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK & + qEntry) >> + IX_ETHNPE_QM_Q_FIELD_NPEID_R); + portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); + +#ifndef NDEBUG + /* Prudent to at least check the port is within range */ + if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) + { + ixEthAccDataStats.unexpectedError++; + IX_ETH_ACC_FATAL_LOG( + "ixEthTxFrameDoneQMCallback: Illegal port: %u\n", + (UINT32)portId, 0, 0, 0, 0, 0); + return; + } +#endif + + TX_STATS_INC(portId,txDoneClientCallback); + + /* + * Call user level callback. + */ + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn( + ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag, + mbufPtr); + + /* move to next queue entry */ + qEntry = *(++qEntryPtr); + + } + } while( txDoneQReadStatus == IX_SUCCESS ); +} + +IX_ETH_ACC_PUBLIC +void ixEthAccDataPlaneShow(void) +{ + UINT32 numTx0Entries; + UINT32 numTx1Entries; + UINT32 numTxDoneEntries; + UINT32 numRxEntries; + UINT32 numRxFree0Entries; + UINT32 numRxFree1Entries; + UINT32 portId; +#ifdef __ixp46X + UINT32 numTx2Entries; + UINT32 numRxFree2Entries; +#endif +#ifndef NDEBUG + UINT32 priority; + UINT32 numBuffersInRx=0; + UINT32 numBuffersInTx=0; + UINT32 numBuffersInSwQ=0; + UINT32 totalBuffers=0; + UINT32 rxFreeCallbackCounter = 0; + UINT32 txCallbackCounter = 0; +#endif + UINT32 key; + + /* snapshot of stats */ + IxEthAccTxDataStats tx[IX_ETH_ACC_NUMBER_OF_PORTS]; + IxEthAccRxDataStats rx[IX_ETH_ACC_NUMBER_OF_PORTS]; + IxEthAccDataPlaneStats stats; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return; + } + + /* get a reliable snapshot */ + key = ixOsalIrqLock(); + + numTx0Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET0_Q, &numTx0Entries); + numTx1Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET1_Q, &numTx1Entries); + numTxDoneEntries = 0; + ixQMgrQNumEntriesGet( IX_ETH_ACC_TX_FRAME_DONE_ETH_Q, &numTxDoneEntries); + numRxEntries = 0; + ixEthAccQMgrRxQEntryGet(&numRxEntries); + numRxFree0Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q, &numRxFree0Entries); + numRxFree1Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q, &numRxFree1Entries); + +#ifdef __ixp46X + numTx2Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_TX_FRAME_ENET2_Q, &numTx2Entries); + numRxFree2Entries = 0; + ixQMgrQNumEntriesGet(IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q, &numRxFree2Entries); +#endif + + for(portId=IX_ETH_PORT_1; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + memcpy(&tx[portId], + &ixEthAccPortData[portId].ixEthAccTxData.stats, + sizeof(tx[portId])); + memcpy(&rx[portId], + &ixEthAccPortData[portId].ixEthAccRxData.stats, + sizeof(rx[portId])); + } + memcpy(&stats, &ixEthAccDataStats, sizeof(stats)); + + ixOsalIrqUnlock(key); + +#ifdef NDEBUG + printf("Detailed statistics collection not supported in this load\n"); +#endif + + /* print snapshot */ + for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */ + if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != + (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) + || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) + { + if ((IX_ETH_PORT_1 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + continue ; + } + if ((IX_ETH_PORT_2 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + continue ; + } + if ((IX_ETH_PORT_3 == portId) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + continue ; + } + } + + printf("PORT %u --------------------------------\n", + portId); +#ifndef NDEBUG + printf("Tx Done Frames : %u\n", + tx[portId].txDoneClientCallback + + tx[portId].txDoneSwQDuringDisable + + tx[portId].txDoneDuringDisable); + printf("Tx Frames : %u\n", + tx[portId].txQOK + tx[portId].txQDelayed); + printf("Tx H/W Q Added OK : %u\n", + tx[portId].txQOK); + printf("Tx H/W Q Delayed : %u\n", + tx[portId].txQDelayed); + printf("Tx From S/W Q Added OK : %u\n", + tx[portId].txFromSwQOK); + printf("Tx From S/W Q Delayed : %u\n", + tx[portId].txFromSwQDelayed); + printf("Tx Overflow : %u\n", + tx[portId].txOverflow); + printf("Tx Mutual Lock : %u\n", + tx[portId].txLock); + printf("Tx Late Ntf Enabled : %u\n", + tx[portId].txLateNotificationEnabled); + printf("Tx Low Thresh CB : %u\n", + tx[portId].txLowThreshCallback); + printf("Tx Done from H/W Q (Disable) : %u\n", + tx[portId].txDoneDuringDisable); + printf("Tx Done from S/W Q (Disable) : %u\n", + tx[portId].txDoneSwQDuringDisable); + for (priority = IX_ETH_ACC_TX_PRIORITY_0; + priority <= IX_ETH_ACC_TX_PRIORITY_7; + priority++) + { + if (tx[portId].txPriority[priority]) + { + printf("Tx Priority %u : %u\n", + priority, + tx[portId].txPriority[priority]); + } + } +#endif + printf("Tx unexpected errors : %u (should be 0)\n", + tx[portId].txUnexpectedError); + +#ifndef NDEBUG + printf("Rx Frames : %u\n", + rx[portId].rxFrameClientCallback + + rx[portId].rxSwQDuringDisable+ + rx[portId].rxDuringDisable); + printf("Rx Free Replenish : %u\n", + rx[portId].rxFreeRepOK + rx[portId].rxFreeRepDelayed); + printf("Rx Free H/W Q Added OK : %u\n", + rx[portId].rxFreeRepOK); + printf("Rx Free H/W Q Delayed : %u\n", + rx[portId].rxFreeRepDelayed); + printf("Rx Free From S/W Q Added OK : %u\n", + rx[portId].rxFreeRepFromSwQOK); + printf("Rx Free From S/W Q Delayed : %u\n", + rx[portId].rxFreeRepFromSwQDelayed); + printf("Rx Free Overflow : %u\n", + rx[portId].rxFreeOverflow); + printf("Rx Free Mutual Lock : %u\n", + rx[portId].rxFreeLock); + printf("Rx Free Late Ntf Enabled : %u\n", + rx[portId].rxFreeLateNotificationEnabled); + printf("Rx Free Low CB : %u\n", + rx[portId].rxFreeLowCallback); + printf("Rx From H/W Q (Disable) : %u\n", + rx[portId].rxDuringDisable); + printf("Rx From S/W Q (Disable) : %u\n", + rx[portId].rxSwQDuringDisable); + printf("Rx unlearned Mac Address : %u\n", + rx[portId].rxUnlearnedMacAddress); + printf("Rx Filtered (Rx => RxFree) : %u\n", + rx[portId].rxFiltered); + + for (priority = IX_ETH_ACC_TX_PRIORITY_0; + priority <= IX_ETH_ACC_TX_PRIORITY_7; + priority++) + { + if (rx[portId].rxPriority[priority]) + { + printf("Rx Priority %u : %u\n", + priority, + rx[portId].rxPriority[priority]); + } + } +#endif + printf("Rx unexpected errors : %u (should be 0)\n", + rx[portId].rxUnexpectedError); + +#ifndef NDEBUG + numBuffersInTx = tx[portId].txQOK + + tx[portId].txQDelayed - + tx[portId].txDoneClientCallback - + tx[portId].txDoneSwQDuringDisable - + tx[portId].txDoneDuringDisable; + + printf("# Tx Buffers currently for transmission : %u\n", + numBuffersInTx); + + numBuffersInRx = rx[portId].rxFreeRepOK + + rx[portId].rxFreeRepDelayed - + rx[portId].rxFrameClientCallback - + rx[portId].rxSwQDuringDisable - + rx[portId].rxDuringDisable; + + printf("# Rx Buffers currently for reception : %u\n", + numBuffersInRx); + + totalBuffers += numBuffersInRx + numBuffersInTx; +#endif + } + + printf("---------------------------------------\n"); + +#ifndef NDEBUG + printf("\n"); + printf("Mbufs :\n"); + printf("Tx Unchained mbufs : %u\n", + stats.unchainedTxMBufs); + printf("Tx Chained bufs : %u\n", + stats.chainedTxMBufs); + printf("TxDone Unchained mbufs : %u\n", + stats.unchainedTxDoneMBufs); + printf("TxDone Chained bufs : %u\n", + stats.chainedTxDoneMBufs); + printf("RxFree Unchained mbufs : %u\n", + stats.unchainedRxFreeMBufs); + printf("RxFree Chained bufs : %u\n", + stats.chainedRxFreeMBufs); + printf("Rx Unchained mbufs : %u\n", + stats.unchainedRxMBufs); + printf("Rx Chained bufs : %u\n", + stats.chainedRxMBufs); + + printf("\n"); + printf("Software queue usage :\n"); + printf("Buffers added to S/W Q : %u\n", + stats.addToSwQ); + printf("Buffers removed from S/W Q : %u\n", + stats.removeFromSwQ); + + printf("\n"); + printf("Hardware queues callbacks :\n"); + + for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + rxFreeCallbackCounter += rx[portId].rxFreeLowCallback; + txCallbackCounter += tx[portId].txLowThreshCallback; + } + printf("Tx Done QM Callback invoked : %u\n", + stats.txDoneCallbackCounter); + printf("Tx QM Callback invoked : %u\n", + txCallbackCounter); + printf("Rx QM Callback invoked : %u\n", + stats.rxCallbackCounter); + printf("Rx QM Callback burst read : %u\n", + stats.rxCallbackBurstRead); + printf("Rx Free QM Callback invoked : %u\n", + rxFreeCallbackCounter); +#endif + printf("Unexpected errors in CB : %u (should be 0)\n", + stats.unexpectedError); + printf("\n"); + + printf("Hardware queues levels :\n"); + printf("Transmit Port 1 Q : %u \n",numTx0Entries); + printf("Transmit Port 2 Q : %u \n",numTx1Entries); +#ifdef __ixp46X + printf("Transmit Port 3 Q : %u \n",numTx2Entries); +#endif + printf("Transmit Done Q : %u \n",numTxDoneEntries); + printf("Receive Q : %u \n",numRxEntries); + printf("Receive Free Port 1 Q : %u \n",numRxFree0Entries); + printf("Receive Free Port 2 Q : %u \n",numRxFree1Entries); +#ifdef __ixp46X + printf("Receive Free Port 3 Q : %u \n",numRxFree2Entries); +#endif + +#ifndef NDEBUG + printf("\n"); + printf("# Total Buffers accounted for : %u\n", + totalBuffers); + + numBuffersInSwQ = ixEthAccDataStats.addToSwQ - + ixEthAccDataStats.removeFromSwQ; + + printf(" Buffers in S/W Qs : %u\n", + numBuffersInSwQ); + printf(" Buffers in H/W Qs or NPEs : %u\n", + totalBuffers - numBuffersInSwQ); +#endif + + printf("Rx QoS Discipline : %s\n", + (ixEthAccDataInfo.schDiscipline == + FIFO_PRIORITY ) ? "Enabled" : "Disabled"); + + for(portId=0; portId < IX_ETH_ACC_NUMBER_OF_PORTS; portId++) + { + printf("Tx QoS Discipline port %u : %s\n", + portId, + (ixEthAccPortData[portId].ixEthAccTxData.schDiscipline == + FIFO_PRIORITY ) ? "Enabled" : "Disabled"); + } + printf("\n"); +} + + + + + diff --git a/drivers/net/npe/IxEthAccMac.c b/drivers/net/npe/IxEthAccMac.c new file mode 100644 index 0000000..369ee91 --- /dev/null +++ b/drivers/net/npe/IxEthAccMac.c @@ -0,0 +1,2641 @@ +/** + * @file IxEthAccMac.c + * + * @author Intel Corporation + * @date + * + * @brief MAC control functions + * + * Design Notes: + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxOsal.h" +#include "IxNpeMh.h" +#ifdef CONFIG_IXP425_COMPONENT_ETHDB +#include "IxEthDB.h" +#endif +#include "IxEthDBPortDefs.h" +#include "IxEthNpe.h" +#include "IxEthAcc.h" +#include "IxEthAccDataPlane_p.h" +#include "IxEthAcc_p.h" +#include "IxEthAccMac_p.h" + +/* Maximum number of retries during ixEthAccPortDisable, which + * is approximately 10 seconds +*/ +#define IX_ETH_ACC_MAX_RETRY 500 + +/* Maximum number of retries during ixEthAccPortDisable when expecting + * timeout + */ +#define IX_ETH_ACC_MAX_RETRY_TIMEOUT 5 + +#define IX_ETH_ACC_VALIDATE_PORT_ID(portId) \ + do \ + { \ + if(!IX_ETH_ACC_IS_PORT_VALID(portId)) \ + { \ + return IX_ETH_ACC_INVALID_PORT; \ + } \ + } while(0) + +PUBLIC IxEthAccMacState ixEthAccMacState[IX_ETH_ACC_NUMBER_OF_PORTS]; + +PRIVATE UINT32 ixEthAccMacBase[IX_ETH_ACC_NUMBER_OF_PORTS]; + +/*Forward function declarations*/ +PRIVATE void +ixEthAccPortDisableRx (IxEthAccPortId portId, + IX_OSAL_MBUF * mBufPtr, + BOOL useMultiBufferCallback); + +PRIVATE void +ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId, + IX_OSAL_MBUF * mBufPtr, + BOOL useMultiBufferCallback); + +PRIVATE void +ixEthAccPortDisableTxDone (UINT32 cbTag, + IX_OSAL_MBUF *mbuf); + +PRIVATE void +ixEthAccPortDisableTxDoneAndSubmit (UINT32 cbTag, + IX_OSAL_MBUF *mbuf); + +PRIVATE void +ixEthAccPortDisableRxCallback (UINT32 cbTag, + IX_OSAL_MBUF * mBufPtr, + UINT32 learnedPortId); + +PRIVATE void +ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag, + IX_OSAL_MBUF **mBufPtr); + +PRIVATE IxEthAccStatus +ixEthAccPortDisableTryTransmit(UINT32 portId); + +PRIVATE IxEthAccStatus +ixEthAccPortDisableTryReplenish(UINT32 portId); + +PRIVATE IxEthAccStatus +ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + +PRIVATE IxEthAccStatus +ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + +PRIVATE void +ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId, + IxNpeMhMessage msg); + +PRIVATE void +ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId, + IxNpeMhMessage msg); + +PRIVATE void +ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId, + IxNpeMhMessage msg); + +PRIVATE void +ixEthAccMulticastAddressSet(IxEthAccPortId portId); + +PRIVATE BOOL +ixEthAccMacEqual(IxEthAccMacAddr *macAddr1, + IxEthAccMacAddr *macAddr2); + +PRIVATE void +ixEthAccMacPrint(IxEthAccMacAddr *m); + +PRIVATE void +ixEthAccMacStateUpdate(IxEthAccPortId portId); + +IxEthAccStatus +ixEthAccMacMemInit(void) +{ + ixEthAccMacBase[IX_ETH_PORT_1] = + (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, + IX_OSAL_IXP400_ETHA_MAP_SIZE); + ixEthAccMacBase[IX_ETH_PORT_2] = + (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_1_BASE, + IX_OSAL_IXP400_ETHB_MAP_SIZE); +#ifdef __ixp46X + ixEthAccMacBase[IX_ETH_PORT_3] = + (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_2_BASE, + IX_OSAL_IXP400_ETH_NPEA_MAP_SIZE); + if (ixEthAccMacBase[IX_ETH_PORT_3] == 0) + { + ixOsalLog(IX_OSAL_LOG_LVL_FATAL, + IX_OSAL_LOG_DEV_STDOUT, + "EthAcc: Could not map MAC I/O memory\n", + 0, 0, 0, 0, 0 ,0); + + return IX_ETH_ACC_FAIL; + } +#endif + + if (ixEthAccMacBase[IX_ETH_PORT_1] == 0 + || ixEthAccMacBase[IX_ETH_PORT_2] == 0) + { + ixOsalLog(IX_OSAL_LOG_LVL_FATAL, + IX_OSAL_LOG_DEV_STDOUT, + "EthAcc: Could not map MAC I/O memory\n", + 0, 0, 0, 0, 0 ,0); + + return IX_ETH_ACC_FAIL; + } + + return IX_ETH_ACC_SUCCESS; +} + +void +ixEthAccMacUnload(void) +{ + IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_1]); + IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_2]); +#ifdef __ixp46X + IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_3]); + ixEthAccMacBase[IX_ETH_PORT_3] = 0; +#endif + ixEthAccMacBase[IX_ETH_PORT_2] = 0; + ixEthAccMacBase[IX_ETH_PORT_1] = 0; +} + +IxEthAccStatus +ixEthAccPortEnablePriv(IxEthAccPortId portId) +{ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + printf("EthAcc: (Mac) cannot enable port %d, port not initialized\n", portId); + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + if (ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn == NULL) + { + /* TxDone callback not registered */ + printf("EthAcc: (Mac) cannot enable port %d, TxDone callback not registered\n", portId); + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + if ((ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn == NULL) + && (ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn == NULL)) + { + /* Receive callback not registered */ + printf("EthAcc: (Mac) cannot enable port %d, Rx callback not registered\n", portId); + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + if(!ixEthAccMacState[portId].initDone) + { + printf("EthAcc: (Mac) cannot enable port %d, MAC address not set\n", portId); + return (IX_ETH_ACC_MAC_UNINITIALIZED); + } + + /* if the state is being set to what it is already at, do nothing*/ + if (ixEthAccMacState[portId].enabled) + { + return IX_ETH_ACC_SUCCESS; + } + +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + /* enable ethernet database for this port */ + if (ixEthDBPortEnable(portId) != IX_ETH_DB_SUCCESS) + { + printf("EthAcc: (Mac) cannot enable port %d, EthDB failure\n", portId); + return IX_ETH_ACC_FAIL; + } +#endif + + /* set the MAC core registers */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL2, + IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RANDOM_SEED, + IX_ETH_ACC_RANDOM_SEED_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_THRESH_P_EMPTY, + IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_THRESH_P_FULL, + IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_DEFER, + IX_ETH_ACC_MAC_TX_DEFER_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_TWO_DEFER_1, + IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_TWO_DEFER_2, + IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_SLOT_TIME, + IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_INT_CLK_THRESH, + IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_BUF_SIZE_TX, + IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + IX_ETH_ACC_TX_CNTRL1_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + IX_ETH_ACC_RX_CNTRL1_DEFAULT); + + /* set the global state */ + ixEthAccMacState[portId].portDisableState = ACTIVE; + ixEthAccMacState[portId].enabled = TRUE; + + /* rewrite the setup (including mac filtering) depending + * on current options + */ + ixEthAccMacStateUpdate(portId); + + return IX_ETH_ACC_SUCCESS; +} + +/* + * PortDisable local variables. They contain the intermediate steps + * while the port is being disabled and the buffers being drained out + * of the NPE. + */ +typedef void (*IxEthAccPortDisableRx)(IxEthAccPortId portId, + IX_OSAL_MBUF * mBufPtr, + BOOL useMultiBufferCallback); +static IxEthAccPortRxCallback +ixEthAccPortDisableFn[IX_ETH_ACC_NUMBER_OF_PORTS]; +static IxEthAccPortMultiBufferRxCallback +ixEthAccPortDisableMultiBufferFn[IX_ETH_ACC_NUMBER_OF_PORTS]; +static IxEthAccPortDisableRx +ixEthAccPortDisableRxTable[IX_ETH_ACC_NUMBER_OF_PORTS]; +static UINT32 +ixEthAccPortDisableCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; +static UINT32 +ixEthAccPortDisableMultiBufferCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; + +static IxEthAccPortTxDoneCallback +ixEthAccPortDisableTxDoneFn[IX_ETH_ACC_NUMBER_OF_PORTS]; +static UINT32 +ixEthAccPortDisableTxDoneCbTag[IX_ETH_ACC_NUMBER_OF_PORTS]; + +static UINT32 +ixEthAccPortDisableUserBufferCount[IX_ETH_ACC_NUMBER_OF_PORTS]; + +/* + * PortDisable private callbacks functions. They handle the user + * traffic, and the special buffers (one for tx, one for rx) used + * in portDisable. + */ +PRIVATE void +ixEthAccPortDisableTxDone(UINT32 cbTag, + IX_OSAL_MBUF *mbuf) +{ + IxEthAccPortId portId = (IxEthAccPortId)cbTag; + volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; + + /* check for the special mbuf used in portDisable */ + if (mbuf == ixEthAccMacState[portId].portDisableTxMbufPtr) + { + *txState = TRANSMIT_DONE; + } + else + { + /* increment the count of user traffic during portDisable */ + ixEthAccPortDisableUserBufferCount[portId]++; + + /* call client TxDone function */ + ixEthAccPortDisableTxDoneFn[portId](ixEthAccPortDisableTxDoneCbTag[portId], mbuf); + } +} + +PRIVATE IxEthAccStatus +ixEthAccPortDisableTryTransmit(UINT32 portId) +{ + int key; + IxEthAccStatus status = IX_ETH_ACC_SUCCESS; + volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; + /* transmit the special buffer again if it is transmitted + * and update the txState + * This section is protected because the portDisable context + * run an identical code, so the system keeps transmitting at the + * maximum rate. + */ + key = ixOsalIrqLock(); + if (*txState == TRANSMIT_DONE) + { + IX_OSAL_MBUF *mbufTxPtr = ixEthAccMacState[portId].portDisableTxMbufPtr; + *txState = TRANSMIT; + status = ixEthAccPortTxFrameSubmit(portId, + mbufTxPtr, + IX_ETH_ACC_TX_DEFAULT_PRIORITY); + } + ixOsalIrqUnlock(key); + + return status; +} + +PRIVATE void +ixEthAccPortDisableTxDoneAndSubmit(UINT32 cbTag, + IX_OSAL_MBUF *mbuf) +{ + IxEthAccPortId portId = (IxEthAccPortId)cbTag; + + /* call the callback which forwards the traffic to the client */ + ixEthAccPortDisableTxDone(cbTag, mbuf); + + /* try to transmit the buffer used in portDisable + * if seen in TxDone + */ + ixEthAccPortDisableTryTransmit(portId); +} + +PRIVATE void +ixEthAccPortDisableRx (IxEthAccPortId portId, + IX_OSAL_MBUF * mBufPtr, + BOOL useMultiBufferCallback) +{ + volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; + IX_OSAL_MBUF *mNextPtr; + + while (mBufPtr) + { + mNextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr); + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr) = NULL; + + /* check for the special mbuf used in portDisable */ + if (mBufPtr == ixEthAccMacState[portId].portDisableRxMbufPtr) + { + *rxState = RECEIVE; + } + else + { + /* increment the count of user traffic during portDisable */ + ixEthAccPortDisableUserBufferCount[portId]++; + + /* reset the received payload length during portDisable */ + IX_OSAL_MBUF_MLEN(mBufPtr) = 0; + IX_OSAL_MBUF_PKT_LEN(mBufPtr) = 0; + + if (useMultiBufferCallback) + { + /* call the user callback with one unchained + * buffer, without payload. A small array is built + * to be used as a parameter (the user callback expects + * to receive an array ended by a NULL pointer. + */ + IX_OSAL_MBUF *mBufPtrArray[2]; + + mBufPtrArray[0] = mBufPtr; + mBufPtrArray[1] = NULL; + ixEthAccPortDisableMultiBufferFn[portId]( + ixEthAccPortDisableMultiBufferCbTag[portId], + mBufPtrArray); + } + else + { + /* call the user callback with a unchained + * buffer, without payload and the destination port is + * unknown. + */ + ixEthAccPortDisableFn[portId]( + ixEthAccPortDisableCbTag[portId], + mBufPtr, + IX_ETH_DB_UNKNOWN_PORT /* port not found */); + } + } + + mBufPtr = mNextPtr; + } +} + +PRIVATE IxEthAccStatus +ixEthAccPortDisableTryReplenish(UINT32 portId) +{ + int key; + IxEthAccStatus status = IX_ETH_ACC_SUCCESS; + volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; + /* replenish with the special buffer again if it is received + * and update the rxState + * This section is protected because the portDisable context + * run an identical code, so the system keeps replenishing at the + * maximum rate. + */ + key = ixOsalIrqLock(); + if (*rxState == RECEIVE) + { + IX_OSAL_MBUF *mbufRxPtr = ixEthAccMacState[portId].portDisableRxMbufPtr; + *rxState = REPLENISH; + IX_OSAL_MBUF_MLEN(mbufRxPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE; + status = ixEthAccPortRxFreeReplenish(portId, mbufRxPtr); + } + ixOsalIrqUnlock(key); + + return status; +} + +PRIVATE void +ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId, + IX_OSAL_MBUF * mBufPtr, + BOOL useMultiBufferCallback) +{ + /* call the callback which forwards the traffic to the client */ + ixEthAccPortDisableRx(portId, mBufPtr, useMultiBufferCallback); + + /* try to replenish with the buffer used in portDisable + * if seen in Rx + */ + ixEthAccPortDisableTryReplenish(portId); +} + +PRIVATE void +ixEthAccPortDisableRxCallback (UINT32 cbTag, + IX_OSAL_MBUF * mBufPtr, + UINT32 learnedPortId) +{ + IxEthAccPortId portId = (IxEthAccPortId)cbTag; + + /* call the portDisable receive callback */ + (ixEthAccPortDisableRxTable[portId])(portId, mBufPtr, FALSE); +} + +PRIVATE void +ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag, + IX_OSAL_MBUF **mBufPtr) +{ + IxEthAccPortId portId = (IxEthAccPortId)cbTag; + + while (*mBufPtr) + { + /* call the portDisable receive callback with one buffer at a time */ + (ixEthAccPortDisableRxTable[portId])(portId, *mBufPtr++, TRUE); + } +} + +IxEthAccStatus +ixEthAccPortDisablePriv(IxEthAccPortId portId) +{ + IxEthAccStatus status = IX_ETH_ACC_SUCCESS; + int key; + int retry, retryTimeout; + volatile IxEthAccPortDisableState *state = &ixEthAccMacState[portId].portDisableState; + volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState; + volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable port.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* if the state is being set to what it is already at, do nothing */ + if (!ixEthAccMacState[portId].enabled) + { + return IX_ETH_ACC_SUCCESS; + } + + *state = DISABLED; + + /* disable MAC receive first */ + ixEthAccPortRxDisablePriv(portId); + +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + /* disable ethernet database for this port - It is done now to avoid + * issuing ELT maintenance after requesting 'port disable' in an NPE + */ + if (ixEthDBPortDisable(portId) != IX_ETH_DB_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + IX_ETH_ACC_FATAL_LOG("ixEthAccPortDisable: failed to disable EthDB for this port\n", 0, 0, 0, 0, 0, 0); + } +#endif + + /* enter the critical section */ + key = ixOsalIrqLock(); + + /* swap the Rx and TxDone callbacks */ + ixEthAccPortDisableFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn; + ixEthAccPortDisableMultiBufferFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn; + ixEthAccPortDisableCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag; + ixEthAccPortDisableMultiBufferCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag; + ixEthAccPortDisableTxDoneFn[portId] = ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn; + ixEthAccPortDisableTxDoneCbTag[portId] = ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag; + ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx; + + /* register temporary callbacks */ + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableRxCallback; + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = portId; + + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferRxCallback; + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = portId; + + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDone; + ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = portId; + + /* initialise the Rx state and Tx states */ + *txState = TRANSMIT_DONE; + *rxState = RECEIVE; + + /* exit the critical section */ + ixOsalIrqUnlock(key); + + /* enable a NPE loopback */ + if (ixEthAccNpeLoopbackEnablePriv(portId) != IX_ETH_ACC_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + + if (status == IX_ETH_ACC_SUCCESS) + { + retry = 0; + + /* Step 1 : Drain Tx traffic and TxDone queues : + * + * Transmit and replenish at least once with the + * special buffers until both of them are seen + * in the callback hook + * + * (the receive callback keeps replenishing, so once we see + * the special Tx buffer, we can be sure that Tx drain is complete) + */ + ixEthAccPortDisableRxTable[portId] + = ixEthAccPortDisableRxAndReplenish; + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn + = ixEthAccPortDisableTxDone; + + do + { + /* keep replenishing */ + status = ixEthAccPortDisableTryReplenish(portId); + if (status == IX_ETH_ACC_SUCCESS) + { + /* keep transmitting */ + status = ixEthAccPortDisableTryTransmit(portId); + } + if (status == IX_ETH_ACC_SUCCESS) + { + /* wait for some traffic being processed */ + ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); + } + } + while ((status == IX_ETH_ACC_SUCCESS) + && (retry++ < IX_ETH_ACC_MAX_RETRY) + && (*txState == TRANSMIT)); + + /* Step 2 : Drain Rx traffic, RxFree and Rx queues : + * + * Transmit and replenish at least once with the + * special buffers until both of them are seen + * in the callback hook + * (the transmit callback keeps transmitting, and when we see + * the special Rx buffer, we can be sure that rxFree drain + * is complete) + * + * The nested loop helps to retry if the user was keeping + * replenishing or transmitting during portDisable. + * + * The 2 nested loops ensure more retries if user traffic is + * seen during portDisable : the user should not replenish + * or transmit while portDisable is running. However, because of + * the queueing possibilities in ethAcc dataplane, it is possible + * that a lot of traffic is left in the queues (e.g. when + * transmitting over a low speed link) and therefore, more + * retries are allowed to help flushing the buffers out. + */ + ixEthAccPortDisableRxTable[portId] + = ixEthAccPortDisableRx; + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn + = ixEthAccPortDisableTxDoneAndSubmit; + + do + { + do + { + ixEthAccPortDisableUserBufferCount[portId] = 0; + + /* keep replenishing */ + status = ixEthAccPortDisableTryReplenish(portId); + if (status == IX_ETH_ACC_SUCCESS) + { + /* keep transmitting */ + status = ixEthAccPortDisableTryTransmit(portId); + } + if (status == IX_ETH_ACC_SUCCESS) + { + /* wait for some traffic being processed */ + ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); + } + } + while ((status == IX_ETH_ACC_SUCCESS) + && (retry++ < IX_ETH_ACC_MAX_RETRY) + && ((ixEthAccPortDisableUserBufferCount[portId] != 0) + || (*rxState == REPLENISH))); + + /* After the first iteration, change the receive callbacks, + * to process only 1 buffer at a time + */ + ixEthAccPortDisableRxTable[portId] + = ixEthAccPortDisableRx; + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn + = ixEthAccPortDisableTxDone; + + /* repeat the whole process while user traffic is seen in TxDone + * + * The conditions to stop the loop are + * - Xscale has both Rx and Tx special buffers + * (txState = transmit, rxState = receive) + * - any error in txSubmit or rxReplenish + * - no user traffic seen + * - an excessive amount of retries + */ + } + while ((status == IX_ETH_ACC_SUCCESS) + && (retry < IX_ETH_ACC_MAX_RETRY) + && (*txState == TRANSMIT)); + + /* check the loop exit conditions. The NPE should not hold + * the special buffers. + */ + if ((*rxState == REPLENISH) || (*txState == TRANSMIT)) + { + status = IX_ETH_ACC_FAIL; + } + + if (status == IX_ETH_ACC_SUCCESS) + { + /* Step 3 : Replenish without transmitting until a timeout + * occurs, in order to drain the internal NPE fifos + * + * we can expect a few frames srill held + * in the NPE. + * + * The 2 nested loops take care about the NPE dropping traffic + * (including loopback traffic) when the Rx queue is full. + * + * The timeout value is very conservative + * since the loopback used keeps replenishhing. + * + */ + do + { + ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRxAndReplenish; + ixEthAccPortDisableUserBufferCount[portId] = 0; + retryTimeout = 0; + do + { + /* keep replenishing */ + status = ixEthAccPortDisableTryReplenish(portId); + if (status == IX_ETH_ACC_SUCCESS) + { + /* wait for some traffic being processed */ + ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); + } + } + while ((status == IX_ETH_ACC_SUCCESS) + && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT)); + + /* Step 4 : Transmit once. Stop replenish + * + * After the Rx timeout, we are sure that the NPE does not + * hold any frame in its internal NPE fifos. + * + * At this point, the NPE still holds the last rxFree buffer. + * By transmitting a single frame, this should unblock the + * last rxFree buffer. This code just transmit once and + * wait for both frames seen in TxDone and in rxFree. + * + */ + ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx; + status = ixEthAccPortDisableTryTransmit(portId); + + /* the NPE should immediatelyt release + * the last Rx buffer and the last transmitted buffer + * unless the last Tx frame was dropped (rx queue full) + */ + if (status == IX_ETH_ACC_SUCCESS) + { + retryTimeout = 0; + do + { + ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS); + } + while ((*rxState == REPLENISH) + && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT)); + } + + /* the NPE may have dropped the traffic because of Rx + * queue being full. This code ensures that the last + * Tx and Rx frames are both received. + */ + } + while ((status == IX_ETH_ACC_SUCCESS) + && (retry++ < IX_ETH_ACC_MAX_RETRY) + && ((*txState == TRANSMIT) + || (*rxState == REPLENISH) + || (ixEthAccPortDisableUserBufferCount[portId] != 0))); + + /* Step 5 : check the final states : the NPE has + * no buffer left, nor in Tx , nor in Rx directions. + */ + if ((*rxState == REPLENISH) || (*txState == TRANSMIT)) + { + status = IX_ETH_ACC_FAIL; + } + } + + /* now all the buffers are drained, disable NPE loopback + * This is done regardless of the logic to drain the queues and + * the internal buffers held by the NPE. + */ + if (ixEthAccNpeLoopbackDisablePriv(portId) != IX_ETH_ACC_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + } + + /* disable MAC Tx and Rx services */ + ixEthAccMacState[portId].enabled = FALSE; + ixEthAccMacStateUpdate(portId); + + /* restore the Rx and TxDone callbacks (within a critical section) */ + key = ixOsalIrqLock(); + + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableFn[portId]; + ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = ixEthAccPortDisableCbTag[portId]; + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferFn[portId]; + ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = ixEthAccPortDisableMultiBufferCbTag[portId]; + ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDoneFn[portId]; + ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = ixEthAccPortDisableTxDoneCbTag[portId]; + + ixOsalIrqUnlock(key); + + /* the MAC core rx/tx disable may left the MAC hardware in an + * unpredictable state. A hw reset is executed before resetting + * all the MAC parameters to a known value. + */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_RESET); + + ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); + + /* rewrite all parameters to their current value */ + ixEthAccMacStateUpdate(portId); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_INT_CLK_THRESH, + IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_MDC_EN); + + return status; +} + +IxEthAccStatus +ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled) +{ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0); + + /* Since Eth NPE is not available, port must be disabled */ + *enabled = FALSE ; + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + /* Since Eth NPE is not available, port must be disabled */ + *enabled = FALSE ; + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + *enabled = ixEthAccMacState[portId].enabled; + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortMacResetPriv(IxEthAccPortId portId) +{ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot reset Ethernet coprocessor.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_RESET); + + ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); + + /* rewrite all parameters to their current value */ + ixEthAccMacStateUpdate(portId); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_INT_CLK_THRESH, + IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_MDC_EN); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortLoopbackEnable(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable loopback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* read register */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + /* update register */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval | IX_ETH_ACC_RX_CNTRL1_LOOP_EN); + + return IX_ETH_ACC_SUCCESS; +} + +PRIVATE void +ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId, + IxNpeMhMessage msg) +{ + IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); + +#ifndef NDEBUG + /* Prudent to at least check the port is within range */ + if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) + { + IX_ETH_ACC_FATAL_LOG("IXETHACC:ixEthAccPortDisableMessageCallback: Illegal port: %u\n", + (UINT32) portId, 0, 0, 0, 0, 0); + + return; + } +#endif + + /* unlock message reception mutex */ + ixOsalMutexUnlock(&ixEthAccMacState[portId].npeLoopbackMessageLock); +} + +IxEthAccStatus +ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId) +{ + IX_STATUS npeMhStatus; + IxNpeMhMessage message; + IxEthAccStatus status = IX_ETH_ACC_SUCCESS; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* enable NPE loopback (lsb of the message contains the value 1) */ + message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL) + | 0x01; + message.data[1] = 0; + + npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), + message, + IX_ETHNPE_SETLOOPBACK_MODE_ACK, + ixEthAccNpeLoopbackMessageCallback, + IX_NPEMH_SEND_RETRIES_DEFAULT); + + if (npeMhStatus != IX_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + else + { + /* wait for NPE loopbackEnable response */ + if (ixOsalMutexLock(&ixEthAccMacState[portId]. npeLoopbackMessageLock, + IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS) + != IX_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + } + + return status; +} + +IxEthAccStatus +ixEthAccPortTxEnablePriv(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable TX.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* read register */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval); + + /* update register */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval | IX_ETH_ACC_TX_CNTRL1_TX_EN); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortRxEnablePriv(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable RX.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* read register */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + /* update register */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval | IX_ETH_ACC_RX_CNTRL1_RX_EN); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortLoopbackDisable(IxEthAccPortId portId) +{ + UINT32 regval; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable loopback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /*disable MAC loopabck */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + (regval & ~IX_ETH_ACC_RX_CNTRL1_LOOP_EN)); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId) +{ + IX_STATUS npeMhStatus; + IxNpeMhMessage message; + IxEthAccStatus status = IX_ETH_ACC_SUCCESS; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* disable NPE loopback (lsb of the message contains the value 0) */ + message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL); + message.data[1] = 0; + + npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), + message, + IX_ETHNPE_SETLOOPBACK_MODE_ACK, + ixEthAccNpeLoopbackMessageCallback, + IX_NPEMH_SEND_RETRIES_DEFAULT); + + if (npeMhStatus != IX_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + else + { + /* wait for NPE loopbackEnable response */ + if (ixOsalMutexLock(&ixEthAccMacState[portId].npeLoopbackMessageLock, + IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS) + != IX_SUCCESS) + { + status = IX_ETH_ACC_FAIL; + } + } + + return status; +} + +IxEthAccStatus +ixEthAccPortTxDisablePriv(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable TX.\n", (INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* read register */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval); + + /* update register */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + (regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN)); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortRxDisablePriv(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable RX.\n", (INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* read register */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + /* update register */ + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + (regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN)); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId) +{ + UINT32 regval; + + /* Turn off promiscuous mode */ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear promiscuous mode.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /*set bit 5 of Rx control 1 - enable address filtering*/ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN); + + ixEthAccMacState[portId].promiscuous = FALSE; + + ixEthAccMulticastAddressSet(portId); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId) +{ + UINT32 regval; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set promiscuous mode.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* + * Set bit 5 of Rx control 1 - We enable address filtering even in + * promiscuous mode because we want the MAC to set the appropriate + * bits in m_flags which doesn't happen if we turn off filtering. + */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN); + + ixEthAccMacState[portId].promiscuous = TRUE; + + ixEthAccMulticastAddressSet(portId); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortUnicastMacAddressSetPriv (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + UINT32 i; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + + if (macAddr == NULL) + { + return IX_ETH_ACC_FAIL; + } + + if ( macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT ) + { + /* This is a multicast/broadcast address cant set it ! */ + return IX_ETH_ACC_FAIL; + } + + if ( macAddr->macAddress[0] == 0 && + macAddr->macAddress[1] == 0 && + macAddr->macAddress[2] == 0 && + macAddr->macAddress[3] == 0 && + macAddr->macAddress[4] == 0 && + macAddr->macAddress[5] == 0 ) + { + /* This is an invalid mac address cant set it ! */ + return IX_ETH_ACC_FAIL; + } + +#ifdef CONFIG_IXP425_COMPONENT_ETHDB + /* update the MAC address in the ethernet database */ + if (ixEthDBPortAddressSet(portId, (IxEthDBMacAddr *) macAddr) != IX_ETH_DB_SUCCESS) + { + return IX_ETH_ACC_FAIL; + } +#endif + + /*Set the Unicast MAC to the specified value*/ + for(i=0;imacAddress[i]); + } + ixEthAccMacState[portId].initDone = TRUE; + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortUnicastMacAddressGetPriv (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + /*Return the current value of the Unicast MAC from h/w + for the specified port*/ + UINT32 i; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0); + /* Since Eth Npe is unavailable, return invalid MAC Address = 00:00:00:00:00:00 */ + for(i=0;imacAddress[i] = 0; + } + return IX_ETH_ACC_SUCCESS ; + } + + if(!ixEthAccMacState[portId].initDone) + { + return (IX_ETH_ACC_MAC_UNINITIALIZED); + } + + if (macAddr == NULL) + { + return IX_ETH_ACC_FAIL; + } + + + for(i=0;imacAddress[i]); + } + return IX_ETH_ACC_SUCCESS; +} + +PRIVATE IxEthAccStatus +ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + /*Return the current value of the Multicast MAC from h/w + for the specified port*/ + UINT32 i; + + for(i=0;imacAddress[i]); + } + + return IX_ETH_ACC_SUCCESS; +} + +PRIVATE IxEthAccStatus +ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + /*Return the current value of the Multicast MAC from h/w + for the specified port*/ + UINT32 i; + + for(i=0;imacAddress[i]); + } + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortMulticastAddressJoinPriv (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + UINT32 i; + IxEthAccMacAddr broadcastAddr = {{0xff,0xff,0xff,0xff,0xff,0xff}}; + + /*Check that the port parameter is valid*/ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join Multicast Mac Address.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /*Check that the mac address is valid*/ + if(macAddr == NULL) + { + return IX_ETH_ACC_FAIL; + } + + /* Check that this is a multicast address */ + if (!(macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT)) + { + return IX_ETH_ACC_FAIL; + } + + /* We don't add the Broadcast address */ + if(ixEthAccMacEqual(&broadcastAddr, macAddr)) + { + return IX_ETH_ACC_FAIL; + } + + for (i = 0; + i= IX_ETH_ACC_MAX_MULTICAST_ADDRESSES) + { + return IX_ETH_ACC_FAIL; + } + + /*First add the address to the multicast table for the + specified port*/ + i=ixEthAccMacState[portId].mcastAddrIndex; + + memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i], + &macAddr->macAddress, + IX_IEEE803_MAC_ADDRESS_SIZE); + + /*Increment the index into the table, this must be done here + as MulticastAddressSet below needs to know about the latest + entry. + */ + ixEthAccMacState[portId].mcastAddrIndex++; + + /*Then calculate the new value to be written to the address and + address mask registers*/ + ixEthAccMulticastAddressSet(portId); + + return IX_ETH_ACC_SUCCESS; +} + + +IxEthAccStatus +ixEthAccPortMulticastAddressJoinAllPriv (IxEthAccPortId portId) +{ + IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; + + /*Check that the port parameter is valid*/ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join all Multicast Address.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /* remove all entries from the database and + * insert a multicast entry + */ + memcpy(&ixEthAccMacState[portId].mcastAddrsTable[0], + &mcastMacAddr.macAddress, + IX_IEEE803_MAC_ADDRESS_SIZE); + + ixEthAccMacState[portId].mcastAddrIndex = 1; + ixEthAccMacState[portId].joinAll = TRUE; + + ixEthAccMulticastAddressSet(portId); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccPortMulticastAddressLeavePriv (IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) +{ + UINT32 i; + IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; + + /*Check that the port parameter is valid*/ + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave Multicast Address.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + /*Check that the mac address is valid*/ + if(macAddr == NULL) + { + return IX_ETH_ACC_FAIL; + } + /* Remove this mac address from the mask for the specified port + * we copy down all entries above the blanked entry, and + * decrement the index + */ + i=0; + + while(i= IX_ETH_ACC_NUMBER_OF_PORTS) + { + IX_ETH_ACC_FATAL_LOG( + "IXETHACC:ixEthAccMacNpeStatsMessageCallback: Illegal port: %u\n", + (UINT32)portId, 0, 0, 0, 0, 0); + return; + } +#endif + + /*Unblock Stats Get call*/ + ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsLock); + +} + +PRIVATE void +ixEthAccMibIIStatsEndianConvert (IxEthEthObjStats *retStats) +{ + /* endianness conversion */ + + /* Rx stats */ + retStats->dot3StatsAlignmentErrors = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsAlignmentErrors); + retStats->dot3StatsFCSErrors = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsFCSErrors); + retStats->dot3StatsInternalMacReceiveErrors = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacReceiveErrors); + retStats->RxOverrunDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxOverrunDiscards); + retStats->RxLearnedEntryDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLearnedEntryDiscards); + retStats->RxLargeFramesDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLargeFramesDiscards); + retStats->RxSTPBlockedDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxSTPBlockedDiscards); + retStats->RxVLANTypeFilterDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANTypeFilterDiscards); + retStats->RxVLANIdFilterDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANIdFilterDiscards); + retStats->RxInvalidSourceDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxInvalidSourceDiscards); + retStats->RxBlackListDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxBlackListDiscards); + retStats->RxWhiteListDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxWhiteListDiscards); + retStats->RxUnderflowEntryDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxUnderflowEntryDiscards); + + /* Tx stats */ + retStats->dot3StatsSingleCollisionFrames = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsSingleCollisionFrames); + retStats->dot3StatsMultipleCollisionFrames = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsMultipleCollisionFrames); + retStats->dot3StatsDeferredTransmissions = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsDeferredTransmissions); + retStats->dot3StatsLateCollisions = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsLateCollisions); + retStats->dot3StatsExcessiveCollsions = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsExcessiveCollsions); + retStats->dot3StatsInternalMacTransmitErrors = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacTransmitErrors); + retStats->dot3StatsCarrierSenseErrors = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsCarrierSenseErrors); + retStats->TxLargeFrameDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxLargeFrameDiscards); + retStats->TxVLANIdFilterDiscards = + IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxVLANIdFilterDiscards); +} + +IxEthAccStatus +ixEthAccMibIIStatsGet (IxEthAccPortId portId, + IxEthEthObjStats *retStats ) +{ + IxNpeMhMessage message; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + printf("EthAcc: ixEthAccMibIIStatsGet (Mac) EthAcc service is not initialized\n"); + return (IX_ETH_ACC_FAIL); + } + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (retStats == NULL) + { + printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NULL argument\n"); + return (IX_ETH_ACC_FAIL); + } + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NPE for port %d is not available\n", portId); + + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get MIB II Stats.\n",(INT32)portId,0,0,0,0,0); + + /* Return all zero stats */ + IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats)); + + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + printf("EthAcc: ixEthAccMibIIStatsGet (Mac) port %d is not initialized\n", portId); + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats)); + + message.data[0] = IX_ETHNPE_GETSTATS << IX_ETH_ACC_MAC_MSGID_SHL; + message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats); + + /* Permit only one task to request MIB statistics Get operation + at a time */ + ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetAccessLock, IX_OSAL_WAIT_FOREVER); + + if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), + message, + IX_ETHNPE_GETSTATS, + ixEthAccMacNpeStatsMessageCallback, + IX_NPEMH_SEND_RETRIES_DEFAULT) + != IX_SUCCESS) + { + ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock); + + printf("EthAcc: (Mac) StatsGet failed to send NPE message\n"); + + return IX_ETH_ACC_FAIL; + } + + /* Wait for callback invocation indicating response to + this request - we need this mutex in order to ensure + that the return from this function is synchronous */ + ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS); + + /* Permit other tasks to perform MIB statistics Get operation */ + ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock); + + ixEthAccMibIIStatsEndianConvert (retStats); + + return IX_ETH_ACC_SUCCESS; +} + + +PRIVATE void +ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId, + IxNpeMhMessage msg) +{ + IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId); + +#ifndef NDEBUG + /* Prudent to at least check the port is within range */ + if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS) + { + IX_ETH_ACC_FATAL_LOG( + "IXETHACC:ixEthAccMacNpeStatsResetMessageCallback: Illegal port: %u\n", + (UINT32)portId, 0, 0, 0, 0, 0); + return; + } +#endif + + /*Unblock Stats Get & reset call*/ + ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsResetLock); + +} + + + +IxEthAccStatus +ixEthAccMibIIStatsGetClear (IxEthAccPortId portId, + IxEthEthObjStats *retStats) +{ + IxNpeMhMessage message; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) EthAcc service is not initialized\n"); + return (IX_ETH_ACC_FAIL); + } + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (retStats == NULL) + { + printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NULL argument\n"); + return (IX_ETH_ACC_FAIL); + } + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NPE for port %d is not available\n", portId); + + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get and clear MIB II Stats.\n", (INT32)portId, 0, 0, 0, 0, 0); + + /* Return all zero stats */ + IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats)); + + return IX_ETH_ACC_SUCCESS ; + } + + if (!IX_ETH_IS_PORT_INITIALIZED(portId)) + { + printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) port %d is not initialized\n", portId); + return (IX_ETH_ACC_PORT_UNINITIALIZED); + } + + IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats)); + + message.data[0] = IX_ETHNPE_RESETSTATS << IX_ETH_ACC_MAC_MSGID_SHL; + message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats); + + /* Permit only one task to request MIB statistics Get-Reset operation at a time */ + ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock, IX_OSAL_WAIT_FOREVER); + + if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId), + message, + IX_ETHNPE_RESETSTATS, + ixEthAccMacNpeStatsResetMessageCallback, + IX_NPEMH_SEND_RETRIES_DEFAULT) + != IX_SUCCESS) + { + ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); + + printf("EthAcc: (Mac) ixEthAccMibIIStatsGetClear failed to send NPE message\n"); + + return IX_ETH_ACC_FAIL; + } + + /* Wait for callback invocation indicating response to this request */ + ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS); + + /* permit other tasks to get and reset MIB stats*/ + ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); + + ixEthAccMibIIStatsEndianConvert(retStats); + + return IX_ETH_ACC_SUCCESS; +} + +IxEthAccStatus +ixEthAccMibIIStatsClear (IxEthAccPortId portId) +{ + static IxEthEthObjStats retStats; + IxEthAccStatus status; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear MIB II Stats.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + /* there is no reset operation without a corresponding Get */ + status = ixEthAccMibIIStatsGetClear(portId, &retStats); + + return status; +} + +/* Initialize the ethernet MAC settings */ +IxEthAccStatus +ixEthAccMacInit(IxEthAccPortId portId) +{ + IX_OSAL_MBUF_POOL* portDisablePool; + UINT8 *data; + + IX_ETH_ACC_VALIDATE_PORT_ID(portId); + + if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId)) + { + IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Mac.\n",(INT32)portId,0,0,0,0,0); + return IX_ETH_ACC_SUCCESS ; + } + + if(ixEthAccMacState[portId].macInitialised == FALSE) + { + ixEthAccMacState[portId].fullDuplex = TRUE; + ixEthAccMacState[portId].rxFCSAppend = TRUE; + ixEthAccMacState[portId].txFCSAppend = TRUE; + ixEthAccMacState[portId].txPADAppend = TRUE; + ixEthAccMacState[portId].enabled = FALSE; + ixEthAccMacState[portId].promiscuous = TRUE; + ixEthAccMacState[portId].joinAll = FALSE; + ixEthAccMacState[portId].initDone = FALSE; + ixEthAccMacState[portId].macInitialised = TRUE; + + /* initialize MIB stats mutexes */ + ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsLock); + ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_OSAL_WAIT_FOREVER); + + ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsResetLock); + ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_OSAL_WAIT_FOREVER); + + ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetAccessLock); + + ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock); + + ixOsalMutexInit(&ixEthAccMacState[portId].npeLoopbackMessageLock); + + ixEthAccMacState[portId].portDisableRxMbufPtr = NULL; + ixEthAccMacState[portId].portDisableTxMbufPtr = NULL; + + portDisablePool = IX_OSAL_MBUF_POOL_INIT(2, + IX_ETHACC_RX_MBUF_MIN_SIZE, + "portDisable Pool"); + + IX_OSAL_ENSURE(portDisablePool != NULL, "Failed to initialize PortDisable pool"); + + ixEthAccMacState[portId].portDisableRxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool); + ixEthAccMacState[portId].portDisableTxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool); + + IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableRxMbufPtr != NULL, + "Pool allocation failed"); + IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableTxMbufPtr != NULL, + "Pool allocation failed"); + /* fill the payload of the Rx mbuf used in portDisable */ + IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableRxMbufPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE; + + memset(IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableRxMbufPtr), + 0xAA, + IX_ETHACC_RX_MBUF_MIN_SIZE); + + /* fill the payload of the Tx mbuf used in portDisable (64 bytes) */ + IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64; + IX_OSAL_MBUF_PKT_LEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64; + + data = (UINT8 *) IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableTxMbufPtr); + memset(data, 0xBB, 64); + data[0] = 0x00; /* unicast destination MAC address */ + data[6] = 0x00; /* unicast source MAC address */ + data[12] = 0x08; /* typelength : IP frame */ + data[13] = 0x00; /* typelength : IP frame */ + + IX_OSAL_CACHE_FLUSH(data, 64); + } + + IX_OSAL_ASSERT (ixEthAccMacBase[portId] != 0); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_RESET); + + ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_CORE_CNTRL, + IX_ETH_ACC_CORE_MDC_EN); + + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_INT_CLK_THRESH, + IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT); + + ixEthAccMacStateUpdate(portId); + + return IX_ETH_ACC_SUCCESS; +} + +/* PRIVATE Functions*/ + +PRIVATE void +ixEthAccMacStateUpdate(IxEthAccPortId portId) +{ + UINT32 regval; + + if ( ixEthAccMacState[portId].enabled == FALSE ) + { + /* Just disable both the transmitter and reciver in the MAC. */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN); + + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval); + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN); + } + + if(ixEthAccMacState[portId].fullDuplex) + { + ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_FULL_DUPLEX); + } + else + { + ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_HALF_DUPLEX); + } + + if(ixEthAccMacState[portId].rxFCSAppend) + { + ixEthAccPortRxFrameAppendFCSEnablePriv (portId); + } + else + { + ixEthAccPortRxFrameAppendFCSDisablePriv (portId); + } + + if(ixEthAccMacState[portId].txFCSAppend) + { + ixEthAccPortTxFrameAppendFCSEnablePriv (portId); + } + else + { + ixEthAccPortTxFrameAppendFCSDisablePriv (portId); + } + + if(ixEthAccMacState[portId].txPADAppend) + { + ixEthAccPortTxFrameAppendPaddingEnablePriv (portId); + } + else + { + ixEthAccPortTxFrameAppendPaddingDisablePriv (portId); + } + + if(ixEthAccMacState[portId].promiscuous) + { + ixEthAccPortPromiscuousModeSetPriv(portId); + } + else + { + ixEthAccPortPromiscuousModeClearPriv(portId); + } + + if ( ixEthAccMacState[portId].enabled == TRUE ) + { + /* Enable both the transmitter and reciver in the MAC. */ + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval); + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_RX_CNTRL1, + regval | IX_ETH_ACC_RX_CNTRL1_RX_EN); + + REG_READ(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval); + REG_WRITE(ixEthAccMacBase[portId], + IX_ETH_ACC_MAC_TX_CNTRL1, + regval | IX_ETH_ACC_TX_CNTRL1_TX_EN); + } +} + + +PRIVATE BOOL +ixEthAccMacEqual(IxEthAccMacAddr *macAddr1, + IxEthAccMacAddr *macAddr2) +{ + UINT32 i; + for(i=0;imacAddress[i] != macAddr2->macAddress[i]) + { + return FALSE; + } + } + return TRUE; +} + +PRIVATE void +ixEthAccMacPrint(IxEthAccMacAddr *m) +{ + printf("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", + m->macAddress[0], m->macAddress[1], + m->macAddress[2], m->macAddress[3], + m->macAddress[4], m->macAddress[5]); +} + +/* Set the multicast address and address mask registers + * + * A bit in the address mask register must be set if + * all multicast addresses always have that bit set, or if + * all multicast addresses always have that bit cleared. + * + * A bit in the address register must be set if all multicast + * addresses have that bit set, otherwise, it should be cleared + */ + +PRIVATE void +ixEthAccMulticastAddressSet(IxEthAccPortId portId) +{ + UINT32 i; + UINT32 j; + IxEthAccMacAddr addressMask; + IxEthAccMacAddr address; + IxEthAccMacAddr alwaysClearBits; + IxEthAccMacAddr alwaysSetBits; + + /* calculate alwaysClearBits and alwaysSetBits: + * alwaysClearBits is calculated by ORing all + * multicast addresses, those bits that are always + * clear are clear in the result + * + * alwaysSetBits is calculated by ANDing all + * multicast addresses, those bits that are always set + * are set in the result + */ + + if (ixEthAccMacState[portId].promiscuous == TRUE) + { + /* Promiscuous Mode is set, and filtering + * allow all packets, and enable the mcast and + * bcast detection. + */ + memset(&addressMask.macAddress, + 0, + IX_IEEE803_MAC_ADDRESS_SIZE); + memset(&address.macAddress, + 0, + IX_IEEE803_MAC_ADDRESS_SIZE); + } + else + { + if(ixEthAccMacState[portId].joinAll == TRUE) + { + /* Join all is set. The mask and address are + * the multicast settings. + */ + IxEthAccMacAddr macAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}}; + + memcpy(addressMask.macAddress, + macAddr.macAddress, + IX_IEEE803_MAC_ADDRESS_SIZE); + memcpy(address.macAddress, + macAddr.macAddress, + IX_IEEE803_MAC_ADDRESS_SIZE); + } + else if(ixEthAccMacState[portId].mcastAddrIndex == 0) + { + /* No entry in the filtering database, + * Promiscuous Mode is cleared, Broadcast filtering + * is configured. + */ + memset(addressMask.macAddress, + IX_ETH_ACC_MAC_ALL_BITS_SET, + IX_IEEE803_MAC_ADDRESS_SIZE); + memset(address.macAddress, + IX_ETH_ACC_MAC_ALL_BITS_SET, + IX_IEEE803_MAC_ADDRESS_SIZE); + } + else + { + /* build a mask and an address which mix all entreis + * from the list of multicast addresses + */ + memset(alwaysClearBits.macAddress, + 0, + IX_IEEE803_MAC_ADDRESS_SIZE); + memset(alwaysSetBits.macAddress, + IX_ETH_ACC_MAC_ALL_BITS_SET, + IX_IEEE803_MAC_ADDRESS_SIZE); + + for(i=0;i> 8) & 0xff); + + REG_WRITE(miiBaseAddressVirt, + IX_ETH_ACC_MAC_MDIO_CMD_3, + (mdioCommand >> 16) & 0xff); + + REG_WRITE(miiBaseAddressVirt, + IX_ETH_ACC_MAC_MDIO_CMD_4, + (mdioCommand >> 24) & 0xff); +} + +PRIVATE void +ixEthAccMdioCmdRead(UINT32 *data) +{ + UINT32 regval; + + REG_READ(miiBaseAddressVirt, + IX_ETH_ACC_MAC_MDIO_CMD_1, + regval); + + *data = regval & 0xff; + + REG_READ(miiBaseAddressVirt, + IX_ETH_ACC_MAC_MDIO_CMD_2, + regval); + + *data |= (regval & 0xff) << 8; + + REG_READ(miiBaseAddressVirt, + IX_ETH_ACC_MAC_MDIO_CMD_3, + regval); + + *data |= (regval & 0xff) << 16; + + REG_READ(miiBaseAddressVirt, + IX_ETH_ACC_MAC_MDIO_CMD_4, + regval); + + *data |= (regval & 0xff) << 24; + +} + +PRIVATE void +ixEthAccMdioStatusRead(UINT32 *data) +{ + UINT32 regval; + + REG_READ(miiBaseAddressVirt, + IX_ETH_ACC_MAC_MDIO_STS_1, + regval); + + *data = regval & 0xff; + + REG_READ(miiBaseAddressVirt, + IX_ETH_ACC_MAC_MDIO_STS_2, + regval); + + *data |= (regval & 0xff) << 8; + + REG_READ(miiBaseAddressVirt, + IX_ETH_ACC_MAC_MDIO_STS_3, + regval); + + *data |= (regval & 0xff) << 16; + + REG_READ(miiBaseAddressVirt, + IX_ETH_ACC_MAC_MDIO_STS_4, + regval); + + *data |= (regval & 0xff) << 24; + +} + + +/******************************************************************** + * ixEthAccMiiInit + */ +IxEthAccStatus +ixEthAccMiiInit() +{ + if(ixOsalMutexInit(&miiAccessLock)!= IX_SUCCESS) + { + return IX_ETH_ACC_FAIL; + } + + miiBaseAddressVirt = (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE, IX_OSAL_IXP400_ETHA_MAP_SIZE); + + if (miiBaseAddressVirt == 0) + { + ixOsalLog(IX_OSAL_LOG_LVL_FATAL, + IX_OSAL_LOG_DEV_STDOUT, + "EthAcc: Could not map MII I/O mapped memory\n", + 0, 0, 0, 0, 0, 0); + + return IX_ETH_ACC_FAIL; + } + + return IX_ETH_ACC_SUCCESS; +} + +void +ixEthAccMiiUnload(void) +{ + IX_OSAL_MEM_UNMAP(miiBaseAddressVirt); + + miiBaseAddressVirt = 0; +} + +PUBLIC IxEthAccStatus +ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount) +{ + if (retryCount < 1) return IX_ETH_ACC_FAIL; + + ixEthAccMiiRetryCount = retryCount; + ixEthAccMiiAccessTimeout = timeout; + + return IX_ETH_ACC_SUCCESS; +} + +/********************************************************************* + * ixEthAccMiiReadRtn - read a 16 bit value from a PHY + */ +IxEthAccStatus +ixEthAccMiiReadRtn (UINT8 phyAddr, + UINT8 phyReg, + UINT16 *value) +{ + UINT32 mdioCommand; + UINT32 regval; + UINT32 miiTimeout; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR) + || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG)) + { + return (IX_ETH_ACC_FAIL); + } + + if (value == NULL) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER); + mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL + | phyAddr << IX_ETH_ACC_MII_ADDR_SHL; + mdioCommand |= IX_ETH_ACC_MII_GO; + + ixEthAccMdioCmdWrite(mdioCommand); + + miiTimeout = ixEthAccMiiRetryCount; + + while(miiTimeout) + { + + ixEthAccMdioCmdRead(®val); + + if((regval & IX_ETH_ACC_MII_GO) == 0x0) + { + break; + } + /* Sleep for a while */ + ixOsalSleep(ixEthAccMiiAccessTimeout); + miiTimeout--; + } + + + + if(miiTimeout == 0) + { + ixOsalMutexUnlock(&miiAccessLock); + *value = 0xffff; + return IX_ETH_ACC_FAIL; + } + + + ixEthAccMdioStatusRead(®val); + if(regval & IX_ETH_ACC_MII_READ_FAIL) + { + ixOsalMutexUnlock(&miiAccessLock); + *value = 0xffff; + return IX_ETH_ACC_FAIL; + } + + *value = regval & 0xffff; + ixOsalMutexUnlock(&miiAccessLock); + return IX_ETH_ACC_SUCCESS; + +} + + +/********************************************************************* + * ixEthAccMiiWriteRtn - write a 16 bit value to a PHY + */ +IxEthAccStatus +ixEthAccMiiWriteRtn (UINT8 phyAddr, + UINT8 phyReg, + UINT16 value) +{ + UINT32 mdioCommand; + UINT32 regval; + UINT16 readVal; + UINT32 miiTimeout; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + if ((phyAddr >= IXP425_ETH_ACC_MII_MAX_ADDR) + || (phyReg >= IXP425_ETH_ACC_MII_MAX_REG)) + { + return (IX_ETH_ACC_FAIL); + } + + /* ensure that a PHY is present at this address */ + if(ixEthAccMiiReadRtn(phyAddr, + IX_ETH_ACC_MII_CTRL_REG, + &readVal) != IX_ETH_ACC_SUCCESS) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER); + mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL + | phyAddr << IX_ETH_ACC_MII_ADDR_SHL ; + mdioCommand |= IX_ETH_ACC_MII_GO | IX_ETH_ACC_MII_WRITE | value; + + ixEthAccMdioCmdWrite(mdioCommand); + + miiTimeout = ixEthAccMiiRetryCount; + + while(miiTimeout) + { + + ixEthAccMdioCmdRead(®val); + + /*The "GO" bit is reset to 0 when the write completes*/ + if((regval & IX_ETH_ACC_MII_GO) == 0x0) + { + break; + } + /* Sleep for a while */ + ixOsalSleep(ixEthAccMiiAccessTimeout); + miiTimeout--; + } + + ixOsalMutexUnlock(&miiAccessLock); + if(miiTimeout == 0) + { + return IX_ETH_ACC_FAIL; + } + return IX_ETH_ACC_SUCCESS; +} + + +/***************************************************************** + * + * Phy query functions + * + */ +IxEthAccStatus +ixEthAccMiiStatsShow (UINT32 phyAddr) +{ + UINT16 regval; + printf("Regisers on PHY at address 0x%x\n", phyAddr); + ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_CTRL_REG, ®val); + printf(" Control Register : 0x%4.4x\n", regval); + ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_STAT_REG, ®val); + printf(" Status Register : 0x%4.4x\n", regval); + ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID1_REG, ®val); + printf(" PHY ID1 Register : 0x%4.4x\n", regval); + ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_PHY_ID2_REG, ®val); + printf(" PHY ID2 Register : 0x%4.4x\n", regval); + ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_ADS_REG, ®val); + printf(" Auto Neg ADS Register : 0x%4.4x\n", regval); + ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_PRTN_REG, ®val); + printf(" Auto Neg Partner Ability Register : 0x%4.4x\n", regval); + ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_EXP_REG, ®val); + printf(" Auto Neg Expansion Register : 0x%4.4x\n", regval); + ixEthAccMiiReadRtn(phyAddr, IX_ETH_ACC_MII_AN_NEXT_REG, ®val); + printf(" Auto Neg Next Register : 0x%4.4x\n", regval); + + return IX_ETH_ACC_SUCCESS; +} + + +/***************************************************************** + * + * Interface query functions + * + */ +IxEthAccStatus +ixEthAccMdioShow (void) +{ + UINT32 regval; + + if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED()) + { + return (IX_ETH_ACC_FAIL); + } + + ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER); + ixEthAccMdioCmdRead(®val); + ixOsalMutexUnlock(&miiAccessLock); + + printf("MDIO command register\n"); + printf(" Go bit : 0x%x\n", (regval & BIT(31)) >> 31); + printf(" MDIO Write : 0x%x\n", (regval & BIT(26)) >> 26); + printf(" PHY address : 0x%x\n", (regval >> 21) & 0x1f); + printf(" Reg address : 0x%x\n", (regval >> 16) & 0x1f); + + ixOsalMutexLock(&miiAccessLock, IX_OSAL_WAIT_FOREVER); + ixEthAccMdioStatusRead(®val); + ixOsalMutexUnlock(&miiAccessLock); + + printf("MDIO status register\n"); + printf(" Read OK : 0x%x\n", (regval & BIT(31)) >> 31); + printf(" Read Data : 0x%x\n", (regval >> 16) & 0xff); + + return IX_ETH_ACC_SUCCESS; +} + diff --git a/drivers/net/npe/IxEthDBAPI.c b/drivers/net/npe/IxEthDBAPI.c new file mode 100644 index 0000000..b2bfb72 --- /dev/null +++ b/drivers/net/npe/IxEthDBAPI.c @@ -0,0 +1,448 @@ +/** + * @file IxEthDBAPI.c + * + * @brief Implementation of the public API + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxEthDB_p.h" +#include "IxFeatureCtrl.h" + +extern HashTable dbHashtable; +extern IxEthDBPortMap overflowUpdatePortList; +extern BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1]; + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING); + + return ixEthDBTriggerAddPortUpdate(macAddr, portID, TRUE); +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING); + + return ixEthDBTriggerAddPortUpdate(macAddr, portID, FALSE); +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr) +{ + HashNode *searchResult; + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); + + if (searchResult == NULL) + { + return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ + } + + ixEthDBReleaseHashNode(searchResult); + + /* build a remove event and place it on the event queue */ + return ixEthDBTriggerRemovePortUpdate(macAddr, ((MacDescriptor *) searchResult->data)->portID); +} + +IX_ETH_DB_PUBLIC +void ixEthDBDatabaseMaintenance() +{ + HashIterator iterator; + UINT32 portIndex; + BOOL agingRequired = FALSE; + + /* ports who will have deleted records and therefore will need updating */ + IxEthDBPortMap triggerPorts; + + if (IX_FEATURE_CTRL_SWCONFIG_ENABLED != + ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING)) + { + return; + } + + SET_EMPTY_DEPENDENCY_MAP(triggerPorts); + + /* check if there's at least a port that needs aging */ + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + if (ixEthDBPortInfo[portIndex].agingEnabled && ixEthDBPortInfo[portIndex].enabled) + { + agingRequired = TRUE; + } + } + + if (agingRequired) + { + /* ask each NPE port to write back the database for aging inspection */ + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE + && ixEthDBPortInfo[portIndex].agingEnabled + && ixEthDBPortInfo[portIndex].enabled) + { + IxNpeMhMessage message; + IX_STATUS result; + + /* send EDB_GetMACAddressDatabase message */ + FILL_GETMACADDRESSDATABASE(message, + 0 /* unused */, + IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone)); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), message, result); + + if (result == IX_SUCCESS) + { + /* analyze NPE copy */ + ixEthDBNPESyncScan(portIndex, ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone, FULL_ELT_BYTE_SIZE); + + IX_ETH_DB_SUPPORT_TRACE("DB: (API) Finished scanning NPE tree on port %d\n", portIndex); + } + else + { + ixEthDBPortInfo[portIndex].agingEnabled = FALSE; + ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = FALSE; + ixEthDBPortInfo[portIndex].updateMethod.userControlled = TRUE; + + ixOsalLog(IX_OSAL_LOG_LVL_FATAL, + IX_OSAL_LOG_DEV_STDOUT, + "EthDB: (Maintenance) warning, disabling aging and updates for port %d (assumed dead)\n", + portIndex, 0, 0, 0, 0, 0); + + ixEthDBDatabaseClear(portIndex, IX_ETH_DB_ALL_RECORD_TYPES); + } + } + } + + /* browse database and age entries */ + BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); + + while (IS_ITERATOR_VALID(&iterator)) + { + MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; + UINT32 *age = NULL; + BOOL staticEntry = TRUE; + + if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) + { + age = &descriptor->recordData.filteringData.age; + staticEntry = descriptor->recordData.filteringData.staticEntry; + } + else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) + { + age = &descriptor->recordData.filteringVlanData.age; + staticEntry = descriptor->recordData.filteringVlanData.staticEntry; + } + else + { + staticEntry = TRUE; + } + + if (ixEthDBPortInfo[descriptor->portID].agingEnabled && (staticEntry == FALSE)) + { + /* manually increment the age if the port has no such capability */ + if ((ixEthDBPortDefinitions[descriptor->portID].capabilities & IX_ETH_ENTRY_AGING) == 0) + { + *age += (IX_ETH_DB_MAINTENANCE_TIME / 60); + } + + /* age entry if it exceeded the maximum time to live */ + if (*age >= (IX_ETH_DB_LEARNING_ENTRY_AGE_TIME / 60)) + { + /* add port to the set of update trigger ports */ + JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID); + + /* delete entry */ + BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator)); + } + else + { + /* move to the next record */ + BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); + } + } + else + { + /* move to the next record */ + BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); + } + } + + /* update ports which lost records */ + ixEthDBUpdatePortLearningTrees(triggerPorts); + } +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType) +{ + IxEthDBPortMap triggerPorts; + HashIterator iterator; + + if (portID >= IX_ETH_DB_NUMBER_OF_PORTS && portID != IX_ETH_DB_ALL_PORTS) + { + return IX_ETH_DB_INVALID_PORT; + } + + /* check if the user passes some extra bits */ + if ((recordType | IX_ETH_DB_ALL_RECORD_TYPES) != IX_ETH_DB_ALL_RECORD_TYPES) + { + return IX_ETH_DB_INVALID_ARG; + } + + SET_EMPTY_DEPENDENCY_MAP(triggerPorts); + + /* browse database and age entries */ + BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); + + while (IS_ITERATOR_VALID(&iterator)) + { + MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; + + if (((descriptor->portID == portID) || (portID == IX_ETH_DB_ALL_PORTS)) + && ((descriptor->type & recordType) != 0)) + { + /* add to trigger if automatic updates are required */ + if (ixEthDBPortUpdateRequired[descriptor->type]) + { + /* add port to the set of update trigger ports */ + JOIN_PORT_TO_MAP(triggerPorts, descriptor->portID); + } + + /* delete entry */ + BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator)); + } + else + { + /* move to the next record */ + BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); + } + } + + /* update ports which lost records */ + ixEthDBUpdatePortLearningTrees(triggerPorts); + + return IX_ETH_DB_SUCCESS; +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) +{ + HashNode *searchResult; + IxEthDBStatus result = IX_ETH_DB_NO_SUCH_ADDR; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING); + + searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); + + if (searchResult == NULL) + { + return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ + } + + if (((MacDescriptor *) (searchResult->data))->portID == portID) + { + result = IX_ETH_DB_SUCCESS; /* address and port match */ + } + + ixEthDBReleaseHashNode(searchResult); + + return result; +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) +{ + HashNode *searchResult; + + IX_ETH_DB_CHECK_REFERENCE(portID); + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); + + if (searchResult == NULL) + { + return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ + } + + /* return the port ID */ + *portID = ((MacDescriptor *) searchResult->data)->portID; + + ixEthDBReleaseHashNode(searchResult); + + return IX_ETH_DB_SUCCESS; +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING); + + ixEthDBPortInfo[portID].agingEnabled = FALSE; + + return IX_ETH_DB_SUCCESS; +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_LEARNING); + + ixEthDBPortInfo[portID].agingEnabled = TRUE; + + return IX_ETH_DB_SUCCESS; +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) +{ + HashNode *searchResult; + MacDescriptor *descriptor; + + IX_ETH_DB_CHECK_REFERENCE(portID); + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); + + if (searchResult == NULL) + { + return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ + } + + descriptor = (MacDescriptor *) searchResult->data; + + /* return the port ID */ + *portID = descriptor->portID; + + /* reset entry age */ + if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) + { + descriptor->recordData.filteringData.age = 0; + } + else + { + descriptor->recordData.filteringVlanData.age = 0; + } + + ixEthDBReleaseHashNode(searchResult); + + return IX_ETH_DB_SUCCESS; +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING); + + /* force bit at offset 255 to 0 (reserved) */ + dependencyPortMap[31] &= 0xFE; + + COPY_DEPENDENCY_MAP(ixEthDBPortInfo[portID].dependencyPortMap, dependencyPortMap); + + return IX_ETH_DB_SUCCESS; +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(dependencyPortMap); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING); + + COPY_DEPENDENCY_MAP(dependencyPortMap, ixEthDBPortInfo[portID].dependencyPortMap); + + return IX_ETH_DB_SUCCESS; +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FILTERING); + + ixEthDBPortInfo[portID].updateMethod.updateEnabled = enableUpdate; + ixEthDBPortInfo[portID].updateMethod.userControlled = TRUE; + + return IX_ETH_DB_SUCCESS; +} diff --git a/drivers/net/npe/IxEthDBAPISupport.c b/drivers/net/npe/IxEthDBAPISupport.c new file mode 100644 index 0000000..36bc200 --- /dev/null +++ b/drivers/net/npe/IxEthDBAPISupport.c @@ -0,0 +1,675 @@ +/** + * @file IxEthDBAPISupport.c + * + * @brief Public API support functions + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include +#include +#include + +#include "IxEthDB_p.h" +#include "IxEthDBMessages_p.h" +#include "IxEthDB_p.h" +#include "IxEthDBLog_p.h" + +#ifdef IX_UNIT_TEST + +int dbAccessCounter = 0; +int overflowEvent = 0; + +#endif + +/* + * External declaration + */ +extern HashTable dbHashtable; + +/* + * Internal declaration + */ +IX_ETH_DB_PUBLIC +PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS]; + +IX_ETH_DB_PRIVATE +struct +{ + BOOL saved; + IxEthDBPriorityTable priorityTable; + IxEthDBVlanSet vlanMembership; + IxEthDBVlanSet transmitTaggingInfo; + IxEthDBFrameFilter frameFilter; + IxEthDBTaggingAction taggingAction; + IxEthDBFirewallMode firewallMode; + BOOL stpBlocked; + BOOL srcAddressFilterEnabled; + UINT32 maxRxFrameSize; + UINT32 maxTxFrameSize; +} ixEthDBPortState[IX_ETH_DB_NUMBER_OF_PORTS]; + +#define IX_ETH_DB_DEFAULT_FRAME_SIZE (1518) + +/** + * @brief initializes a port + * + * @param portID ID of the port to be initialized + * + * Note that redundant initializations are silently + * dealt with and do not constitute an error + * + * This function is fully documented in the main + * header file, IxEthDB.h + */ +IX_ETH_DB_PUBLIC +void ixEthDBPortInit(IxEthDBPortId portID) +{ + PortInfo *portInfo; + + if (portID >= IX_ETH_DB_NUMBER_OF_PORTS) + { + return; + } + + portInfo = &ixEthDBPortInfo[portID]; + + if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS) + { + WARNING_LOG("EthDB: Unavailable Eth %d: Cannot initialize EthDB Port.\n", (UINT32) portID); + + return; + } + + if (portInfo->initialized) + { + /* redundant */ + return; + } + + /* initialize core fields */ + portInfo->portID = portID; + SET_DEPENDENCY_MAP(portInfo->dependencyPortMap, portID); + + /* default values */ + portInfo->agingEnabled = FALSE; + portInfo->enabled = FALSE; + portInfo->macAddressUploaded = FALSE; + portInfo->maxRxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE; + portInfo->maxTxFrameSize = IX_ETHDB_DEFAULT_FRAME_SIZE; + + /* default update control values */ + portInfo->updateMethod.searchTree = NULL; + portInfo->updateMethod.searchTreePendingWrite = FALSE; + portInfo->updateMethod.treeInitialized = FALSE; + portInfo->updateMethod.updateEnabled = FALSE; + portInfo->updateMethod.userControlled = FALSE; + + /* default WiFi parameters */ + memset(portInfo->bbsid, 0, sizeof (portInfo->bbsid)); + portInfo->frameControlDurationID = 0; + + /* Ethernet NPE-specific initializations */ + if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) + { + /* update handler */ + portInfo->updateMethod.updateHandler = ixEthDBNPEUpdateHandler; + } + + /* initialize state save */ + ixEthDBPortState[portID].saved = FALSE; + + portInfo->initialized = TRUE; +} + +/** + * @brief enables a port + * + * @param portID ID of the port to enable + * + * This function is fully documented in the main + * header file, IxEthDB.h + * + * @return IX_ETH_DB_SUCCESS if enabling was + * accomplished, or a meaningful error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID) +{ + IxEthDBPortMap triggerPorts; + PortInfo *portInfo; + + IX_ETH_DB_CHECK_PORT_EXISTS(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + portInfo = &ixEthDBPortInfo[portID]; + + if (portInfo->enabled) + { + /* redundant */ + return IX_ETH_DB_SUCCESS; + } + + SET_DEPENDENCY_MAP(triggerPorts, portID); + + /* mark as enabled */ + portInfo->enabled = TRUE; + + /* Operation stops here when Ethernet Learning is not enabled */ + if(IX_FEATURE_CTRL_SWCONFIG_DISABLED == + ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) + { + return IX_ETH_DB_SUCCESS; + } + + if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE && !portInfo->macAddressUploaded) + { + IX_ETH_DB_SUPPORT_TRACE("DB: (Support) MAC address not set on port %d, enable failed\n", portID); + + /* must use UnicastAddressSet() before enabling an NPE port */ + return IX_ETH_DB_MAC_UNINITIALIZED; + } + + if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) + { + IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Attempting to enable the NPE callback for port %d...\n", portID); + + if (!portInfo->updateMethod.userControlled + && ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0)) + { + portInfo->updateMethod.updateEnabled = TRUE; + } + + /* if this is first time initialization then we already have + write access to the tree and can AccessRelease directly */ + if (!portInfo->updateMethod.treeInitialized) + { + IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Initializing tree for port %d\n", portID); + + /* create an initial tree and release access into it */ + ixEthDBUpdatePortLearningTrees(triggerPorts); + + /* mark tree as being initialized */ + portInfo->updateMethod.treeInitialized = TRUE; + } + } + + if (ixEthDBPortState[portID].saved) + { + /* previous configuration data stored, restore state */ + if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0) + { + ixEthDBFirewallModeSet(portID, ixEthDBPortState[portID].firewallMode); + ixEthDBFirewallInvalidAddressFilterEnable(portID, ixEthDBPortState[portID].srcAddressFilterEnabled); + } + +#if 0 /* test-only */ + if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) + { + ixEthDBAcceptableFrameTypeSet(portID, ixEthDBPortState[portID].frameFilter); + ixEthDBIngressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].taggingAction); + + ixEthDBEgressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].transmitTaggingInfo); + ixEthDBPortVlanMembershipSet(portID, ixEthDBPortState[portID].vlanMembership); + + ixEthDBPriorityMappingTableSet(portID, ixEthDBPortState[portID].priorityTable); + } +#endif + + if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) + { + ixEthDBSpanningTreeBlockingStateSet(portID, ixEthDBPortState[portID].stpBlocked); + } + + ixEthDBFilteringPortMaximumRxFrameSizeSet(portID, ixEthDBPortState[portID].maxRxFrameSize); + ixEthDBFilteringPortMaximumTxFrameSizeSet(portID, ixEthDBPortState[portID].maxTxFrameSize); + + /* discard previous save */ + ixEthDBPortState[portID].saved = FALSE; + } + + IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Enabling succeeded for port %d\n", portID); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief disables a port + * + * @param portID ID of the port to disable + * + * This function is fully documented in the + * main header file, IxEthDB.h + * + * @return IX_ETH_DB_SUCCESS if disabling was + * successful or an appropriate error message + * otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID) +{ + HashIterator iterator; + IxEthDBPortMap triggerPorts; /* ports who will have deleted records and therefore will need updating */ + BOOL result; + PortInfo *portInfo; + IxEthDBFeature learningEnabled; +#if 0 /* test-only */ + IxEthDBPriorityTable classZeroTable; +#endif + + IX_ETH_DB_CHECK_PORT_EXISTS(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + portInfo = &ixEthDBPortInfo[portID]; + + if (!portInfo->enabled) + { + /* redundant */ + return IX_ETH_DB_SUCCESS; + } + + if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) + { + /* save filtering state */ + ixEthDBPortState[portID].firewallMode = portInfo->firewallMode; + ixEthDBPortState[portID].frameFilter = portInfo->frameFilter; + ixEthDBPortState[portID].taggingAction = portInfo->taggingAction; + ixEthDBPortState[portID].stpBlocked = portInfo->stpBlocked; + ixEthDBPortState[portID].srcAddressFilterEnabled = portInfo->srcAddressFilterEnabled; + ixEthDBPortState[portID].maxRxFrameSize = portInfo->maxRxFrameSize; + ixEthDBPortState[portID].maxTxFrameSize = portInfo->maxTxFrameSize; + + memcpy(ixEthDBPortState[portID].vlanMembership, portInfo->vlanMembership, sizeof (IxEthDBVlanSet)); + memcpy(ixEthDBPortState[portID].transmitTaggingInfo, portInfo->transmitTaggingInfo, sizeof (IxEthDBVlanSet)); + memcpy(ixEthDBPortState[portID].priorityTable, portInfo->priorityTable, sizeof (IxEthDBPriorityTable)); + + ixEthDBPortState[portID].saved = TRUE; + + /* now turn off all EthDB filtering features on the port */ + +#if 0 /* test-only */ + /* VLAN & QoS */ + if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) + { + ixEthDBPortVlanMembershipRangeAdd((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID); + ixEthDBEgressVlanRangeTaggingEnabledSet((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID, FALSE); + ixEthDBAcceptableFrameTypeSet((IxEthDBPortId) portID, IX_ETH_DB_ACCEPT_ALL_FRAMES); + ixEthDBIngressVlanTaggingEnabledSet((IxEthDBPortId) portID, IX_ETH_DB_PASS_THROUGH); + + memset(classZeroTable, 0, sizeof (classZeroTable)); + ixEthDBPriorityMappingTableSet((IxEthDBPortId) portID, classZeroTable); + } +#endif + + /* STP */ + if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) + { + ixEthDBSpanningTreeBlockingStateSet((IxEthDBPortId) portID, FALSE); + } + + /* Firewall */ + if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0) + { + ixEthDBFirewallModeSet((IxEthDBPortId) portID, IX_ETH_DB_FIREWALL_BLACK_LIST); + ixEthDBFirewallTableDownload((IxEthDBPortId) portID); + ixEthDBFirewallInvalidAddressFilterEnable((IxEthDBPortId) portID, FALSE); + } + + /* Frame size filter */ + ixEthDBFilteringPortMaximumFrameSizeSet((IxEthDBPortId) portID, IX_ETH_DB_DEFAULT_FRAME_SIZE); + + /* WiFi */ + if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) + { + ixEthDBWiFiConversionTableDownload((IxEthDBPortId) portID); + } + + /* save and disable the learning feature bit */ + learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING; + portInfo->featureStatus &= ~IX_ETH_DB_LEARNING; + } + else + { + /* save the learning feature bit */ + learningEnabled = portInfo->featureStatus & IX_ETH_DB_LEARNING; + } + + SET_EMPTY_DEPENDENCY_MAP(triggerPorts); + + ixEthDBUpdateLock(); + + /* wipe out current entries for this port */ + BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); + + while (IS_ITERATOR_VALID(&iterator)) + { + MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; + + /* check if the port match. If so, remove the entry */ + if (descriptor->portID == portID + && (descriptor->type == IX_ETH_DB_FILTERING_RECORD || descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) + && !descriptor->recordData.filteringData.staticEntry) + { + /* delete entry */ + BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator)); + + /* add port to the set of update trigger ports */ + JOIN_PORT_TO_MAP(triggerPorts, portID); + } + else + { + /* move to the next record */ + BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); + } + } + + if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) + { + if (portInfo->updateMethod.searchTree != NULL) + { + ixEthDBFreeMacTreeNode(portInfo->updateMethod.searchTree); + portInfo->updateMethod.searchTree = NULL; + } + + ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FILTERING_RECORD); + } + + /* mark as disabled */ + portInfo->enabled = FALSE; + + /* disable updates unless the user has specifically altered the default behavior */ + if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) + { + if (!portInfo->updateMethod.userControlled) + { + portInfo->updateMethod.updateEnabled = FALSE; + } + + /* make sure we re-initialize the NPE learning tree when the port is re-enabled */ + portInfo->updateMethod.treeInitialized = FALSE; + } + + ixEthDBUpdateUnlock(); + + /* restore learning feature bit */ + portInfo->featureStatus |= learningEnabled; + + /* if we've removed any records or lost any events make sure to force an update */ + IS_EMPTY_DEPENDENCY_MAP(result, triggerPorts); + + if (!result) + { + ixEthDBUpdatePortLearningTrees(triggerPorts); + } + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief sends the updated maximum Tx/Rx frame lengths to the NPE + * + * @param portID ID of the port to update + * + * @return IX_ETH_DB_SUCCESS if the update completed + * successfully or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBPortFrameLengthsUpdate(IxEthDBPortId portID) +{ + IxNpeMhMessage message; + PortInfo *portInfo = &ixEthDBPortInfo[portID]; + IX_STATUS result; + + FILL_SETMAXFRAMELENGTHS_MSG(message, portID, portInfo->maxRxFrameSize, portInfo->maxTxFrameSize); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief sets the port maximum Rx frame size + * + * @param portID ID of the port to set the frame size on + * @param maximumRxFrameSize maximum Rx frame size + * + * This function updates the internal data structures and + * calls ixEthDBPortFrameLengthsUpdate() for NPE update. + * + * This function is fully documented in the main header + * file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation was + * successfull or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize) +{ + IX_ETH_DB_CHECK_PORT_EXISTS(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + if (!ixEthDBPortInfo[portID].initialized) + { + return IX_ETH_DB_PORT_UNINITIALIZED; + } + + if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) + { + if ((maximumRxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) || + (maximumRxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE)) + { + return IX_ETH_DB_INVALID_ARG; + } + } + else + { + return IX_ETH_DB_NO_PERMISSION; + } + + /* update internal structure */ + ixEthDBPortInfo[portID].maxRxFrameSize = maximumRxFrameSize; + + /* update the maximum frame size in the NPE */ + return ixEthDBPortFrameLengthsUpdate(portID); +} + +/** + * @brief sets the port maximum Tx frame size + * + * @param portID ID of the port to set the frame size on + * @param maximumTxFrameSize maximum Tx frame size + * + * This function updates the internal data structures and + * calls ixEthDBPortFrameLengthsUpdate() for NPE update. + * + * This function is fully documented in the main header + * file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation was + * successfull or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize) +{ + IX_ETH_DB_CHECK_PORT_EXISTS(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + if (!ixEthDBPortInfo[portID].initialized) + { + return IX_ETH_DB_PORT_UNINITIALIZED; + } + + if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) + { + if ((maximumTxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) || + (maximumTxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE)) + { + return IX_ETH_DB_INVALID_ARG; + } + } + else + { + return IX_ETH_DB_NO_PERMISSION; + } + + /* update internal structure */ + ixEthDBPortInfo[portID].maxTxFrameSize = maximumTxFrameSize; + + /* update the maximum frame size in the NPE */ + return ixEthDBPortFrameLengthsUpdate(portID); +} + +/** + * @brief sets the port maximum Tx and Rx frame sizes + * + * @param portID ID of the port to set the frame size on + * @param maximumFrameSize maximum Tx and Rx frame sizes + * + * This function updates the internal data structures and + * calls ixEthDBPortFrameLengthsUpdate() for NPE update. + * + * Note that both the maximum Tx and Rx frame size are set + * to the same value. This function is kept for compatibility + * reasons. + * + * This function is fully documented in the main header + * file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation was + * successfull or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize) +{ + IX_ETH_DB_CHECK_PORT_EXISTS(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + if (!ixEthDBPortInfo[portID].initialized) + { + return IX_ETH_DB_PORT_UNINITIALIZED; + } + + if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) + { + if ((maximumFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) || + (maximumFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE)) + { + return IX_ETH_DB_INVALID_ARG; + } + } + else + { + return IX_ETH_DB_NO_PERMISSION; + } + + /* update internal structure */ + ixEthDBPortInfo[portID].maxRxFrameSize = maximumFrameSize; + ixEthDBPortInfo[portID].maxTxFrameSize = maximumFrameSize; + + /* update the maximum frame size in the NPE */ + return ixEthDBPortFrameLengthsUpdate(portID); +} + +/** + * @brief sets the MAC address of an NPE port + * + * @param portID port ID to set the MAC address on + * @param macAddr pointer to the 6-byte MAC address + * + * This function is called by the EthAcc + * ixEthAccUnicastMacAddressSet() and should not be + * manually invoked unless required by special circumstances. + * + * @return IX_ETH_DB_SUCCESS if the operation succeeded + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) +{ + IxNpeMhMessage message; + IX_STATUS result; + + /* use this macro instead CHECK_PORT + as the port doesn't need to be enabled */ + IX_ETH_DB_CHECK_PORT_EXISTS(portID); + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + if (!ixEthDBPortInfo[portID].initialized) + { + return IX_ETH_DB_PORT_UNINITIALIZED; + } + + /* Operation stops here when Ethernet Learning is not enabled */ + if(IX_FEATURE_CTRL_SWCONFIG_DISABLED == + ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING)) + { + return IX_ETH_DB_SUCCESS; + } + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + /* exit if the port is not an Ethernet NPE */ + if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE) + { + return IX_ETH_DB_INVALID_PORT; + } + + /* populate message */ + FILL_SETPORTADDRESS_MSG(message, portID, macAddr->macAddress); + + IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Sending SetPortAddress on port %d...\n", portID); + + /* send a SetPortAddress message */ + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + if (result == IX_SUCCESS) + { + ixEthDBPortInfo[portID].macAddressUploaded = TRUE; + } + + return result; +} diff --git a/drivers/net/npe/IxEthDBCore.c b/drivers/net/npe/IxEthDBCore.c new file mode 100644 index 0000000..25b7cbb --- /dev/null +++ b/drivers/net/npe/IxEthDBCore.c @@ -0,0 +1,463 @@ +/** + * @file IxEthDBDBCore.c + * + * @brief Database support functions + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxEthDB_p.h" + +/* list of database hashtables */ +IX_ETH_DB_PUBLIC HashTable dbHashtable; +IX_ETH_DB_PUBLIC MatchFunction matchFunctions[IX_ETH_DB_MAX_KEY_INDEX + 1]; +IX_ETH_DB_PUBLIC BOOL ixEthDBPortUpdateRequired[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1]; +IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyType[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1]; + +/* private initialization flag */ +IX_ETH_DB_PRIVATE BOOL ethDBInitializationComplete = FALSE; + +/** + * @brief initializes EthDB + * + * This function must be called to initialize the component. + * + * It does the following things: + * - checks the port definition structure + * - scans the capabilities of the NPE images and sets the + * capabilities of the ports accordingly + * - initializes the memory pools internally used in EthDB + * for storing database records and handling data + * - registers automatic update handlers for add and remove + * operations + * - registers hashing match functions, depending on key sets + * - initializes the main database hashtable + * - allocates contiguous memory zones to be used for NPE + * updates + * - registers the serialize methods used to convert data + * into NPE-readable format + * - starts the event processor + * + * Note that this function is documented in the public + * component header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS or an appropriate error if the + * component failed to initialize correctly + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBInit(void) +{ + IxEthDBStatus result; + + if (ethDBInitializationComplete) + { + /* redundant */ + return IX_ETH_DB_SUCCESS; + } + + /* trap an invalid port definition structure */ + IX_ETH_DB_PORTS_ASSERTION; + + /* memory management */ + ixEthDBInitMemoryPools(); + + /* register hashing search methods */ + ixEthDBMatchMethodsRegister(matchFunctions); + + /* register type-based automatic port updates */ + ixEthDBUpdateTypeRegister(ixEthDBPortUpdateRequired); + + /* register record to key type mappings */ + ixEthDBKeyTypeRegister(ixEthDBKeyType); + + /* hash table */ + ixEthDBInitHash(&dbHashtable, NUM_BUCKETS, ixEthDBEntryXORHash, matchFunctions, (FreeFunction) ixEthDBFreeMacDescriptor); + + /* NPE update zones */ + ixEthDBNPEUpdateAreasInit(); + + /* register record serialization methods */ + ixEthDBRecordSerializeMethodsRegister(); + + /* start the event processor */ + result = ixEthDBEventProcessorInit(); + + /* scan NPE features */ + if (result == IX_ETH_DB_SUCCESS) + { + ixEthDBFeatureCapabilityScan(); + } + + ethDBInitializationComplete = TRUE; + + return result; +} + +/** + * @brief prepares EthDB for unloading + * + * This function must be called before removing the + * EthDB component from memory (e.g. doing rmmod in + * Linux) if the component is to be re-initialized again + * without rebooting the platform. + * + * All the EthDB ports must be disabled before this + * function is to be called. Failure to disable all + * the ports will return the IX_ETH_DB_BUSY error. + * + * This function will destroy mutexes, deallocate + * memory and stop the event processor. + * + * Note that this function is fully documented in the + * main component header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if de-initialization + * completed successfully or an appropriate error + * message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUnload(void) +{ + IxEthDBPortId portIndex; + + if (!ethDBInitializationComplete) + { + /* redundant */ + return IX_ETH_DB_SUCCESS; + } + + /* check if any ports are enabled */ + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + if (ixEthDBPortInfo[portIndex].enabled) + { + return IX_ETH_DB_BUSY; + } + } + + /* free port resources */ + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) + { + ixOsalMutexDestroy(&ixEthDBPortInfo[portIndex].npeAckLock); + } + + ixEthDBPortInfo[portIndex].initialized = FALSE; + } + + /* shutdown event processor */ + ixEthDBStopLearningFunction(); + + /* deallocate NPE update zones */ + ixEthDBNPEUpdateAreasUnload(); + + ethDBInitializationComplete = FALSE; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief adds a new entry to the Ethernet database + * + * @param newRecordTemplate address of the record template to use + * @param updateTrigger port map containing the update triggers + * resulting from this update operation + * + * Creates a new database entry, populates it with the data + * copied from the given template and adds the record to the + * database hash table. + * It also checks whether the new record type is registered to trigger + * automatic updates; if it is, the update trigger will contain the + * port on which the record insertion was performed, as well as the + * old port in case the addition was a record migration (from one port + * to the other). The caller can use the updateTrigger to trigger + * automatic updates on the ports changed as a result of this addition. + * + * @retval IX_ETH_DB_SUCCESS addition successful + * @retval IX_ETH_DB_NOMEM insertion failed, no memory left in the mac descriptor memory pool + * @retval IX_ETH_DB_BUSY database busy, cannot insert due to locking + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger) +{ + IxEthDBStatus result; + MacDescriptor *newDescriptor; + IxEthDBPortId originalPortID; + HashNode *node = NULL; + + BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, ixEthDBKeyType[newRecordTemplate->type], newRecordTemplate, &node)); + + TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; + + if (node == NULL) + { + /* not found, create a new one */ + newDescriptor = ixEthDBAllocMacDescriptor(); + + if (newDescriptor == NULL) + { + return IX_ETH_DB_NOMEM; /* no memory */ + } + + /* old port does not exist, avoid unnecessary updates */ + originalPortID = newRecordTemplate->portID; + } + else + { + /* a node with the same key exists, will update node */ + newDescriptor = (MacDescriptor *) node->data; + + /* save original port id */ + originalPortID = newDescriptor->portID; + } + + /* copy/update fields into new record */ + memcpy(newDescriptor->macAddress, newRecordTemplate->macAddress, sizeof (IxEthDBMacAddr)); + memcpy(&newDescriptor->recordData, &newRecordTemplate->recordData, sizeof (IxEthDBRecordData)); + + newDescriptor->type = newRecordTemplate->type; + newDescriptor->portID = newRecordTemplate->portID; + newDescriptor->user = newRecordTemplate->user; + + if (node == NULL) + { + /* new record, insert into hashtable */ + BUSY_RETRY_WITH_RESULT(ixEthDBAddHashEntry(&dbHashtable, newDescriptor), result); + + if (result != IX_ETH_DB_SUCCESS) + { + ixEthDBFreeMacDescriptor(newDescriptor); + + return result; /* insertion failed */ + } + } + + if (node != NULL) + { + /* release access */ + ixEthDBReleaseHashNode(node); + } + + /* trigger add/remove update if required by type */ + if (updateTrigger != NULL && + ixEthDBPortUpdateRequired[newRecordTemplate->type]) + { + /* add new port to update list */ + JOIN_PORT_TO_MAP(updateTrigger, newRecordTemplate->portID); + + /* check if record has moved, we'll need to update the old port as well */ + if (originalPortID != newDescriptor->portID) + { + JOIN_PORT_TO_MAP(updateTrigger, originalPortID); + } + } + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief remove a record from the Ethernet database + * + * @param templateRecord template record used to determine + * what record is to be removed + * @param updateTrigger port map containing the update triggers + * resulting from this update operation + * + * This function will examine the template record it receives + * and attempts to delete a record of the same type and containing + * the same keys as the template record. If deletion is successful + * and the record type is registered for automatic port updates the + * port will also be set in the updateTrigger port map, so that the + * client can perform an update of the port. + * + * @retval IX_ETH_DB_SUCCESS removal was successful + * @retval IX_ETH_DB_NO_SUCH_ADDR the record with the given MAC address was not found + * @retval IX_ETH_DB_BUSY database busy, cannot remove due to locking + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger) +{ + IxEthDBStatus result; + + TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; + + BUSY_RETRY_WITH_RESULT(ixEthDBRemoveHashEntry(&dbHashtable, ixEthDBKeyType[templateRecord->type], templateRecord), result); + + if (result != IX_ETH_DB_SUCCESS) + { + return IX_ETH_DB_NO_SUCH_ADDR; /* not found */ + } + + /* trigger add/remove update if required by type */ + if (updateTrigger != NULL + &&ixEthDBPortUpdateRequired[templateRecord->type]) + { + /* add new port to update list */ + JOIN_PORT_TO_MAP(updateTrigger, templateRecord->portID); + } + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief register record key types + * + * This function registers the appropriate key types, + * depending on record types. + * + * All filtering records use the MAC address as the key. + * WiFi and Firewall records use a compound key consisting + * in both the MAC address and the port ID. + * + * @return the number of registered record types + */ +IX_ETH_DB_PUBLIC +UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType) +{ + /* safety */ + memset(keyType, 0, sizeof (keyType)); + + /* register all known record types */ + keyType[IX_ETH_DB_FILTERING_RECORD] = IX_ETH_DB_MAC_KEY; + keyType[IX_ETH_DB_FILTERING_VLAN_RECORD] = IX_ETH_DB_MAC_KEY; + keyType[IX_ETH_DB_ALL_FILTERING_RECORDS] = IX_ETH_DB_MAC_KEY; + keyType[IX_ETH_DB_WIFI_RECORD] = IX_ETH_DB_MAC_PORT_KEY; + keyType[IX_ETH_DB_FIREWALL_RECORD] = IX_ETH_DB_MAC_PORT_KEY; + + return 5; +} + +/** + * @brief Sets a user-defined field into a database record + * + * Note that this function is fully documented in the main component + * header file. + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field) +{ + HashNode *result = NULL; + + if (macAddr == NULL) + { + return IX_ETH_DB_INVALID_ARG; + } + + if (recordType == IX_ETH_DB_FILTERING_RECORD) + { + result = ixEthDBSearch(macAddr, recordType); + } + else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD) + { + result = ixEthDBVlanSearch(macAddr, vlanID, recordType); + } + else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD) + { + IX_ETH_DB_CHECK_PORT_EXISTS(portID); + + result = ixEthDBPortSearch(macAddr, portID, recordType); + } + else + { + return IX_ETH_DB_INVALID_ARG; + } + + if (result == NULL) + { + return IX_ETH_DB_NO_SUCH_ADDR; + } + + ((MacDescriptor *) result->data)->user = field; + + ixEthDBReleaseHashNode(result); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief Retrieves a user-defined field from a database record + * + * Note that this function is fully documented in the main component + * header file. + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field) +{ + HashNode *result = NULL; + + if (macAddr == NULL || field == NULL) + { + return IX_ETH_DB_INVALID_ARG; + } + + if (recordType == IX_ETH_DB_FILTERING_RECORD) + { + result = ixEthDBSearch(macAddr, recordType); + } + else if (recordType == IX_ETH_DB_FILTERING_VLAN_RECORD) + { + result = ixEthDBVlanSearch(macAddr, vlanID, recordType); + } + else if (recordType == IX_ETH_DB_WIFI_RECORD || recordType == IX_ETH_DB_FIREWALL_RECORD) + { + IX_ETH_DB_CHECK_PORT_EXISTS(portID); + + result = ixEthDBPortSearch(macAddr, portID, recordType); + } + else + { + return IX_ETH_DB_INVALID_ARG; + } + + if (result == NULL) + { + return IX_ETH_DB_NO_SUCH_ADDR; + } + + *field = ((MacDescriptor *) result->data)->user; + + ixEthDBReleaseHashNode(result); + + return IX_ETH_DB_SUCCESS; +} diff --git a/drivers/net/npe/IxEthDBEvents.c b/drivers/net/npe/IxEthDBEvents.c new file mode 100644 index 0000000..4d44e03 --- /dev/null +++ b/drivers/net/npe/IxEthDBEvents.c @@ -0,0 +1,520 @@ +/** + * @file IxEthDBEvents.c + * + * @brief Implementation of the event processor component + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include +#include + +#include "IxEthDB_p.h" + +/* forward prototype declarations */ +IX_ETH_DB_PUBLIC void ixEthDBEventProcessorLoop(void *); +IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); +IX_ETH_DB_PRIVATE void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts); +IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void); + +/* data */ +IX_ETH_DB_PRIVATE IxOsalSemaphore eventQueueSemaphore; +IX_ETH_DB_PRIVATE PortEventQueue eventQueue; +IX_ETH_DB_PRIVATE IxOsalMutex eventQueueLock; +IX_ETH_DB_PRIVATE IxOsalMutex portUpdateLock; + +IX_ETH_DB_PRIVATE BOOL ixEthDBLearningShutdown = FALSE; +IX_ETH_DB_PRIVATE BOOL ixEthDBEventProcessorRunning = FALSE; + +/* imported data */ +extern HashTable dbHashtable; + +/** + * @brief initializes the event processor + * + * Initializes the event processor queue and processing thread. + * Called from ixEthDBInit() DB-subcomponent master init function. + * + * @warning do not call directly + * + * @retval IX_ETH_DB_SUCCESS initialization was successful + * @retval IX_ETH_DB_FAIL initialization failed (OSAL or mutex init failure) + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEventProcessorInit(void) +{ + if (ixOsalMutexInit(&portUpdateLock) != IX_SUCCESS) + { + return IX_ETH_DB_FAIL; + } + + if (ixOsalMutexInit(&eventQueueLock) != IX_SUCCESS) + { + return IX_ETH_DB_FAIL; + } + + if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == + ixFeatureCtrlSwConfigurationCheck (IX_FEATURECTRL_ETH_LEARNING)) + { + + /* start processor loop thread */ + if (ixEthDBStartLearningFunction() != IX_ETH_DB_SUCCESS) + { + return IX_ETH_DB_FAIL; + } + } + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief initializes the event queue and the event processor + * + * This function is called by the component initialization + * function, ixEthDBInit(). + * + * @warning do not call directly + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or IX_ETH_DB_FAIL otherwise + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBStartLearningFunction(void) +{ + IxOsalThread eventProcessorThread; + IxOsalThreadAttr threadAttr; + + threadAttr.name = "EthDB event thread"; + threadAttr.stackSize = 32 * 1024; /* 32kbytes */ + threadAttr.priority = 128; + + /* reset event queue */ + ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); + + RESET_QUEUE(&eventQueue); + + ixOsalMutexUnlock(&eventQueueLock); + + /* init event queue semaphore */ + if (ixOsalSemaphoreInit(&eventQueueSemaphore, 0) != IX_SUCCESS) + { + return IX_ETH_DB_FAIL; + } + + ixEthDBLearningShutdown = FALSE; + + /* create processor loop thread */ + if (ixOsalThreadCreate(&eventProcessorThread, &threadAttr, ixEthDBEventProcessorLoop, NULL) != IX_SUCCESS) + { + return IX_ETH_DB_FAIL; + } + + /* start event processor */ + ixOsalThreadStart(&eventProcessorThread); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief stops the event processor + * + * Stops the event processor and frees the event queue semaphore + * Called by the component de-initialization function, ixEthDBUnload() + * + * @warning do not call directly + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or IX_ETH_DB_FAIL otherwise; + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBStopLearningFunction(void) +{ + ixEthDBLearningShutdown = TRUE; + + /* wake up event processing loop to actually process the shutdown event */ + ixOsalSemaphorePost(&eventQueueSemaphore); + + if (ixOsalSemaphoreDestroy(&eventQueueSemaphore) != IX_SUCCESS) + { + return IX_ETH_DB_FAIL; + } + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief default NPE event processing callback + * + * @param npeID ID of the NPE that generated the event + * @param msg NPE message (encapsulated event) + * + * Creates an event object on the Ethernet event processor queue + * and signals the new event by incrementing the event queue semaphore. + * Events are processed by @ref ixEthDBEventProcessorLoop() which runs + * at user level. + * + * @see ixEthDBEventProcessorLoop() + * + * @warning do not call directly + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg) +{ + PortEvent *local_event; + + IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) new event received by processor callback from port %d, id 0x%X\n", IX_ETH_DB_NPE_TO_PORT_ID(npeID), NPE_MSG_ID(msg), 0, 0, 0, 0); + + if (CAN_ENQUEUE(&eventQueue)) + { + TEST_FIXTURE_LOCK_EVENT_QUEUE; + + local_event = QUEUE_HEAD(&eventQueue); + + /* create event structure on queue */ + local_event->eventType = NPE_MSG_ID(msg); + local_event->portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID); + + /* update queue */ + PUSH_UPDATE_QUEUE(&eventQueue); + + TEST_FIXTURE_UNLOCK_EVENT_QUEUE; + + IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Waking up main processor loop...\n", 0, 0, 0, 0, 0, 0); + + /* increment event queue semaphore */ + ixOsalSemaphorePost(&eventQueueSemaphore); + } + else + { + IX_ETH_DB_IRQ_EVENTS_TRACE("DB: (Events) Warning: could not enqueue event (overflow)\n", 0, 0, 0, 0, 0, 0); + } +} + +/** + * @brief Ethernet event processor loop + * + * Extracts at most EVENT_PROCESSING_LIMIT batches of events and + * sends them for processing to @ref ixEthDBProcessEvent(). + * Triggers port updates which normally follow learning events. + * + * @warning do not call directly, executes in separate thread + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBEventProcessorLoop(void *unused1) +{ + IxEthDBPortMap triggerPorts; + IxEthDBPortId portIndex; + + ixEthDBEventProcessorRunning = TRUE; + + IX_ETH_DB_EVENTS_TRACE("DB: (Events) Event processor loop was started\n"); + + while (!ixEthDBLearningShutdown) + { + BOOL keepProcessing = TRUE; + UINT32 processedEvents = 0; + + IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Waiting for new learning event...\n"); + + ixOsalSemaphoreWait(&eventQueueSemaphore, IX_OSAL_WAIT_FOREVER); + + IX_ETH_DB_EVENTS_VERBOSE_TRACE("DB: (Events) Received new event\n"); + + if (!ixEthDBLearningShutdown) + { + /* port update handling */ + SET_EMPTY_DEPENDENCY_MAP(triggerPorts); + + while (keepProcessing) + { + PortEvent local_event; + UINT32 intLockKey; + + /* lock queue */ + ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); + + /* lock NPE interrupts */ + intLockKey = ixOsalIrqLock(); + + /* extract event */ + local_event = *(QUEUE_TAIL(&eventQueue)); + + SHIFT_UPDATE_QUEUE(&eventQueue); + + ixOsalIrqUnlock(intLockKey); + + ixOsalMutexUnlock(&eventQueueLock); + + IX_ETH_DB_EVENTS_TRACE("DB: (Events) Processing event with ID 0x%X\n", local_event.eventType); + + ixEthDBProcessEvent(&local_event, triggerPorts); + + processedEvents++; + + if (processedEvents > EVENT_PROCESSING_LIMIT /* maximum burst reached? */ + || ixOsalSemaphoreTryWait(&eventQueueSemaphore) != IX_SUCCESS) /* or empty queue? */ + { + keepProcessing = FALSE; + } + } + + ixEthDBUpdatePortLearningTrees(triggerPorts); + } + } + + /* turn off automatic updates */ + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + ixEthDBPortInfo[portIndex].updateMethod.updateEnabled = FALSE; + } + + ixEthDBEventProcessorRunning = FALSE; +} + +/** + * @brief event processor routine + * + * @param event event to be processed + * @param triggerPorts port map accumulating ports to be updated + * + * Processes learning events by synchronizing the database with + * newly learnt data. Called only by @ref ixEthDBEventProcessorLoop(). + * + * @warning do not call directly + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBProcessEvent(PortEvent *local_event, IxEthDBPortMap triggerPorts) +{ + MacDescriptor recordTemplate; + + switch (local_event->eventType) + { + case IX_ETH_DB_ADD_FILTERING_RECORD: + /* add record */ + memset(&recordTemplate, 0, sizeof (recordTemplate)); + memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr)); + + recordTemplate.type = IX_ETH_DB_FILTERING_RECORD; + recordTemplate.portID = local_event->portID; + recordTemplate.recordData.filteringData.staticEntry = local_event->staticEntry; + + ixEthDBAdd(&recordTemplate, triggerPorts); + + IX_ETH_DB_EVENTS_TRACE("DB: (Events) Added record on port %d\n", local_event->portID); + + break; + + case IX_ETH_DB_REMOVE_FILTERING_RECORD: + /* remove record */ + memset(&recordTemplate, 0, sizeof (recordTemplate)); + memcpy(recordTemplate.macAddress, local_event->macAddr.macAddress, sizeof (IxEthDBMacAddr)); + + recordTemplate.type = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD; + + ixEthDBRemove(&recordTemplate, triggerPorts); + + IX_ETH_DB_EVENTS_TRACE("DB: (Events) Removed record on port %d\n", local_event->portID); + + break; + + default: + /* can't handle/not interested in this event type */ + ERROR_LOG("DB: (Events) Event processor received an unknown event type (0x%X)\n", local_event->eventType); + + return; + } +} + +/** + * @brief asynchronously adds a filtering record + * by posting an ADD_FILTERING_RECORD event to the event queue + * + * @param macAddr MAC address of the new record + * @param portID port ID of the new record + * @param staticEntry TRUE if record is static, FALSE if dynamic + * + * @return IX_ETH_DB_SUCCESS if the event creation was + * successfull or IX_ETH_DB_BUSY if the event queue is full + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry) +{ + MacDescriptor reference; + + TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; + + /* fill search fields */ + memcpy(reference.macAddress, macAddr, sizeof (IxEthDBMacAddr)); + reference.portID = portID; + + /* set acceptable record types */ + reference.type = IX_ETH_DB_ALL_FILTERING_RECORDS; + + if (ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference) == IX_ETH_DB_SUCCESS) + { + /* already have an identical record */ + return IX_ETH_DB_SUCCESS; + } + else + { + return ixEthDBTriggerPortUpdate(IX_ETH_DB_ADD_FILTERING_RECORD, macAddr, portID, staticEntry); + } +} + +/** + * @brief asynchronously removes a filtering record + * by posting a REMOVE_FILTERING_RECORD event to the event queue + * + * @param macAddr MAC address of the record to remove + * @param portID port ID of the record to remove + * + * @return IX_ETH_DB_SUCCESS if the event creation was + * successfull or IX_ETH_DB_BUSY if the event queue is full + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID) +{ + if (ixEthDBPeek(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS) != IX_ETH_DB_NO_SUCH_ADDR) + { + return ixEthDBTriggerPortUpdate(IX_ETH_DB_REMOVE_FILTERING_RECORD, macAddr, portID, FALSE); + } + else + { + return IX_ETH_DB_NO_SUCH_ADDR; + } +} + +/** + * @brief adds an ADD or REMOVE event to the main event queue + * + * @param eventType event type - IX_ETH_DB_ADD_FILTERING_RECORD + * to add and IX_ETH_DB_REMOVE_FILTERING_RECORD to remove a + * record. + * + * @return IX_ETH_DB_SUCCESS if the event was successfully + * sent or IX_ETH_DB_BUSY if the event queue is full + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBTriggerPortUpdate(UINT32 eventType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry) +{ + UINT32 intLockKey; + + /* lock interrupts to protect queue */ + intLockKey = ixOsalIrqLock(); + + if (CAN_ENQUEUE(&eventQueue)) + { + PortEvent *queueEvent = QUEUE_HEAD(&eventQueue); + + /* update fields on the queue */ + memcpy(queueEvent->macAddr.macAddress, macAddr->macAddress, sizeof (IxEthDBMacAddr)); + + queueEvent->eventType = eventType; + queueEvent->portID = portID; + queueEvent->staticEntry = staticEntry; + + PUSH_UPDATE_QUEUE(&eventQueue); + + /* imcrement event queue semaphore */ + ixOsalSemaphorePost(&eventQueueSemaphore); + + /* unlock interrupts */ + ixOsalIrqUnlock(intLockKey); + + return IX_ETH_DB_SUCCESS; + } + else /* event queue full */ + { + /* unlock interrupts */ + ixOsalIrqUnlock(intLockKey); + + return IX_ETH_DB_BUSY; + } +} + +/** + * @brief Locks learning tree updates and port disable + * + * + * This function locks portUpdateLock single mutex. It is primarily used + * to avoid executing 'port disable' during ELT maintenance. + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBUpdateLock(void) +{ + ixOsalMutexLock(&portUpdateLock, IX_OSAL_WAIT_FOREVER); +} + +/** + * @brief Unlocks learning tree updates and port disable + * + * + * This function unlocks a portUpdateLock mutex. It is primarily used + * to avoid executing 'port disable' during ELT maintenance. + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBUpdateUnlock(void) +{ + ixOsalMutexUnlock(&portUpdateLock); +} + diff --git a/drivers/net/npe/IxEthDBFeatures.c b/drivers/net/npe/IxEthDBFeatures.c new file mode 100644 index 0000000..7a58d26 --- /dev/null +++ b/drivers/net/npe/IxEthDBFeatures.c @@ -0,0 +1,662 @@ +/** + * @file IxEthDBFeatures.c + * + * @brief Implementation of the EthDB feature control API + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxNpeDl.h" +#include "IxEthDBQoS.h" +#include "IxEthDB_p.h" + +/** + * @brief scans the capabilities of the loaded NPE images + * + * This function MUST be called by the ixEthDBInit() function. + * No EthDB features (including learning and filtering) are enabled + * before this function is called. + * + * @return none + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBFeatureCapabilityScan(void) +{ + IxNpeDlImageId imageId, npeAImageId; + IxEthDBPortId portIndex; + PortInfo *portInfo; + IxEthDBPriorityTable defaultPriorityTable; + IX_STATUS result; + UINT32 queueIndex; + UINT32 queueStructureIndex; + UINT32 trafficClassDefinitionIndex; + + /* read version of NPE A - required to set the AQM queues for B and C */ + npeAImageId.functionalityId = 0; + ixNpeDlLoadedImageGet(IX_NPEDL_NPEID_NPEA, &npeAImageId); + + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + IxNpeMhMessage msg; + + portInfo = &ixEthDBPortInfo[portIndex]; + + /* check and bypass if NPE B or C is fused out */ + if (ixEthDBSingleEthNpeCheck(portIndex) != IX_ETH_DB_SUCCESS) continue; + + /* all ports are capable of LEARNING by default */ + portInfo->featureCapability |= IX_ETH_DB_LEARNING; + portInfo->featureStatus |= IX_ETH_DB_LEARNING; + + if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) + { + + if (ixNpeDlLoadedImageGet(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), &imageId) != IX_SUCCESS) + { + WARNING_LOG("DB: (FeatureScan) NpeDl did not provide the image ID for NPE port %d\n", portIndex); + } + else + { + /* initialize and empty NPE response mutex */ + ixOsalMutexInit(&portInfo->npeAckLock); + ixOsalMutexLock(&portInfo->npeAckLock, IX_OSAL_WAIT_FOREVER); + + /* check NPE response to GetStatus */ + msg.data[0] = IX_ETHNPE_NPE_GETSTATUS << 24; + msg.data[1] = 0; + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portIndex), msg, result); + if (result != IX_SUCCESS) + { + WARNING_LOG("DB: (FeatureScan) warning, could not send message to the NPE\n"); + continue; + } + + + if (imageId.functionalityId == 0x00 + || imageId.functionalityId == 0x03 + || imageId.functionalityId == 0x04 + || imageId.functionalityId == 0x80) + { + portInfo->featureCapability |= IX_ETH_DB_FILTERING; + portInfo->featureCapability |= IX_ETH_DB_FIREWALL; + portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; + } + else if (imageId.functionalityId == 0x01 + || imageId.functionalityId == 0x81) + { + portInfo->featureCapability |= IX_ETH_DB_FILTERING; + portInfo->featureCapability |= IX_ETH_DB_FIREWALL; + portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; + portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS; + } + else if (imageId.functionalityId == 0x02 + || imageId.functionalityId == 0x82) + { + portInfo->featureCapability |= IX_ETH_DB_WIFI_HEADER_CONVERSION; + portInfo->featureCapability |= IX_ETH_DB_FIREWALL; + portInfo->featureCapability |= IX_ETH_DB_SPANNING_TREE_PROTOCOL; + portInfo->featureCapability |= IX_ETH_DB_VLAN_QOS; + } + + /* reset AQM queues */ + memset(portInfo->ixEthDBTrafficClassAQMAssignments, 0, sizeof (portInfo->ixEthDBTrafficClassAQMAssignments)); + + /* ensure there's at least one traffic class record in the definition table, otherwise we have no default case, hence no queues */ + IX_ENSURE(sizeof (ixEthDBTrafficClassDefinitions) != 0, "DB: no traffic class definitions found, check IxEthDBQoS.h"); + + /* find the traffic class definition index compatible with the current NPE A functionality ID */ + for (trafficClassDefinitionIndex = 0 ; + trafficClassDefinitionIndex < sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0]); + trafficClassDefinitionIndex++) + { + if (ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX] == npeAImageId.functionalityId) + { + /* found it */ + break; + } + } + + /* select the default case if we went over the array boundary */ + if (trafficClassDefinitionIndex == sizeof (ixEthDBTrafficClassDefinitions) / sizeof (ixEthDBTrafficClassDefinitions[0])) + { + trafficClassDefinitionIndex = 0; /* the first record is the default case */ + } + + /* select queue assignment structure based on the traffic class configuration index */ + queueStructureIndex = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX]; + + /* only traffic class 0 is active at initialization time */ + portInfo->ixEthDBTrafficClassCount = 1; + + /* enable port, VLAN and Firewall feature bits to initialize QoS/VLAN/Firewall configuration */ + portInfo->featureStatus |= IX_ETH_DB_VLAN_QOS; + portInfo->featureStatus |= IX_ETH_DB_FIREWALL; + portInfo->enabled = TRUE; + +#define CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ +#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ + /* set VLAN initial configuration (permissive) */ + if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) /* QoS-enabled image */ + { + /* QoS capable */ + portInfo->ixEthDBTrafficClassAvailable = ixEthDBTrafficClassDefinitions[trafficClassDefinitionIndex][IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX]; + + /* set AQM queues */ + for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++) + { + portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = ixEthDBQueueAssignments[queueStructureIndex][queueIndex]; + } + + /* set default PVID (0) and default traffic class 0 */ + ixEthDBPortVlanTagSet(portIndex, 0); + + /* enable reception of all frames */ + ixEthDBAcceptableFrameTypeSet(portIndex, IX_ETH_DB_ACCEPT_ALL_FRAMES); + + /* clear full VLAN membership */ + ixEthDBPortVlanMembershipRangeRemove(portIndex, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID); + + /* clear TTI table - no VLAN tagged frames will be transmitted */ + ixEthDBEgressVlanRangeTaggingEnabledSet(portIndex, 0, 4094, FALSE); + + /* set membership on 0, otherwise no Tx or Rx is working */ + ixEthDBPortVlanMembershipAdd(portIndex, 0); + } + else /* QoS not available in this image */ +#endif /* test-only */ + { + /* initialize traffic class availability (only class 0 is available) */ + portInfo->ixEthDBTrafficClassAvailable = 1; + + /* point all AQM queues to traffic class 0 */ + for (queueIndex = 0 ; queueIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; queueIndex++) + { + portInfo->ixEthDBTrafficClassAQMAssignments[queueIndex] = + ixEthDBQueueAssignments[queueStructureIndex][0]; + } + } + +#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ + /* download priority mapping table and Rx queue configuration */ + memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable)); + ixEthDBPriorityMappingTableSet(portIndex, defaultPriorityTable); +#endif + + /* by default we turn off invalid source MAC address filtering */ + ixEthDBFirewallInvalidAddressFilterEnable(portIndex, FALSE); + + /* disable port, VLAN, Firewall feature bits */ + portInfo->featureStatus &= ~IX_ETH_DB_VLAN_QOS; + portInfo->featureStatus &= ~IX_ETH_DB_FIREWALL; + portInfo->enabled = FALSE; + + /* enable filtering by default if present */ + if ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0) + { + portInfo->featureStatus |= IX_ETH_DB_FILTERING; + } + } + } + } +} + +/** + * @brief returns the capability of a port + * + * @param portID ID of the port + * @param featureSet location to store the port capability in + * + * This function will save the capability set of the given port + * into the given location. Capabilities are bit-ORed, each representing + * a bit of the feature set. + * + * Note that this function is documented in the main component + * public header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or IX_ETH_DB_INVALID_PORT if the given port is invalid + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet) +{ + IX_ETH_DB_CHECK_PORT_INITIALIZED(portID); + + IX_ETH_DB_CHECK_REFERENCE(featureSet); + + *featureSet = ixEthDBPortInfo[portID].featureCapability; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief enables or disables a port capability + * + * @param portID ID of the port + * @param feature feature to enable or disable + * @param enabled TRUE to enable the selected feature or FALSE to disable it + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enable) +{ + PortInfo *portInfo; + IxEthDBPriorityTable defaultPriorityTable; + IxEthDBVlanSet vlanSet; + IxEthDBStatus status = IX_ETH_DB_SUCCESS; + BOOL portEnabled; + + IX_ETH_DB_CHECK_PORT_INITIALIZED(portID); + + portInfo = &ixEthDBPortInfo[portID]; + portEnabled = portInfo->enabled; + + /* check that only one feature is selected */ + if (!ixEthDBCheckSingleBitValue(feature)) + { + return IX_ETH_DB_FEATURE_UNAVAILABLE; + } + + /* port capable of this feature? */ + if ((portInfo->featureCapability & feature) == 0) + { + return IX_ETH_DB_FEATURE_UNAVAILABLE; + } + + /* mutual exclusion between learning and WiFi header conversion */ + if (enable && ((feature | portInfo->featureStatus) & (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION)) + == (IX_ETH_DB_FILTERING | IX_ETH_DB_WIFI_HEADER_CONVERSION)) + { + return IX_ETH_DB_NO_PERMISSION; + } + + /* learning must be enabled before filtering */ + if (enable && (feature == IX_ETH_DB_FILTERING) && ((portInfo->featureStatus & IX_ETH_DB_LEARNING) == 0)) + { + return IX_ETH_DB_NO_PERMISSION; + } + + /* filtering must be disabled before learning */ + if (!enable && (feature == IX_ETH_DB_LEARNING) && ((portInfo->featureStatus & IX_ETH_DB_FILTERING) != 0)) + { + return IX_ETH_DB_NO_PERMISSION; + } + + /* redundant enabling or disabling */ + if ((!enable && ((portInfo->featureStatus & feature) == 0)) + || (enable && ((portInfo->featureStatus & feature) != 0))) + { + /* do nothing */ + return IX_ETH_DB_SUCCESS; + } + + /* force port enabled */ + portInfo->enabled = TRUE; + + if (enable) + { + /* turn on enable bit */ + portInfo->featureStatus |= feature; + +#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ + /* if this is VLAN/QoS set the default priority table */ + if (feature == IX_ETH_DB_VLAN_QOS) + { + /* turn on VLAN/QoS (most permissive mode): + - set default 802.1Q priority mapping table, in accordance to the + availability of traffic classes + - set the acceptable frame filter to accept all + - set the Ingress tagging mode to pass-through + - set full VLAN membership list + - set full TTI table + - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0) + - enable TPID port extraction + */ + + portInfo->ixEthDBTrafficClassCount = portInfo->ixEthDBTrafficClassAvailable; + + /* set default 802.1Q priority mapping table - note that C indexing starts from 0, so we substract 1 here */ + memcpy (defaultPriorityTable, + (const void *) ixEthIEEE802_1QUserPriorityToTrafficClassMapping[portInfo->ixEthDBTrafficClassCount - 1], + sizeof (defaultPriorityTable)); + + /* update priority mapping and AQM queue assignments */ + status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable); + + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES); + } + + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH); + } + + /* set membership and TTI tables */ + memset (vlanSet, 0xFF, sizeof (vlanSet)); + + if (status == IX_ETH_DB_SUCCESS) + { + /* use the internal function to bypass PVID check */ + status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet); + } + + if (status == IX_ETH_DB_SUCCESS) + { + /* use the internal function to bypass PVID check */ + status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet); + } + + /* reset the PVID */ + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBPortVlanTagSet(portID, 0); + } + + /* enable TPID port extraction */ + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBVlanPortExtractionEnable(portID, TRUE); + } + } + else if (feature == IX_ETH_DB_FIREWALL) +#endif + { + /* firewall starts in black-list mode unless otherwise configured before * + * note that invalid source MAC address filtering is disabled by default */ + if (portInfo->firewallMode != IX_ETH_DB_FIREWALL_BLACK_LIST + && portInfo->firewallMode != IX_ETH_DB_FIREWALL_WHITE_LIST) + { + status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST); + + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE); + } + } + } + + if (status != IX_ETH_DB_SUCCESS) + { + /* checks failed, disable */ + portInfo->featureStatus &= ~feature; + } + } + else + { + /* turn off features */ + if (feature == IX_ETH_DB_FIREWALL) + { + /* turning off the firewall is equivalent to: + - set to black-list mode + - clear all the entries and download the new table + - turn off the invalid source address checking + */ + + status = ixEthDBDatabaseClear(portID, IX_ETH_DB_FIREWALL_RECORD); + + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBFirewallModeSet(portID, IX_ETH_DB_FIREWALL_BLACK_LIST); + } + + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBFirewallInvalidAddressFilterEnable(portID, FALSE); + } + + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBFirewallTableDownload(portID); + } + } + else if (feature == IX_ETH_DB_WIFI_HEADER_CONVERSION) + { + /* turn off header conversion */ + status = ixEthDBDatabaseClear(portID, IX_ETH_DB_WIFI_RECORD); + + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBWiFiConversionTableDownload(portID); + } + } +#ifdef CONFIG_WITH_VLAN /* test-only: VLAN support not included to save space!!! */ + else if (feature == IX_ETH_DB_VLAN_QOS) + { + /* turn off VLAN/QoS: + - set a priority mapping table with one traffic class + - set the acceptable frame filter to accept all + - set the Ingress tagging mode to pass-through + - clear the VLAN membership list + - clear the TTI table + - set the default 802.1Q tag to 0 (VLAN ID 0, Pri 0, CFI 0) + - disable TPID port extraction + */ + + /* initialize all => traffic class 0 priority mapping table */ + memset (defaultPriorityTable, 0, sizeof (defaultPriorityTable)); + portInfo->ixEthDBTrafficClassCount = 1; + status = ixEthDBPriorityMappingTableSet(portID, defaultPriorityTable); + + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBAcceptableFrameTypeSet(portID, IX_ETH_DB_ACCEPT_ALL_FRAMES); + } + + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBIngressVlanTaggingEnabledSet(portID, IX_ETH_DB_PASS_THROUGH); + } + + /* clear membership and TTI tables */ + memset (vlanSet, 0, sizeof (vlanSet)); + + if (status == IX_ETH_DB_SUCCESS) + { + /* use the internal function to bypass PVID check */ + status = ixEthDBPortVlanTableSet(portID, portInfo->vlanMembership, vlanSet); + } + + if (status == IX_ETH_DB_SUCCESS) + { + /* use the internal function to bypass PVID check */ + status = ixEthDBPortVlanTableSet(portID, portInfo->transmitTaggingInfo, vlanSet); + } + + /* reset the PVID */ + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBPortVlanTagSet(portID, 0); + } + + /* disable TPID port extraction */ + if (status == IX_ETH_DB_SUCCESS) + { + status = ixEthDBVlanPortExtractionEnable(portID, FALSE); + } + } +#endif + + if (status == IX_ETH_DB_SUCCESS) + { + /* checks passed, disable */ + portInfo->featureStatus &= ~feature; + } + } + + /* restore port enabled state */ + portInfo->enabled = portEnabled; + + return status; +} + +/** + * @brief returns the status of a feature + * + * @param portID port ID + * @param present location to store a boolean value indicating + * if the feature is present (TRUE) or not (FALSE) + * @param enabled location to store a booleam value indicating + * if the feature is present (TRUE) or not (FALSE) + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled) +{ + PortInfo *portInfo; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_REFERENCE(present); + + IX_ETH_DB_CHECK_REFERENCE(enabled); + + portInfo = &ixEthDBPortInfo[portID]; + + *present = (portInfo->featureCapability & feature) != 0; + *enabled = (portInfo->featureStatus & feature) != 0; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief returns the value of an EthDB property + * + * @param portID ID of the port + * @param feature feature owning the property + * @param property ID of the property + * @param type location to store the property type into + * @param value location to store the property value into + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value) +{ + IX_ETH_DB_CHECK_PORT_EXISTS(portID); + + IX_ETH_DB_CHECK_REFERENCE(type); + + IX_ETH_DB_CHECK_REFERENCE(value); + + if (feature == IX_ETH_DB_VLAN_QOS) + { + if (property == IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY) + { + * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount; + *type = IX_ETH_DB_INTEGER_PROPERTY; + + return IX_ETH_DB_SUCCESS; + } + else if (property >= IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY + && property <= IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY) + { + UINT32 classDelta = property - IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY; + + if (classDelta >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) + { + return IX_ETH_DB_FAIL; + } + + * (UINT32 *) value = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[classDelta]; + *type = IX_ETH_DB_INTEGER_PROPERTY; + + return IX_ETH_DB_SUCCESS; + } + } + + return IX_ETH_DB_INVALID_ARG; +} + +/** + * @brief sets the value of an EthDB property + * + * @param portID ID of the port + * @param feature feature owning the property + * @param property ID of the property + * @param value location containing the property value + * + * This function implements a private property intended + * only for EthAcc usage. Upon setting the IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE + * property (the value is ignored), the availability of traffic classes is + * frozen to whatever traffic class structure is currently in use. + * This means that if VLAN_QOS has been enabled before EthAcc + * initialization then all the defined traffic classes will be available; + * otherwise only one traffic class (0) will be available. + * + * Note that this function is documented in the main component + * header file, IxEthDB.h as not accepting any parameters. The + * current implementation is only intended for the private use of EthAcc. + * + * Also note that once this function is called the effect is irreversible, + * unless EthDB is complete unloaded and re-initialized. + * + * @return IX_ETH_DB_INVALID_ARG (no read-write properties are + * supported in this release) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value) +{ + IX_ETH_DB_CHECK_PORT_EXISTS(portID); + + if ((feature == IX_ETH_DB_VLAN_QOS) && (property == IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE)) + { + ixEthDBPortInfo[portID].ixEthDBTrafficClassAvailable = ixEthDBPortInfo[portID].ixEthDBTrafficClassCount; + + return IX_ETH_DB_SUCCESS; + } + + return IX_ETH_DB_INVALID_ARG; +} diff --git a/drivers/net/npe/IxEthDBFirewall.c b/drivers/net/npe/IxEthDBFirewall.c new file mode 100644 index 0000000..eb46174 --- /dev/null +++ b/drivers/net/npe/IxEthDBFirewall.c @@ -0,0 +1,266 @@ +/** + * @file IxEthDBFirewall.c + * + * @brief Implementation of the firewall API + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + + +#include "IxEthDB_p.h" + +/** + * @brief updates the NPE firewall operating mode and + * firewall address table + * + * @param portID ID of the port + * @param epDelta initial entry point for binary searches (NPE optimization) + * @param address address of the firewall MAC address table + * + * This function will send a message to the NPE configuring the + * firewall mode (white list or black list), invalid source + * address filtering and downloading a new MAC address database + * to be used for firewall matching. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or IX_ETH_DB_FAIL otherwise + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta) +{ + IxNpeMhMessage message; + IX_STATUS result; + + UINT32 mode = 0; + PortInfo *portInfo = &ixEthDBPortInfo[portID]; + + mode = (portInfo->srcAddressFilterEnabled != FALSE) << 1 | (portInfo->firewallMode == IX_ETH_DB_FIREWALL_WHITE_LIST); + + FILL_SETFIREWALLMODE_MSG(message, + IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), + epDelta, + mode, + IX_OSAL_MMU_VIRT_TO_PHYS(address)); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief configures the firewall white list/black list + * access mode + * + * @param portID ID of the port + * @param mode firewall filtering mode (IX_ETH_DB_FIREWALL_WHITE_LIST + * or IX_ETH_DB_FIREWALL_BLACK_LIST) + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL); + + if (mode != IX_ETH_DB_FIREWALL_WHITE_LIST + && mode != IX_ETH_DB_FIREWALL_BLACK_LIST) + { + return IX_ETH_DB_INVALID_ARG; + } + + ixEthDBPortInfo[portID].firewallMode = mode; + + return ixEthDBFirewallTableDownload(portID); +} + +/** + * @brief enables or disables the invalid source MAC address filter + * + * @param portID ID of the port + * @param enable TRUE to enable invalid source MAC address filtering + * or FALSE to disable it + * + * The invalid source MAC address filter will discard, when enabled, + * frames whose source MAC address is a multicast or the broadcast MAC + * address. + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL); + + ixEthDBPortInfo[portID].srcAddressFilterEnabled = enable; + + return ixEthDBFirewallTableDownload(portID); +} + +/** + * @brief adds a firewall record + * + * @param portID ID of the port + * @param macAddr MAC address of the new record + * + * This function will add a new firewall record + * on the specified port, using the specified + * MAC address. If the record already exists this + * function will silently return IX_ETH_DB_SUCCESS, + * although no duplicate records are added. + * + * Note that this function is documented in the main + * component header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) +{ + MacDescriptor recordTemplate; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL); + + memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr)); + + recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD; + recordTemplate.portID = portID; + + return ixEthDBAdd(&recordTemplate, NULL); +} + +/** + * @brief removes a firewall record + * + * @param portID ID of the port + * @param macAddr MAC address of the record to remove + * + * This function will attempt to remove a firewall + * record from the given port, using the specified + * MAC address. + * + * Note that this function is documented in the main + * component header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully of an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) +{ + MacDescriptor recordTemplate; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL); + + memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr)); + + recordTemplate.type = IX_ETH_DB_FIREWALL_RECORD; + recordTemplate.portID = portID; + + return ixEthDBRemove(&recordTemplate, NULL); +} + +/** + * @brief downloads the firewall address table to an NPE + * + * @param portID ID of the port + * + * This function will download the firewall address table to + * an NPE port. + * + * Note that this function is documented in the main + * component header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or IX_ETH_DB_FAIL otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID) +{ + IxEthDBPortMap query; + IxEthDBStatus result; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_FIREWALL); + + SET_DEPENDENCY_MAP(query, portID); + + ixEthDBUpdateLock(); + + ixEthDBPortInfo[portID].updateMethod.searchTree = ixEthDBQuery(NULL, query, IX_ETH_DB_FIREWALL_RECORD, MAX_FW_SIZE); + + result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FIREWALL_RECORD); + + ixEthDBUpdateUnlock(); + + return result; +} diff --git a/drivers/net/npe/IxEthDBHashtable.c b/drivers/net/npe/IxEthDBHashtable.c new file mode 100644 index 0000000..f1b18e6 --- /dev/null +++ b/drivers/net/npe/IxEthDBHashtable.c @@ -0,0 +1,642 @@ +/** + * @file ethHash.c + * + * @brief Hashtable implementation + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + + +#include "IxEthDB_p.h" +#include "IxEthDBLocks_p.h" + +/** + * @addtogroup EthDB + * + * @{ + */ + +/** + * @brief initializes a hash table object + * + * @param hashTable uninitialized hash table structure + * @param numBuckets number of buckets to use + * @param entryHashFunction hash function used + * to hash entire hash node data block (for adding) + * @param matchFunctions array of match functions, indexed on type, + * used to differentiate records with the same hash value + * @param freeFunction function used to free node data blocks + * + * Initializes the given hash table object. + * + * @internal + */ +void ixEthDBInitHash(HashTable *hashTable, + UINT32 numBuckets, + HashFunction entryHashFunction, + MatchFunction *matchFunctions, + FreeFunction freeFunction) +{ + UINT32 bucketIndex; + UINT32 hashSize = numBuckets * sizeof(HashNode *); + + /* entry hashing, matching and freeing methods */ + hashTable->entryHashFunction = entryHashFunction; + hashTable->matchFunctions = matchFunctions; + hashTable->freeFunction = freeFunction; + + /* buckets */ + hashTable->numBuckets = numBuckets; + + /* set to 0 all buckets */ + memset(hashTable->hashBuckets, 0, hashSize); + + /* init bucket locks - note that initially all mutexes are unlocked after MutexInit()*/ + for (bucketIndex = 0 ; bucketIndex < numBuckets ; bucketIndex++) + { + ixOsalFastMutexInit(&hashTable->bucketLocks[bucketIndex]); + } +} + +/** + * @brief adds an entry to the hash table + * + * @param hashTable hash table to add the entry to + * @param entry entry to add + * + * The entry will be hashed using the entry hashing function and added to the + * hash table, unless a locking blockage occurs, in which case the caller + * should retry. + * + * @retval IX_ETH_DB_SUCCESS if adding entry has succeeded + * @retval IX_ETH_DB_NOMEM if there's no memory left in the hash node pool + * @retval IX_ETH_DB_BUSY if there's a locking failure on the insertion path + * + * @internal + */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry) +{ + UINT32 hashValue = hashTable->entryHashFunction(entry); + UINT32 bucketIndex = hashValue % hashTable->numBuckets; + HashNode *bucket = hashTable->hashBuckets[bucketIndex]; + HashNode *newNode; + + LockStack locks; + + INIT_STACK(&locks); + + /* lock bucket */ + PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]); + + /* lock insertion element (first in chain), if any */ + if (bucket != NULL) + { + PUSH_LOCK(&locks, &bucket->lock); + } + + /* get new node */ + newNode = ixEthDBAllocHashNode(); + + if (newNode == NULL) + { + /* unlock everything */ + UNROLL_STACK(&locks); + + return IX_ETH_DB_NOMEM; + } + + /* init lock - note that mutexes are unlocked after MutexInit */ + ixOsalFastMutexInit(&newNode->lock); + + /* populate new link */ + newNode->data = entry; + + /* add to bucket */ + newNode->next = bucket; + hashTable->hashBuckets[bucketIndex] = newNode; + + /* unlock bucket and insertion point */ + UNROLL_STACK(&locks); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief removes an entry from the hashtable + * + * @param hashTable hash table to remove entry from + * @param keyType type of record key used for matching + * @param reference reference key used to identify the entry + * + * The reference key will be hashed using the key hashing function, + * the entry is searched using the hashed value and then examined + * against the reference entry using the match function. A positive + * match will trigger the deletion of the entry. + * Locking failures are reported and the caller should retry. + * + * @retval IX_ETH_DB_SUCCESS if the removal was successful + * @retval IX_ETH_DB_NO_SUCH_ADDR if the entry was not found + * @retval IX_ETH_DB_BUSY if a locking failure occured during the process + * + * @internal + */ +IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference) +{ + UINT32 hashValue = hashTable->entryHashFunction(reference); + UINT32 bucketIndex = hashValue % hashTable->numBuckets; + HashNode *node = hashTable->hashBuckets[bucketIndex]; + HashNode *previousNode = NULL; + + LockStack locks; + + INIT_STACK(&locks); + + while (node != NULL) + { + /* try to lock node */ + PUSH_LOCK(&locks, &node->lock); + + if (hashTable->matchFunctions[keyType](reference, node->data)) + { + /* found entry */ + if (node->next != NULL) + { + PUSH_LOCK(&locks, &node->next->lock); + } + + if (previousNode == NULL) + { + /* node is head of chain */ + PUSH_LOCK(&locks, &hashTable->bucketLocks[bucketIndex]); + + hashTable->hashBuckets[bucketIndex] = node->next; + + POP_LOCK(&locks); + } + else + { + /* relink */ + previousNode->next = node->next; + } + + UNROLL_STACK(&locks); + + /* free node */ + hashTable->freeFunction(node->data); + ixEthDBFreeHashNode(node); + + return IX_ETH_DB_SUCCESS; + } + else + { + if (previousNode != NULL) + { + /* unlock previous node */ + SHIFT_STACK(&locks); + } + + /* advance to next element in chain */ + previousNode = node; + node = node->next; + } + } + + UNROLL_STACK(&locks); + + /* not found */ + return IX_ETH_DB_NO_SUCH_ADDR; +} + +/** + * @brief retrieves an entry from the hash table + * + * @param hashTable hash table to perform the search into + * @param reference search key (a MAC address) + * @param keyType type of record key used for matching + * @param searchResult pointer where a reference to the located hash node + * is placed + * + * Searches the entry with the same key as reference and places the + * pointer to the resulting node in searchResult. + * An implicit write access lock is granted after a search, which gives the + * caller the opportunity to modify the entry. + * Access should be released as soon as possible using @ref ixEthDBReleaseHashNode(). + * + * @see ixEthDBReleaseHashNode() + * + * @retval IX_ETH_DB_SUCCESS if the search was completed successfully + * @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found + * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case + * the caller should retry + * + * @warning unless the return value is IX_ETH_DB_SUCCESS the searchResult + * location is NOT modified and therefore using a NULL comparison test when the + * value was not properly initialized would be an error + * + * @internal + */ +IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult) +{ + UINT32 hashValue; + HashNode *node; + + hashValue = hashTable->entryHashFunction(reference); + node = hashTable->hashBuckets[hashValue % hashTable->numBuckets]; + + while (node != NULL) + { + TRY_LOCK(&node->lock); + + if (hashTable->matchFunctions[keyType](reference, node->data)) + { + *searchResult = node; + + return IX_ETH_DB_SUCCESS; + } + else + { + UNLOCK(&node->lock); + + node = node->next; + } + } + + /* not found */ + return IX_ETH_DB_NO_SUCH_ADDR; +} + +/** + * @brief reports the existence of an entry in the hash table + * + * @param hashTable hash table to perform the search into + * @param reference search key (a MAC address) + * @param keyType type of record key used for matching + * + * Searches the entry with the same key as reference. + * No implicit write access lock is granted after a search, hence the + * caller cannot access or modify the entry. The result is only temporary. + * + * @see ixEthDBReleaseHashNode() + * + * @retval IX_ETH_DB_SUCCESS if the search was completed successfully + * @retval IX_ETH_DB_NO_SUCH_ADDRESS if no entry with the given key was found + * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case + * the caller should retry + * + * @internal + */ +IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference) +{ + UINT32 hashValue; + HashNode *node; + + hashValue = hashTable->entryHashFunction(reference); + node = hashTable->hashBuckets[hashValue % hashTable->numBuckets]; + + while (node != NULL) + { + TRY_LOCK(&node->lock); + + if (hashTable->matchFunctions[keyType](reference, node->data)) + { + UNLOCK(&node->lock); + + return IX_ETH_DB_SUCCESS; + } + else + { + UNLOCK(&node->lock); + + node = node->next; + } + } + + /* not found */ + return IX_ETH_DB_NO_SUCH_ADDR; +} + +/** + * @brief releases the write access lock + * + * @pre the node should have been obtained via @ref ixEthDBSearchHashEntry() + * + * @see ixEthDBSearchHashEntry() + * + * @internal + */ +void ixEthDBReleaseHashNode(HashNode *node) +{ + UNLOCK(&node->lock); +} + +/** + * @brief initializes a hash iterator + * + * @param hashTable hash table to be iterated + * @param iterator iterator object + * + * If the initialization is successful the iterator will point to the + * first hash table record (if any). + * Testing if the iterator has not passed the end of the table should be + * done using the IS_ITERATOR_VALID(iteratorPtr) macro. + * An implicit write access lock is granted on the entry pointed by the iterator. + * The access is automatically revoked when the iterator is incremented. + * If the caller decides to terminate the iteration before the end of the table is + * passed then the manual access release method, @ref ixEthDBReleaseHashIterator, + * must be called. + * + * @see ixEthDBReleaseHashIterator() + * + * @retval IX_ETH_DB_SUCCESS if initialization was successful and the iterator points + * to the first valid table node + * @retval IX_ETH_DB_FAIL if the table is empty + * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller + * should retry + * + * @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this + * might place the database in a permanent invalid lock state + * + * @internal + */ +IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator) +{ + iterator->bucketIndex = 0; + iterator->node = NULL; + iterator->previousNode = NULL; + + return ixEthDBIncrementHashIterator(hashTable, iterator); +} + +/** + * @brief releases the write access locks of the iterator nodes + * + * @warning use of this function is required only when the caller terminates an iteration + * before reaching the end of the table + * + * @see ixEthDBInitHashIterator() + * @see ixEthDBIncrementHashIterator() + * + * @param iterator iterator whose node(s) should be unlocked + * + * @internal + */ +void ixEthDBReleaseHashIterator(HashIterator *iterator) +{ + if (iterator->previousNode != NULL) + { + UNLOCK(&iterator->previousNode->lock); + } + + if (iterator->node != NULL) + { + UNLOCK(&iterator->node->lock); + } +} + +/** + * @brief incremenents an iterator so that it points to the next valid entry of the table + * (if any) + * + * @param hashTable hash table to iterate + * @param iterator iterator object + * + * @pre the iterator object must be initialized using @ref ixEthDBInitHashIterator() + * + * If the increment operation is successful the iterator will point to the + * next hash table record (if any). + * Testing if the iterator has not passed the end of the table should be + * done using the IS_ITERATOR_VALID(iteratorPtr) macro. + * An implicit write access lock is granted on the entry pointed by the iterator. + * The access is automatically revoked when the iterator is re-incremented. + * If the caller decides to terminate the iteration before the end of the table is + * passed then the manual access release method, @ref ixEthDBReleaseHashIterator, + * must be called. + * Is is guaranteed that no other thread can remove or change the iterated entry until + * the iterator is incremented successfully. + * + * @see ixEthDBReleaseHashIterator() + * + * @retval IX_ETH_DB_SUCCESS if the operation was successful and the iterator points + * to the next valid table node + * @retval IX_ETH_DB_FAIL if the iterator has passed the end of the table + * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller + * should retry + * + * @warning do not use ixEthDBReleaseHashNode() on entries pointed by the iterator, as this + * might place the database in a permanent invalid lock state + * + * @internal + */ +IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator) +{ + /* unless iterator is just initialized... */ + if (iterator->node != NULL) + { + /* try next in chain */ + if (iterator->node->next != NULL) + { + TRY_LOCK(&iterator->node->next->lock); + + if (iterator->previousNode != NULL) + { + UNLOCK(&iterator->previousNode->lock); + } + + iterator->previousNode = iterator->node; + iterator->node = iterator->node->next; + + return IX_ETH_DB_SUCCESS; + } + else + { + /* last in chain, prepare for next bucket */ + iterator->bucketIndex++; + } + } + + /* try next used bucket */ + for (; iterator->bucketIndex < hashTable->numBuckets ; iterator->bucketIndex++) + { + HashNode **nodePtr = &(hashTable->hashBuckets[iterator->bucketIndex]); + HashNode *node = *nodePtr; +#if (CPU!=SIMSPARCSOLARIS) && !defined (__wince) + if (((iterator->bucketIndex & IX_ETHDB_BUCKET_INDEX_MASK) == 0) && + (iterator->bucketIndex < (hashTable->numBuckets - IX_ETHDB_BUCKETPTR_AHEAD))) + { + /* preload next cache line (2 cache line ahead) */ + nodePtr += IX_ETHDB_BUCKETPTR_AHEAD; + __asm__ ("pld [%0];\n": : "r" (nodePtr)); + } +#endif + if (node != NULL) + { + TRY_LOCK(&node->lock); + + /* unlock last one or two nodes in the previous chain */ + if (iterator->node != NULL) + { + UNLOCK(&iterator->node->lock); + + if (iterator->previousNode != NULL) + { + UNLOCK(&iterator->previousNode->lock); + } + } + + /* redirect iterator */ + iterator->previousNode = NULL; + iterator->node = node; + + return IX_ETH_DB_SUCCESS; + } + } + + /* could not advance iterator */ + if (iterator->node != NULL) + { + UNLOCK(&iterator->node->lock); + + if (iterator->previousNode != NULL) + { + UNLOCK(&iterator->previousNode->lock); + } + + iterator->node = NULL; + } + + return IX_ETH_DB_END; +} + +/** + * @brief removes an entry pointed by an iterator + * + * @param hashTable iterated hash table + * @param iterator iterator object + * + * Removes the entry currently pointed by the iterator and repositions the iterator + * on the next valid entry (if any). Handles locking issues automatically and + * implicitely grants write access lock to the new pointed entry. + * Failures due to concurrent threads having write access locks in the same region + * preserve the state of the database and the iterator object, leaving the caller + * free to retry without loss of access. It is guaranteed that only the thread owning + * the iterator can remove the object pointed by the iterator. + * + * @retval IX_ETH_DB_SUCCESS if removal has succeeded + * @retval IX_ETH_DB_BUSY if a locking failure has occured, in which case the caller + * should retry + * + * @internal + */ +IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator) +{ + HashIterator nextIteratorPos; + LockStack locks; + + INIT_STACK(&locks); + + /* set initial bucket index for next position */ + nextIteratorPos.bucketIndex = iterator->bucketIndex; + + /* compute iterator position before removing anything and lock ahead */ + if (iterator->node->next != NULL) + { + PUSH_LOCK(&locks, &iterator->node->next->lock); + + /* reposition on the next node in the chain */ + nextIteratorPos.node = iterator->node->next; + nextIteratorPos.previousNode = iterator->previousNode; + } + else + { + /* try next chain - don't know yet if we'll find anything */ + nextIteratorPos.node = NULL; + + /* if we find something it's a chain head */ + nextIteratorPos.previousNode = NULL; + + /* browse up in the buckets to find a non-null chain */ + while (++nextIteratorPos.bucketIndex < hashTable->numBuckets) + { + nextIteratorPos.node = hashTable->hashBuckets[nextIteratorPos.bucketIndex]; + + if (nextIteratorPos.node != NULL) + { + /* found a non-empty chain, try to lock head */ + PUSH_LOCK(&locks, &nextIteratorPos.node->lock); + + break; + } + } + } + + /* restore links over the to-be-deleted item */ + if (iterator->previousNode == NULL) + { + /* first in chain, lock bucket */ + PUSH_LOCK(&locks, &hashTable->bucketLocks[iterator->bucketIndex]); + + hashTable->hashBuckets[iterator->bucketIndex] = iterator->node->next; + + POP_LOCK(&locks); + } + else + { + /* relink */ + iterator->previousNode->next = iterator->node->next; + + /* unlock last remaining node in current chain when moving between chains */ + if (iterator->node->next == NULL) + { + UNLOCK(&iterator->previousNode->lock); + } + } + + /* delete entry */ + hashTable->freeFunction(iterator->node->data); + ixEthDBFreeHashNode(iterator->node); + + /* reposition iterator */ + *iterator = nextIteratorPos; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @} + */ diff --git a/drivers/net/npe/IxEthDBLearning.c b/drivers/net/npe/IxEthDBLearning.c new file mode 100644 index 0000000..2287dbe --- /dev/null +++ b/drivers/net/npe/IxEthDBLearning.c @@ -0,0 +1,149 @@ +/** + * @file IxEthDBLearning.c + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxEthDB_p.h" + +/** + * @brief hashes the mac address in a mac descriptor with a XOR function + * + * @param entry pointer to a mac descriptor to be hashed + * + * This function only extracts the mac address and employs ixEthDBKeyXORHash() + * to do the actual hashing. + * Used only to add a whole entry to a hash table, as opposed to searching which + * takes only a key and uses the key hashing directly. + * + * @see ixEthDBKeyXORHash() + * + * @return the hash value + * + * @internal + */ +UINT32 ixEthDBEntryXORHash(void *entry) +{ + MacDescriptor *descriptor = (MacDescriptor *) entry; + + return ixEthDBKeyXORHash(descriptor->macAddress); +} + +/** + * @brief hashes a mac address + * + * @param key pointer to a 6 byte structure (typically an IxEthDBMacAddr pointer) + * to be hashed + * + * Given a 6 bytes MAC address, the hash used is: + * + * hash(MAC[0:5]) = MAC[0:1] ^ MAC[2:3] ^ MAC[4:5] + * + * Used by the hash table to search and remove entries based + * solely on their keys (mac addresses). + * + * @return the hash value + * + * @internal + */ +UINT32 ixEthDBKeyXORHash(void *key) +{ + UINT32 hashValue; + UINT8 *value = (UINT8 *) key; + + hashValue = (value[5] << 8) | value[4]; + hashValue ^= (value[3] << 8) | value[2]; + hashValue ^= (value[1] << 8) | value[0]; + + return hashValue; +} + +/** + * @brief mac descriptor match function + * + * @param reference mac address (typically an IxEthDBMacAddr pointer) structure + * @param entry pointer to a mac descriptor whose key (mac address) is to be + * matched against the reference key + * + * Used by the hash table to retrieve entries. Hashing entries can produce + * collisions, i.e. descriptors with different mac addresses and the same + * hash value, where this function is used to differentiate entries. + * + * @retval TRUE if the entry matches the reference key (equal addresses) + * @retval FALSE if the entry does not match the reference key + * + * @internal + */ +BOOL ixEthDBAddressMatch(void *reference, void *entry) +{ + return (ixEthDBAddressCompare(reference, ((MacDescriptor *) entry)->macAddress) == 0); +} + +/** + * @brief compares two mac addresses + * + * @param mac1 first mac address to compare + * @param mac2 second mac address to compare + * + * This comparison works in a similar way to strcmp, producing similar results. + * Used to insert values keyed on mac addresses into binary search trees. + * + * @retval -1 if mac1 < mac2 + * @retval 0 if ma1 == mac2 + * @retval 1 if mac1 > mac2 + */ +UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2) +{ + UINT32 local_index; + + for (local_index = 0 ; local_index < IX_IEEE803_MAC_ADDRESS_SIZE ; local_index++) + { + if (mac1[local_index] > mac2[local_index]) + { + return 1; + } + else if (mac1[local_index] < mac2[local_index]) + { + return -1; + } + } + + return 0; +} + diff --git a/drivers/net/npe/IxEthDBMem.c b/drivers/net/npe/IxEthDBMem.c new file mode 100644 index 0000000..133cbef --- /dev/null +++ b/drivers/net/npe/IxEthDBMem.c @@ -0,0 +1,649 @@ +/** + * @file IxEthDBDBMem.c + * + * @brief Memory handling routines for the MAC address database + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + + +#include "IxEthDB_p.h" + +IX_ETH_DB_PRIVATE HashNode *nodePool = NULL; +IX_ETH_DB_PRIVATE MacDescriptor *macPool = NULL; +IX_ETH_DB_PRIVATE MacTreeNode *treePool = NULL; + +IX_ETH_DB_PRIVATE HashNode nodePoolArea[NODE_POOL_SIZE]; +IX_ETH_DB_PRIVATE MacDescriptor macPoolArea[MAC_POOL_SIZE]; +IX_ETH_DB_PRIVATE MacTreeNode treePoolArea[TREE_POOL_SIZE]; + +IX_ETH_DB_PRIVATE IxOsalMutex nodePoolLock; +IX_ETH_DB_PRIVATE IxOsalMutex macPoolLock; +IX_ETH_DB_PRIVATE IxOsalMutex treePoolLock; + +#define LOCK_NODE_POOL { ixOsalMutexLock(&nodePoolLock, IX_OSAL_WAIT_FOREVER); } +#define UNLOCK_NODE_POOL { ixOsalMutexUnlock(&nodePoolLock); } + +#define LOCK_MAC_POOL { ixOsalMutexLock(&macPoolLock, IX_OSAL_WAIT_FOREVER); } +#define UNLOCK_MAC_POOL { ixOsalMutexUnlock(&macPoolLock); } + +#define LOCK_TREE_POOL { ixOsalMutexLock(&treePoolLock, IX_OSAL_WAIT_FOREVER); } +#define UNLOCK_TREE_POOL { ixOsalMutexUnlock(&treePoolLock); } + +/* private function prototypes */ +IX_ETH_DB_PRIVATE MacDescriptor* ixEthDBPoolAllocMacDescriptor(void); +IX_ETH_DB_PRIVATE void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor); + +/** + * @addtogroup EthMemoryManagement + * + * @{ + */ + +/** + * @brief initializes the memory pools used by the ethernet database component + * + * Initializes the hash table node, mac descriptor and mac tree node pools. + * Called at initialization time by @ref ixEthDBInit(). + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBInitMemoryPools(void) +{ + int local_index; + + /* HashNode pool */ + ixOsalMutexInit(&nodePoolLock); + + for (local_index = 0 ; local_index < NODE_POOL_SIZE ; local_index++) + { + HashNode *freeNode = &nodePoolArea[local_index]; + + freeNode->nextFree = nodePool; + nodePool = freeNode; + } + + /* MacDescriptor pool */ + ixOsalMutexInit(&macPoolLock); + + for (local_index = 0 ; local_index < MAC_POOL_SIZE ; local_index++) + { + MacDescriptor *freeDescriptor = &macPoolArea[local_index]; + + freeDescriptor->nextFree = macPool; + macPool = freeDescriptor; + } + + /* MacTreeNode pool */ + ixOsalMutexInit(&treePoolLock); + + for (local_index = 0 ; local_index < TREE_POOL_SIZE ; local_index++) + { + MacTreeNode *freeNode = &treePoolArea[local_index]; + + freeNode->nextFree = treePool; + treePool = freeNode; + } +} + +/** + * @brief allocates a hash node from the pool + * + * Allocates a hash node and resets its value. + * + * @return the allocated hash node or NULL if the pool is empty + * + * @internal + */ +IX_ETH_DB_PUBLIC +HashNode* ixEthDBAllocHashNode(void) +{ + HashNode *allocatedNode = NULL; + + if (nodePool != NULL) + { + LOCK_NODE_POOL; + + allocatedNode = nodePool; + nodePool = nodePool->nextFree; + + UNLOCK_NODE_POOL; + + memset(allocatedNode, 0, sizeof(HashNode)); + } + + return allocatedNode; +} + +/** + * @brief frees a hash node into the pool + * + * @param hashNode node to be freed + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBFreeHashNode(HashNode *hashNode) +{ + if (hashNode != NULL) + { + LOCK_NODE_POOL; + + hashNode->nextFree = nodePool; + nodePool = hashNode; + + UNLOCK_NODE_POOL; + } +} + +/** + * @brief allocates a mac descriptor from the pool + * + * Allocates a mac descriptor and resets its value. + * This function is not used directly, instead @ref ixEthDBAllocMacDescriptor() + * is used, which keeps track of the pointer reference count. + * + * @see ixEthDBAllocMacDescriptor() + * + * @warning this function is not used directly by any other function + * apart from ixEthDBAllocMacDescriptor() + * + * @return the allocated mac descriptor or NULL if the pool is empty + * + * @internal + */ +IX_ETH_DB_PRIVATE +MacDescriptor* ixEthDBPoolAllocMacDescriptor(void) +{ + MacDescriptor *allocatedDescriptor = NULL; + + if (macPool != NULL) + { + LOCK_MAC_POOL; + + allocatedDescriptor = macPool; + macPool = macPool->nextFree; + + UNLOCK_MAC_POOL; + + memset(allocatedDescriptor, 0, sizeof(MacDescriptor)); + } + + return allocatedDescriptor; +} + +/** + * @brief allocates and initializes a mac descriptor smart pointer + * + * Uses @ref ixEthDBPoolAllocMacDescriptor() to allocate a mac descriptor + * from the pool and initializes its reference count. + * + * @see ixEthDBPoolAllocMacDescriptor() + * + * @return the allocated mac descriptor or NULL if the pool is empty + * + * @internal + */ +IX_ETH_DB_PUBLIC +MacDescriptor* ixEthDBAllocMacDescriptor(void) +{ + MacDescriptor *allocatedDescriptor = ixEthDBPoolAllocMacDescriptor(); + + if (allocatedDescriptor != NULL) + { + LOCK_MAC_POOL; + + allocatedDescriptor->refCount++; + + UNLOCK_MAC_POOL; + } + + return allocatedDescriptor; +} + +/** + * @brief frees a mac descriptor back into the pool + * + * @param macDescriptor mac descriptor to be freed + * + * @warning this function is not to be called by anyone but + * ixEthDBFreeMacDescriptor() + * + * @see ixEthDBFreeMacDescriptor() + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBPoolFreeMacDescriptor(MacDescriptor *macDescriptor) +{ + LOCK_MAC_POOL; + + macDescriptor->nextFree = macPool; + macPool = macDescriptor; + + UNLOCK_MAC_POOL; +} + +/** + * @brief frees or reduces the usage count of a mac descriptor smart pointer + * + * If the reference count reaches 0 (structure is no longer used anywhere) + * then the descriptor is freed back into the pool using ixEthDBPoolFreeMacDescriptor(). + * + * @see ixEthDBPoolFreeMacDescriptor() + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBFreeMacDescriptor(MacDescriptor *macDescriptor) +{ + if (macDescriptor != NULL) + { + LOCK_MAC_POOL; + + if (macDescriptor->refCount > 0) + { + macDescriptor->refCount--; + + if (macDescriptor->refCount == 0) + { + UNLOCK_MAC_POOL; + + ixEthDBPoolFreeMacDescriptor(macDescriptor); + } + else + { + UNLOCK_MAC_POOL; + } + } + else + { + UNLOCK_MAC_POOL; + } + } +} + +/** + * @brief clones a mac descriptor smart pointer + * + * @param macDescriptor mac descriptor to clone + * + * Increments the usage count of the smart pointer + * + * @returns the cloned smart pointer + * + * @internal + */ +IX_ETH_DB_PUBLIC +MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor) +{ + LOCK_MAC_POOL; + + if (macDescriptor->refCount == 0) + { + UNLOCK_MAC_POOL; + + return NULL; + } + + macDescriptor->refCount++; + + UNLOCK_MAC_POOL; + + return macDescriptor; +} + +/** + * @brief allocates a mac tree node from the pool + * + * Allocates and initializes a mac tree node from the pool. + * + * @return the allocated mac tree node or NULL if the pool is empty + * + * @internal + */ +IX_ETH_DB_PUBLIC +MacTreeNode* ixEthDBAllocMacTreeNode(void) +{ + MacTreeNode *allocatedNode = NULL; + + if (treePool != NULL) + { + LOCK_TREE_POOL; + + allocatedNode = treePool; + treePool = treePool->nextFree; + + UNLOCK_TREE_POOL; + + memset(allocatedNode, 0, sizeof(MacTreeNode)); + } + + return allocatedNode; +} + +/** + * @brief frees a mac tree node back into the pool + * + * @param macNode mac tree node to be freed + * + * @warning not to be used except from ixEthDBFreeMacTreeNode(). + * + * @see ixEthDBFreeMacTreeNode() + * + * @internal + */ +void ixEthDBPoolFreeMacTreeNode(MacTreeNode *macNode) +{ + if (macNode != NULL) + { + LOCK_TREE_POOL; + + macNode->nextFree = treePool; + treePool = macNode; + + UNLOCK_TREE_POOL; + } +} + +/** + * @brief frees or reduces the usage count of a mac tree node smart pointer + * + * @param macNode mac tree node to free + * + * Reduces the usage count of the given mac node. If the usage count + * reaches 0 the node is freed back into the pool using ixEthDBPoolFreeMacTreeNode() + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBFreeMacTreeNode(MacTreeNode *macNode) +{ + if (macNode->descriptor != NULL) + { + ixEthDBFreeMacDescriptor(macNode->descriptor); + } + + if (macNode->left != NULL) + { + ixEthDBFreeMacTreeNode(macNode->left); + } + + if (macNode->right != NULL) + { + ixEthDBFreeMacTreeNode(macNode->right); + } + + ixEthDBPoolFreeMacTreeNode(macNode); +} + +/** + * @brief clones a mac tree node + * + * @param macNode mac tree node to be cloned + * + * Increments the usage count of the node, its associated descriptor + * and recursively of all its child nodes. + * + * @warning this function is recursive and clones whole trees/subtrees, use only for + * root nodes + * + * @internal + */ +IX_ETH_DB_PUBLIC +MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *macNode) +{ + if (macNode != NULL) + { + MacTreeNode *clonedMacNode = ixEthDBAllocMacTreeNode(); + + if (clonedMacNode != NULL) + { + if (macNode->right != NULL) + { + clonedMacNode->right = ixEthDBCloneMacTreeNode(macNode->right); + } + + if (macNode->left != NULL) + { + clonedMacNode->left = ixEthDBCloneMacTreeNode(macNode->left); + } + + if (macNode->descriptor != NULL) + { + clonedMacNode->descriptor = ixEthDBCloneMacDescriptor(macNode->descriptor); + } + } + + return clonedMacNode; + } + else + { + return NULL; + } +} + +#ifndef NDEBUG +/* Debug statistical functions for memory usage */ + +extern HashTable dbHashtable; +int ixEthDBNumHashElements(void); + +int ixEthDBNumHashElements(void) +{ + UINT32 bucketIndex; + int numElements = 0; + HashTable *hashTable = &dbHashtable; + + for (bucketIndex = 0 ; bucketIndex < hashTable->numBuckets ; bucketIndex++) + { + if (hashTable->hashBuckets[bucketIndex] != NULL) + { + HashNode *node = hashTable->hashBuckets[bucketIndex]; + + while (node != NULL) + { + numElements++; + + node = node->next; + } + } + } + + return numElements; +} + +UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree) +{ + if (tree == NULL) + { + return 0; + } + else + { + return 1 /* this node */ + ixEthDBSearchTreeUsageGet(tree->left) + ixEthDBSearchTreeUsageGet(tree->right); + } +} + +int ixEthDBShowMemoryStatus(void) +{ + MacDescriptor *mac; + MacTreeNode *tree; + HashNode *node; + + int macCounter = 0; + int treeCounter = 0; + int nodeCounter = 0; + + int totalTreeUsage = 0; + int totalDescriptorUsage = 0; + int totalCloneDescriptorUsage = 0; + int totalNodeUsage = 0; + + UINT32 portIndex; + + LOCK_NODE_POOL; + LOCK_MAC_POOL; + LOCK_TREE_POOL; + + mac = macPool; + tree = treePool; + node = nodePool; + + while (mac != NULL) + { + macCounter++; + + mac = mac->nextFree; + + if (macCounter > MAC_POOL_SIZE) + { + break; + } + } + + while (tree != NULL) + { + treeCounter++; + + tree = tree->nextFree; + + if (treeCounter > TREE_POOL_SIZE) + { + break; + } + } + + while (node != NULL) + { + nodeCounter++; + + node = node->nextFree; + + if (nodeCounter > NODE_POOL_SIZE) + { + break; + } + } + + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + int treeUsage = ixEthDBSearchTreeUsageGet(ixEthDBPortInfo[portIndex].updateMethod.searchTree); + + totalTreeUsage += treeUsage; + totalCloneDescriptorUsage += treeUsage; /* each tree node contains a descriptor */ + } + + totalNodeUsage = ixEthDBNumHashElements(); + totalDescriptorUsage += totalNodeUsage; /* each hash table entry contains a descriptor */ + + UNLOCK_NODE_POOL; + UNLOCK_MAC_POOL; + UNLOCK_TREE_POOL; + + printf("Ethernet database memory usage stats:\n\n"); + + if (macCounter <= MAC_POOL_SIZE) + { + printf("\tMAC descriptor pool : %d free out of %d entries (%d%%)\n", macCounter, MAC_POOL_SIZE, macCounter * 100 / MAC_POOL_SIZE); + } + else + { + printf("\tMAC descriptor pool : invalid state (ring within the pool), normally %d entries\n", MAC_POOL_SIZE); + } + + if (treeCounter <= TREE_POOL_SIZE) + { + printf("\tTree node pool : %d free out of %d entries (%d%%)\n", treeCounter, TREE_POOL_SIZE, treeCounter * 100 / TREE_POOL_SIZE); + } + else + { + printf("\tTREE descriptor pool : invalid state (ring within the pool), normally %d entries\n", TREE_POOL_SIZE); + } + + if (nodeCounter <= NODE_POOL_SIZE) + { + printf("\tHash node pool : %d free out of %d entries (%d%%)\n", nodeCounter, NODE_POOL_SIZE, nodeCounter * 100 / NODE_POOL_SIZE); + } + else + { + printf("\tNODE descriptor pool : invalid state (ring within the pool), normally %d entries\n", NODE_POOL_SIZE); + } + + printf("\n"); + printf("\tMAC descriptor usage : %d entries, %d cloned\n", totalDescriptorUsage, totalCloneDescriptorUsage); + printf("\tTree node usage : %d entries\n", totalTreeUsage); + printf("\tHash node usage : %d entries\n", totalNodeUsage); + printf("\n"); + + /* search for duplicate nodes in the mac pool */ + { + MacDescriptor *reference = macPool; + + while (reference != NULL) + { + MacDescriptor *comparison = reference->nextFree; + + while (comparison != NULL) + { + if (reference == comparison) + { + printf("Warning: reached a duplicate (%p), invalid MAC pool state\n", reference); + + return 1; + } + + comparison = comparison->nextFree; + } + + reference = reference->nextFree; + } + } + + printf("No duplicates found in the MAC pool (sanity check ok)\n"); + + return 0; +} + +#endif /* NDEBUG */ + +/** + * @} EthMemoryManagement + */ diff --git a/drivers/net/npe/IxEthDBNPEAdaptor.c b/drivers/net/npe/IxEthDBNPEAdaptor.c new file mode 100644 index 0000000..112a46c --- /dev/null +++ b/drivers/net/npe/IxEthDBNPEAdaptor.c @@ -0,0 +1,719 @@ +/** + * @file IxEthDBDBNPEAdaptor.c + * + * @brief Routines that read and write learning/search trees in NPE-specific format + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxEthDB_p.h" +#include "IxEthDBLog_p.h" + +/* forward prototype declarations */ +IX_ETH_DB_PUBLIC void ixEthDBELTShow(IxEthDBPortId portID); +IX_ETH_DB_PUBLIC void ixEthDBShowNpeMsgHistory(void); + +/* data */ +UINT8* ixEthDBNPEUpdateArea[IX_ETH_DB_NUMBER_OF_PORTS]; +UINT32 dumpEltSize; + +/* private data */ +IX_ETH_DB_PRIVATE IxEthDBNoteWriteFn ixEthDBNPENodeWrite[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1]; + +#define IX_ETH_DB_MAX_DELTA_ZONES (6) /* at most 6 EP Delta zones, according to NPE FS */ +IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDeltaOffset[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES]; +IX_ETH_DB_PRIVATE UINT32 ixEthDBEPDelta[IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1][IX_ETH_DB_MAX_DELTA_ZONES]; + +/** + * @brief allocates non-cached or contiguous NPE tree update areas for all the ports + * + * This function is called only once at initialization time from + * @ref ixEthDBInit(). + * + * @warning do not call manually + * + * @see ixEthDBInit() + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBNPEUpdateAreasInit(void) +{ + UINT32 portIndex; + PortUpdateMethod *update; + + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + update = &ixEthDBPortInfo[portIndex].updateMethod; + + if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) + { + update->npeUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_ELT_BYTE_SIZE); + update->npeGwUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_GW_BYTE_SIZE); + update->vlanUpdateZone = IX_OSAL_CACHE_DMA_MALLOC(FULL_VLAN_BYTE_SIZE); + + if (update->npeUpdateZone == NULL + || update->npeGwUpdateZone == NULL + || update->vlanUpdateZone == NULL) + { + ERROR_LOG("Fatal error: IX_ACC_DRV_DMA_MALLOC() returned NULL, no NPE update zones available\n"); + } + else + { + memset(update->npeUpdateZone, 0, FULL_ELT_BYTE_SIZE); + memset(update->npeGwUpdateZone, 0, FULL_GW_BYTE_SIZE); + memset(update->vlanUpdateZone, 0, FULL_VLAN_BYTE_SIZE); + } + } + else + { + /* unused */ + update->npeUpdateZone = NULL; + update->npeGwUpdateZone = NULL; + update->vlanUpdateZone = NULL; + } + } +} + +/** + * @brief deallocates the NPE update areas for all the ports + * + * This function is called at component de-initialization time + * by @ref ixEthDBUnload(). + * + * @warning do not call manually + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBNPEUpdateAreasUnload(void) +{ + UINT32 portIndex; + + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + if (ixEthDBPortDefinitions[portIndex].type == IX_ETH_NPE) + { + IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeUpdateZone); + IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.npeGwUpdateZone); + IX_OSAL_CACHE_DMA_FREE(ixEthDBPortInfo[portIndex].updateMethod.vlanUpdateZone); + } + } +} + +/** + * @brief general-purpose NPE callback function + * + * @param npeID NPE ID + * @param msg NPE message + * + * This function will unblock the caller by unlocking + * the npeAckLock mutex defined for each NPE port + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg) +{ + IxEthDBPortId portID = IX_ETH_DB_NPE_TO_PORT_ID(npeID); + PortInfo *portInfo; + + if (portID >= IX_ETH_DB_NUMBER_OF_PORTS) + { + /* invalid port */ + return; + } + + if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE) + { + /* not an NPE */ + return; + } + + portInfo = &ixEthDBPortInfo[portID]; + + ixOsalMutexUnlock(&portInfo->npeAckLock); +} + +/** + * @brief synchronizes the database with tree + * + * @param portID port ID of the NPE whose tree is to be scanned + * @param eltBaseAddress memory base address of the NPE serialized tree + * @param eltSize size in bytes of the NPE serialized tree + * + * Scans the NPE learning tree and resets the age of active database records. + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize) +{ + UINT32 eltEntryOffset; + UINT32 entryPortID; + + /* invalidate cache */ + IX_OSAL_CACHE_INVALIDATE(eltBaseAddress, eltSize); + + for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE) + { + /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node + * + * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit] + * therefore we can just use the pointer for database searches as only the first 6 bytes are checked + */ + void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset); + + /* debug */ + IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) checking node at offset %d...\n", eltEntryOffset / ELT_ENTRY_SIZE); + + if (IX_EDB_NPE_NODE_VALID(eltNodeAddress) != TRUE) + { + IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is empty\n"); + } + else if (eltEntryOffset == ELT_ROOT_OFFSET) + { + IX_ETH_DB_NPE_VERBOSE_TRACE("\t... node is root\n"); + } + + if (IX_EDB_NPE_NODE_VALID(eltNodeAddress)) + { + entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress)); + + /* check only active entries belonging to this port */ + if (ixEthDBPortInfo[portID].agingEnabled && IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) && (portID == entryPortID) + && ((ixEthDBPortDefinitions[portID].capabilities & IX_ETH_ENTRY_AGING) == 0)) + { + /* search record */ + HashNode *node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_FILTERING_RECORDS); + + /* safety check, maybe user deleted record right before sync? */ + if (node != NULL) + { + /* found record */ + MacDescriptor *descriptor = (MacDescriptor *) node->data; + + IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) synced entry [%s] already in the database, updating fields\n", mac2string(eltNodeAddress)); + + /* reset age - set to -1 so that maintenance will restore it to 0 (or more) when incrementing */ + if (!descriptor->recordData.filteringData.staticEntry) + { + if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) + { + descriptor->recordData.filteringData.age = AGE_RESET; + } + else if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) + { + descriptor->recordData.filteringVlanData.age = AGE_RESET; + } + } + + /* end transaction */ + ixEthDBReleaseHashNode(node); + } + } + else + { + IX_ETH_DB_NPE_VERBOSE_TRACE("\t... found portID %d, we check only port %d\n", entryPortID, portID); + } + } + } +} + +/** + * @brief writes a search tree in NPE format + * + * @param type type of records to be written into the NPE update zone + * @param totalSize maximum size of the linearized tree + * @param baseAddress memory base address where to write the NPE tree into + * @param tree search tree to write in NPE format + * @param blocks number of written 64-byte blocks + * @param startIndex optimal binary search start index + * + * Serializes the given tree in NPE linear format + * + * @return none + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *epDelta, UINT32 *blocks) +{ + MacTreeNodeStack *stack; + UINT32 maxOffset = 0; + UINT32 emptyOffset; + + stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack)); + + if (stack == NULL) + { + ERROR_LOG("DB: (NPEAdaptor) failed to allocate the node stack for learning tree linearization, out of memory?\n"); + return; + } + + /* zero out empty root */ + memset(baseAddress, 0, ELT_ENTRY_SIZE); + + NODE_STACK_INIT(stack); + + if (tree != NULL) + { + /* push tree root at offset 1 */ + NODE_STACK_PUSH(stack, tree, 1); + + maxOffset = 1; + } + + while (NODE_STACK_NONEMPTY(stack)) + { + MacTreeNode *node; + UINT32 offset; + + NODE_STACK_POP(stack, node, offset); + + /* update maximum offset */ + if (offset > maxOffset) + { + maxOffset = offset; + } + + IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing MAC [%s] at offset %d\n", mac2string(node->descriptor->macAddress), offset); + + /* add node to NPE ELT at position indicated by offset */ + if (offset < MAX_ELT_SIZE) + { + ixEthDBNPENodeWrite[type]((void *) (((UINT32) baseAddress) + offset * ELT_ENTRY_SIZE), node); + } + + if (node->left != NULL) + { + NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset)); + } + else + { + /* ensure this entry is zeroed */ + memset((void *) ((UINT32) baseAddress + LEFT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE); + } + + if (node->right != NULL) + { + NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset)); + } + else + { + /* ensure this entry is zeroed */ + memset((void *) ((UINT32) baseAddress + RIGHT_CHILD_OFFSET(offset) * ELT_ENTRY_SIZE), 0, ELT_ENTRY_SIZE); + } + } + + emptyOffset = maxOffset + 1; + + /* zero out rest of the tree */ + IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Emptying tree from offset %d, address 0x%08X, %d bytes\n", + emptyOffset, ((UINT32) baseAddress) + emptyOffset * ELT_ENTRY_SIZE, totalSize - (emptyOffset * ELT_ENTRY_SIZE)); + + if (emptyOffset < MAX_ELT_SIZE - 1) + { + memset((void *) (((UINT32) baseAddress) + (emptyOffset * ELT_ENTRY_SIZE)), 0, totalSize - (emptyOffset * ELT_ENTRY_SIZE)); + } + + /* flush cache */ + IX_OSAL_CACHE_FLUSH(baseAddress, totalSize); + + /* debug */ + IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Ethernet learning/filtering tree XScale wrote at address 0x%08X (max %d bytes):\n\n", + (UINT32) baseAddress, FULL_ELT_BYTE_SIZE); + + IX_ETH_DB_NPE_DUMP_ELT(baseAddress, FULL_ELT_BYTE_SIZE); + + /* compute number of 64-byte blocks */ + if (blocks != NULL) + { + *blocks = maxOffset != 0 ? 1 + maxOffset / 8 : 0; + + IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Wrote %d 64-byte blocks\n", *blocks); + } + + /* compute epDelta - start index for binary search */ + if (epDelta != NULL) + { + UINT32 deltaIndex = 0; + + *epDelta = 0; + + for (; deltaIndex < IX_ETH_DB_MAX_DELTA_ZONES ; deltaIndex ++) + { + if (ixEthDBEPDeltaOffset[type][deltaIndex] >= maxOffset) + { + *epDelta = ixEthDBEPDelta[type][deltaIndex]; + break; + } + } + + IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Computed epDelta %d (based on maxOffset %d)\n", *epDelta, maxOffset); + } + + ixOsalCacheDmaFree(stack); +} + +/** + * @brief implements a dummy node serialization function + * + * @param address address of where the node is to be serialized (unused) + * @param node tree node to be serialized (unused) + * + * This function is registered for safety reasons and should + * never be called. It will display an error message if this + * function is called. + * + * @return none + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBNullSerialize(void *address, MacTreeNode *node) +{ + IX_ETH_DB_NPE_TRACE("DB: (NPEAdaptor) Warning, the NullSerialize function was called, wrong record type?\n"); +} + +/** + * @brief writes a filtering entry in NPE linear format + * + * @param address memory address to write node to + * @param node node to be written + * + * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree + * in NPE-readable format. + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBNPELearningNodeWrite(void *address, MacTreeNode *node) +{ + /* copy mac address */ + memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE); + + /* copy port ID */ + NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET) = IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(node->descriptor->portID); + + /* copy flags (valid and not active, as the NPE sets it to active) and clear reserved section (bits 2-7) */ + NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) = (UINT8) IX_EDB_FLAGS_INACTIVE_VALID; + + IX_ETH_DB_NPE_VERBOSE_TRACE("DB: (NPEAdaptor) writing ELT node 0x%08x:0x%08x\n", * (UINT32 *) address, * (((UINT32 *) (address)) + 1)); +} + +/** + * @brief writes a WiFi header conversion record in + * NPE linear format + * + * @param address memory address to write node to + * @param node node to be written + * + * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree + * in NPE-readable format. + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBNPEWiFiNodeWrite(void *address, MacTreeNode *node) +{ + /* copy mac address */ + memcpy(address, node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE); + + /* copy index */ + NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET) = node->descriptor->recordData.wifiData.gwAddressIndex; + + /* copy flags (type and valid) */ + NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET) = node->descriptor->recordData.wifiData.type << 1 | IX_EDB_FLAGS_VALID; +} + +/** + * @brief writes a WiFi gateway header conversion record in + * NPE linear format + * + * @param address memory address to write node to + * @param node node to be written + * + * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree + * in NPE-readable format. + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node) +{ + /* copy mac address */ + memcpy(address, node->descriptor->recordData.wifiData.gwMacAddress, IX_IEEE803_MAC_ADDRESS_SIZE); + + /* set reserved field, two bytes */ + NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0; + NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET + 1) = 0; +} + +/** + * @brief writes a firewall record in + * NPE linear format + * + * @param address memory address to write node to + * @param node node to be written + * + * Used by @ref ixEthDBNPETreeWrite to liniarize a search tree + * in NPE-readable format. + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBNPEFirewallNodeWrite(void *address, MacTreeNode *node) +{ + /* set reserved field */ + NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_RESERVED_OFFSET) = 0; + + /* set flags */ + NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_FW_FLAGS_OFFSET) = IX_EDB_FLAGS_VALID; + + /* copy mac address */ + memcpy((void *) ((UINT32) address + IX_EDB_NPE_NODE_FW_ADDR_OFFSET), node->descriptor->macAddress, IX_IEEE803_MAC_ADDRESS_SIZE); +} + +/** + * @brief registers the NPE serialization methods + * + * This functions registers NPE serialization methods + * for writing the following types of records in NPE + * readable linear format: + * - filtering records + * - WiFi header conversion records + * - WiFi gateway header conversion records + * - firewall records + * + * Note that this function should be called by the + * component initialization function. + * + * @return number of registered record types + * + * @internal + */ +IX_ETH_DB_PUBLIC +UINT32 ixEthDBRecordSerializeMethodsRegister() +{ + int i; + + /* safety - register a blank method for everybody first */ + for ( i = 0 ; i < IX_ETH_DB_MAX_RECORD_TYPE_INDEX + 1 ; i++) + { + ixEthDBNPENodeWrite[i] = ixEthDBNullSerialize; + } + + /* register real methods */ + ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_RECORD] = ixEthDBNPELearningNodeWrite; + ixEthDBNPENodeWrite[IX_ETH_DB_FILTERING_VLAN_RECORD] = ixEthDBNPELearningNodeWrite; + ixEthDBNPENodeWrite[IX_ETH_DB_WIFI_RECORD] = ixEthDBNPEWiFiNodeWrite; + ixEthDBNPENodeWrite[IX_ETH_DB_FIREWALL_RECORD] = ixEthDBNPEFirewallNodeWrite; + ixEthDBNPENodeWrite[IX_ETH_DB_GATEWAY_RECORD] = ixEthDBNPEGatewayNodeWrite; + + /* EP Delta arrays */ + memset(ixEthDBEPDeltaOffset, 0, sizeof (ixEthDBEPDeltaOffset)); + memset(ixEthDBEPDelta, 0, sizeof (ixEthDBEPDelta)); + + /* filtering records */ + ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][0] = 1; + ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][0] = 0; + + ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][1] = 3; + ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][1] = 7; + + ixEthDBEPDeltaOffset[IX_ETH_DB_FILTERING_RECORD][2] = 511; + ixEthDBEPDelta[IX_ETH_DB_FILTERING_RECORD][2] = 14; + + /* wifi records */ + ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][0] = 1; + ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][0] = 0; + + ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][1] = 3; + ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][1] = 7; + + ixEthDBEPDeltaOffset[IX_ETH_DB_WIFI_RECORD][2] = 511; + ixEthDBEPDelta[IX_ETH_DB_WIFI_RECORD][2] = 14; + + /* firewall records */ + ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][0] = 0; + ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][0] = 0; + + ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][1] = 1; + ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][1] = 5; + + ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][2] = 3; + ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][2] = 13; + + ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][3] = 7; + ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][3] = 21; + + ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][4] = 15; + ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][4] = 29; + + ixEthDBEPDeltaOffset[IX_ETH_DB_FIREWALL_RECORD][5] = 31; + ixEthDBEPDelta[IX_ETH_DB_FIREWALL_RECORD][5] = 37; + + return 5; /* 5 methods registered */ +} + +#ifndef IX_NDEBUG + +IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2]; +IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen = 0; + +/** + * When compiled in DEBUG mode, this function can be used to display + * the history of messages sent to the NPEs (up to 100). + */ +IX_ETH_DB_PUBLIC +void ixEthDBShowNpeMsgHistory() +{ + UINT32 i = 0; + UINT32 base, len; + + if (npeMsgHistoryLen <= IX_ETH_DB_NPE_MSG_HISTORY_DEPTH) + { + base = 0; + len = npeMsgHistoryLen; + } + else + { + base = npeMsgHistoryLen % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; + len = IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; + } + + printf("NPE message history [last %d messages, from least to most recent]:\n", len); + + for (; i < len ; i++) + { + UINT32 pos = (base + i) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; + printf("msg[%d]: 0x%08x:0x%08x\n", i, npeMsgHistory[pos][0], npeMsgHistory[pos][1]); + } +} + +IX_ETH_DB_PUBLIC +void ixEthDBELTShow(IxEthDBPortId portID) +{ + IxNpeMhMessage message; + IX_STATUS result; + + /* send EDB_GetMACAddressDatabase message */ + FILL_GETMACADDRESSDATABASE(message, + 0 /* reserved */, + IX_OSAL_MMU_VIRT_TO_PHYS(ixEthDBPortInfo[portID].updateMethod.npeUpdateZone)); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + if (result == IX_SUCCESS) + { + /* analyze NPE copy */ + UINT32 eltEntryOffset; + UINT32 entryPortID; + + UINT32 eltBaseAddress = (UINT32) ixEthDBPortInfo[portID].updateMethod.npeUpdateZone; + UINT32 eltSize = FULL_ELT_BYTE_SIZE; + + /* invalidate cache */ + IX_OSAL_CACHE_INVALIDATE((void *) eltBaseAddress, eltSize); + + printf("Listing records in main learning tree for port %d\n", portID); + + for (eltEntryOffset = ELT_ROOT_OFFSET ; eltEntryOffset < eltSize ; eltEntryOffset += ELT_ENTRY_SIZE) + { + /* (eltBaseAddress + eltEntryOffset) points to a valid NPE tree node + * + * the format of the node is MAC[6 bytes]:PortID[1 byte]:Reserved[6 bits]:Active[1 bit]:Valid[1 bit] + * therefore we can just use the pointer for database searches as only the first 6 bytes are checked + */ + void *eltNodeAddress = (void *) ((UINT32) eltBaseAddress + eltEntryOffset); + + if (IX_EDB_NPE_NODE_VALID(eltNodeAddress)) + { + HashNode *node; + + entryPortID = IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(IX_EDB_NPE_NODE_PORT_ID(eltNodeAddress)); + + /* search record */ + node = ixEthDBSearch((IxEthDBMacAddr *) eltNodeAddress, IX_ETH_DB_ALL_RECORD_TYPES); + + printf("%s - port %d - %s ", mac2string((unsigned char *) eltNodeAddress), entryPortID, + IX_EDB_NPE_NODE_ACTIVE(eltNodeAddress) ? "active" : "inactive"); + + /* safety check, maybe user deleted record right before sync? */ + if (node != NULL) + { + /* found record */ + MacDescriptor *descriptor = (MacDescriptor *) node->data; + + printf("- %s ", + descriptor->type == IX_ETH_DB_FILTERING_RECORD ? "filtering" : + descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD ? "vlan" : + descriptor->type == IX_ETH_DB_WIFI_RECORD ? "wifi" : "other (check main DB)"); + + if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) printf("- age %d - %s ", + descriptor->recordData.filteringData.age, + descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic"); + + if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) printf("- age %d - %s - tci %d ", + descriptor->recordData.filteringVlanData.age, + descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic", + descriptor->recordData.filteringVlanData.ieee802_1qTag); + + /* end transaction */ + ixEthDBReleaseHashNode(node); + } + else + { + printf("- not synced"); + } + + printf("\n"); + } + } + } + else + { + ixOsalLog(IX_OSAL_LOG_LVL_FATAL, IX_OSAL_LOG_DEV_STDOUT, + "EthDB: (ShowELT) Could not complete action (communication failure)\n", + portID, 0, 0, 0, 0, 0); + } +} + +#endif diff --git a/drivers/net/npe/IxEthDBPortUpdate.c b/drivers/net/npe/IxEthDBPortUpdate.c new file mode 100644 index 0000000..cdf114b --- /dev/null +++ b/drivers/net/npe/IxEthDBPortUpdate.c @@ -0,0 +1,740 @@ +/** + * @file IxEthDBDBPortUpdate.c + * + * @brief Implementation of dependency and port update handling + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxEthDB_p.h" + +/* forward prototype declarations */ +IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor); +IX_ETH_DB_PRIVATE void ixEthDBCreateTrees(IxEthDBPortMap updatePorts); +IX_ETH_DB_PRIVATE MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree); +IX_ETH_DB_PRIVATE void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size); +IX_ETH_DB_PRIVATE void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size); +IX_ETH_DB_PRIVATE void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count); +IX_ETH_DB_PRIVATE UINT32 ixEthDBRebalanceLog2Floor(UINT32 x); + +extern HashTable dbHashtable; + +/** + * @brief register types requiring automatic updates + * + * @param typeArray array indexed on record types, each + * element indicating whether the record type requires an + * automatic update (TRUE) or not (FALSE) + * + * Automatic updates are done for registered record types + * upon adding, updating (that is, updating the record portID) + * and removing records. Whenever an automatic update is triggered + * the appropriate ports will be provided with new database + * information. + * + * It is assumed that the typeArray parameter is allocated large + * enough to hold all the user defined types. Also, the type + * array should be initialized to FALSE as this function only + * caters for types which do require automatic updates. + * + * Note that this function should be called by the component + * initialization function. + * + * @return number of record types registered for automatic + * updates + * + * @internal + */ +IX_ETH_DB_PUBLIC +UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray) +{ + typeArray[IX_ETH_DB_FILTERING_RECORD] = TRUE; + typeArray[IX_ETH_DB_FILTERING_VLAN_RECORD] = TRUE; + + return 2; +} + +/** + * @brief computes dependencies and triggers port learning tree updates + * + * @param triggerPorts port map consisting in the ports which triggered the update + * + * This function browses through all the ports and determines how to waterfall the update + * event from the trigger ports to all other ports depending on them. + * + * Once the list of ports to be updated is determined this function + * calls @ref ixEthDBCreateTrees. + * + * @internal + */ +IX_ETH_DB_PUBLIC +void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts) +{ + IxEthDBPortMap updatePorts; + UINT32 portIndex; + + ixEthDBUpdateLock(); + + SET_EMPTY_DEPENDENCY_MAP(updatePorts); + + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + PortInfo *port = &ixEthDBPortInfo[portIndex]; + BOOL mapsCollide; + + MAPS_COLLIDE(mapsCollide, triggerPorts, port->dependencyPortMap); + + if (mapsCollide /* do triggers influence this port? */ + && !IS_PORT_INCLUDED(portIndex, updatePorts) /* and it's not already in the update list */ + && port->updateMethod.updateEnabled) /* and we're allowed to update it */ + { + IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding port %d to update set\n", portIndex); + + JOIN_PORT_TO_MAP(updatePorts, portIndex); + } + else + { + IX_ETH_DB_UPDATE_TRACE("DB: (Update) Didn't add port %d to update set, reasons follow:\n", portIndex); + + if (!mapsCollide) + { + IX_ETH_DB_UPDATE_TRACE("\tMaps don't collide on port %d\n", portIndex); + } + + if (IS_PORT_INCLUDED(portIndex, updatePorts)) + { + IX_ETH_DB_UPDATE_TRACE("\tPort %d is already in the update set\n", portIndex); + } + + if (!port->updateMethod.updateEnabled) + { + IX_ETH_DB_UPDATE_TRACE("\tPort %d doesn't have updateEnabled set\n", portIndex); + } + } + } + + IX_ETH_DB_UPDATE_TRACE("DB: (Update) Updating port set\n"); + + ixEthDBCreateTrees(updatePorts); + + ixEthDBUpdateUnlock(); +} + +/** + * @brief creates learning trees and calls the port update handlers + * + * @param updatePorts set of ports in need of learning trees + * + * This function determines the optimal method of creating learning + * trees using a minimal number of database queries, keeping in mind + * that different ports can either use the same learning trees or they + * can partially share them. The actual tree building routine is + * @ref ixEthDBQuery. + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBCreateTrees(IxEthDBPortMap updatePorts) +{ + UINT32 portIndex; + BOOL result; + BOOL portsLeft = TRUE; + + while (portsLeft) + { + /* get port with minimal dependency map and NULL search tree */ + UINT32 minPortIndex = MAX_PORT_SIZE; + UINT32 minimalSize = MAX_PORT_SIZE; + + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + UINT32 size; + PortInfo *port = &ixEthDBPortInfo[portIndex]; + + /* generate trees only for ports that need them */ + if (!port->updateMethod.searchTreePendingWrite && IS_PORT_INCLUDED(portIndex, updatePorts)) + { + GET_MAP_SIZE(port->dependencyPortMap, size); + + IX_ETH_DB_UPDATE_TRACE("DB: (Update) Dependency map for port %d: size %d\n", + portIndex, size); + + if (size < minimalSize) + { + minPortIndex = portIndex; + minimalSize = size; + } + } + else + { + IX_ETH_DB_UPDATE_TRACE("DB: (Update) Skipped port %d from tree diff (%s)\n", portIndex, + port->updateMethod.searchTreePendingWrite ? "pending write access" : "ignored by query"); + } + } + + /* if a port was found than minimalSize is not MAX_PORT_SIZE */ + if (minimalSize != MAX_PORT_SIZE) + { + /* minPortIndex is the port we seek */ + PortInfo *port = &ixEthDBPortInfo[minPortIndex]; + + IxEthDBPortMap query; + MacTreeNode *baseTree; + + /* now try to find a port with minimal map difference */ + PortInfo *minimalDiffPort = NULL; + UINT32 minimalDiff = MAX_PORT_SIZE; + + IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal size port is %d\n", minPortIndex); + + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + PortInfo *diffPort = &ixEthDBPortInfo[portIndex]; + BOOL mapIsSubset; + + IS_MAP_SUBSET(mapIsSubset, diffPort->dependencyPortMap, port->dependencyPortMap); + + + if (portIndex != minPortIndex + && diffPort->updateMethod.searchTree != NULL + && mapIsSubset) + { + /* compute size and pick only minimal size difference */ + UINT32 diffPortSize; + UINT32 sizeDifference; + + GET_MAP_SIZE(diffPort->dependencyPortMap, diffPortSize); + + IX_ETH_DB_UPDATE_TRACE("DB: (Update) Checking port %d for differences...\n", portIndex); + + sizeDifference = minimalSize - diffPortSize; + + if (sizeDifference < minimalDiff) + { + minimalDiffPort = diffPort; + minimalDiff = sizeDifference; + + IX_ETH_DB_UPDATE_TRACE("DB: (Update) Minimal difference 0x%x was found on port %d\n", + minimalDiff, portIndex); + } + } + } + + /* check if filtering is enabled on this port */ + if ((port->featureStatus & IX_ETH_DB_FILTERING) != 0) + { + /* if minimalDiff is not MAX_PORT_SIZE minimalDiffPort points to the most similar port */ + if (minimalDiff != MAX_PORT_SIZE) + { + baseTree = ixEthDBCloneMacTreeNode(minimalDiffPort->updateMethod.searchTree); + DIFF_MAPS(query, port->dependencyPortMap , minimalDiffPort->dependencyPortMap); + + IX_ETH_DB_UPDATE_TRACE("DB: (Update) Found minimal diff, extending tree %d on query\n", + minimalDiffPort->portID); + } + else /* .. otherwise no similar port was found, build tree from scratch */ + { + baseTree = NULL; + + COPY_DEPENDENCY_MAP(query, port->dependencyPortMap); + + IX_ETH_DB_UPDATE_TRACE("DB: (Update) No similar diff, creating tree from query\n"); + } + + IS_EMPTY_DEPENDENCY_MAP(result, query); + + if (!result) /* otherwise we don't need anything more on top of the cloned tree */ + { + IX_ETH_DB_UPDATE_TRACE("DB: (Update) Adding query tree to port %d\n", minPortIndex); + + /* build learning tree */ + port->updateMethod.searchTree = ixEthDBQuery(baseTree, query, IX_ETH_DB_ALL_FILTERING_RECORDS, MAX_ELT_SIZE); + } + else + { + IX_ETH_DB_UPDATE_TRACE("DB: (Update) Query is empty, assuming identical nearest tree\n"); + + port->updateMethod.searchTree = baseTree; + } + } + else + { + /* filtering is not enabled, will download an empty tree */ + if (port->updateMethod.searchTree != NULL) + { + ixEthDBFreeMacTreeNode(port->updateMethod.searchTree); + } + + port->updateMethod.searchTree = NULL; + } + + /* mark tree as valid */ + port->updateMethod.searchTreePendingWrite = TRUE; + } + else + { + portsLeft = FALSE; + + IX_ETH_DB_UPDATE_TRACE("DB: (Update) No trees to create this round\n"); + } + } + + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + PortInfo *updatePort = &ixEthDBPortInfo[portIndex]; + + if (updatePort->updateMethod.searchTreePendingWrite) + { + IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Starting procedure to upload new search tree (%snull) into NPE %d\n", + updatePort->updateMethod.searchTree != NULL ? "not " : "", + portIndex); + + updatePort->updateMethod.updateHandler(portIndex, IX_ETH_DB_FILTERING_RECORD); + } + } +} + +/** + * @brief standard NPE update handler + * + * @param portID id of the port to be updated + * @param type record type to be pushed during this update + * + * The NPE update handler manages updating the NPE databases + * given a certain record type. + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type) +{ + UINT32 epDelta, blockCount; + IxNpeMhMessage message; + UINT32 treeSize = 0; + PortInfo *port = &ixEthDBPortInfo[portID]; + + /* size selection and type check */ + if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD) + { + treeSize = FULL_ELT_BYTE_SIZE; + } + else if (type == IX_ETH_DB_FIREWALL_RECORD) + { + treeSize = FULL_FW_BYTE_SIZE; + } + else + { + return IX_ETH_DB_INVALID_ARG; + } + + /* serialize tree into memory */ + ixEthDBNPETreeWrite(type, treeSize, port->updateMethod.npeUpdateZone, port->updateMethod.searchTree, &epDelta, &blockCount); + + /* free internal copy */ + if (port->updateMethod.searchTree != NULL) + { + ixEthDBFreeMacTreeNode(port->updateMethod.searchTree); + } + + /* forget last used search tree */ + port->updateMethod.searchTree = NULL; + port->updateMethod.searchTreePendingWrite = FALSE; + + /* dependending on the update type we do different things */ + if (type == IX_ETH_DB_FILTERING_RECORD || type == IX_ETH_DB_WIFI_RECORD) + { + IX_STATUS result; + + FILL_SETMACADDRESSDATABASE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), + epDelta, blockCount, + IX_OSAL_MMU_VIRT_TO_PHYS(port->updateMethod.npeUpdateZone)); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + if (result == IX_SUCCESS) + { + IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) Finished downloading NPE tree on port %d\n", portID); + } + else + { + ixEthDBPortInfo[portID].agingEnabled = FALSE; + ixEthDBPortInfo[portID].updateMethod.updateEnabled = FALSE; + ixEthDBPortInfo[portID].updateMethod.userControlled = TRUE; + + ERROR_LOG("EthDB: (PortUpdate) disabling aging and updates on port %d (assumed dead)\n", portID); + + ixEthDBDatabaseClear(portID, IX_ETH_DB_ALL_RECORD_TYPES); + + return IX_ETH_DB_FAIL; + } + + return IX_ETH_DB_SUCCESS; + } + else if (type == IX_ETH_DB_FIREWALL_RECORD) + { + return ixEthDBFirewallUpdate(portID, port->updateMethod.npeUpdateZone, epDelta); + } + + return IX_ETH_DB_INVALID_ARG; +} + +/** + * @brief queries the database for a set of records to be inserted into a given tree + * + * @param searchTree pointer to a tree where insertions will be performed; can be NULL + * @param query set of ports that a database record must match to be inserted into the tree + * + * The query method browses through the database, extracts all the descriptors matching + * the given query parameter and inserts them into the given learning tree. + * Note that this is an append procedure, the given tree needs not to be empty. + * A "descriptor matching the query" is a descriptor whose port id is in the query map. + * If the given tree is empty (NULL) a new tree is created and returned. + * + * @return the tree root + * + * @internal + */ +IX_ETH_DB_PUBLIC +MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maxEntries) +{ + HashIterator iterator; + UINT32 entryCount = 0; + + /* browse database */ + BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); + + while (IS_ITERATOR_VALID(&iterator)) + { + MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; + + IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) querying [%s]:%d on port map ... ", + mac2string(descriptor->macAddress), + descriptor->portID); + + if ((descriptor->type & recordFilter) != 0 + && IS_PORT_INCLUDED(descriptor->portID, query)) + { + MacDescriptor *descriptorClone = ixEthDBCloneMacDescriptor(descriptor); + + IX_ETH_DB_UPDATE_TRACE("match\n"); + + if (descriptorClone != NULL) + { + /* add descriptor to tree */ + searchTree = ixEthDBTreeInsert(searchTree, descriptorClone); + + entryCount++; + } + } + else + { + IX_ETH_DB_UPDATE_TRACE("no match\n"); + } + + if (entryCount < maxEntries) + { + /* advance to the next record */ + BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator)); + } + else + { + /* the NPE won't accept more entries so we can stop now */ + ixEthDBReleaseHashIterator(&iterator); + + IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) number of elements reached maximum supported by port\n"); + + break; + } + } + + IX_ETH_DB_UPDATE_TRACE("DB: (PortUpdate) query inserted %d records in the search tree\n", entryCount); + + return ixEthDBTreeRebalance(searchTree); +} + +/** + * @brief inserts a mac descriptor into an tree + * + * @param searchTree tree where the insertion is to be performed (may be NULL) + * @param descriptor descriptor to insert into tree + * + * @return the tree root + * + * @internal + */ +IX_ETH_DB_PRIVATE +MacTreeNode* ixEthDBTreeInsert(MacTreeNode *searchTree, MacDescriptor *descriptor) +{ + MacTreeNode *currentNode = searchTree; + MacTreeNode *insertLocation = NULL; + MacTreeNode *newNode; + INT32 insertPosition = RIGHT; + + if (descriptor == NULL) + { + return searchTree; + } + + /* create a new node */ + newNode = ixEthDBAllocMacTreeNode(); + + if (newNode == NULL) + { + /* out of memory */ + ERROR_LOG("Warning: ixEthDBAllocMacTreeNode returned NULL in file %s:%d (out of memory?)\n", __FILE__, __LINE__); + + ixEthDBFreeMacDescriptor(descriptor); + + return NULL; + } + + /* populate node */ + newNode->descriptor = descriptor; + + /* an empty initial tree is a special case */ + if (searchTree == NULL) + { + return newNode; + } + + /* get insertion location */ + while (insertLocation == NULL) + { + MacTreeNode *nextNode; + + /* compare given key with current node key */ + insertPosition = ixEthDBAddressCompare(descriptor->macAddress, currentNode->descriptor->macAddress); + + /* navigate down */ + if (insertPosition == RIGHT) + { + nextNode = currentNode->right; + } + else if (insertPosition == LEFT) + { + nextNode = currentNode->left; + } + else + { + /* error, duplicate key */ + ERROR_LOG("Warning: trapped insertion of a duplicate MAC address in an NPE search tree\n"); + + /* this will free the MAC descriptor as well */ + ixEthDBFreeMacTreeNode(newNode); + + return searchTree; + } + + /* when we can no longer dive through the tree we found the insertion place */ + if (nextNode != NULL) + { + currentNode = nextNode; + } + else + { + insertLocation = currentNode; + } + } + + /* insert node */ + if (insertPosition == RIGHT) + { + insertLocation->right = newNode; + } + else + { + insertLocation->left = newNode; + } + + return searchTree; +} + +/** + * @brief balance a tree + * + * @param searchTree tree to balance + * + * Converts a tree into a balanced tree and returns the root of + * the balanced tree. The resulting tree is route balanced + * not perfectly balanced. This makes no difference to the + * average tree search time which is the same in both cases, O(log2(n)). + * + * @return root of the balanced tree or NULL if there's no memory left + * + * @internal + */ +IX_ETH_DB_PRIVATE +MacTreeNode* ixEthDBTreeRebalance(MacTreeNode *searchTree) +{ + MacTreeNode *pseudoRoot = ixEthDBAllocMacTreeNode(); + UINT32 size; + + if (pseudoRoot == NULL) + { + /* out of memory */ + return NULL; + } + + pseudoRoot->right = searchTree; + + ixEthDBRebalanceTreeToVine(pseudoRoot, &size); + ixEthDBRebalanceVineToTree(pseudoRoot, size); + + searchTree = pseudoRoot->right; + + /* remove pseudoRoot right branch, otherwise it will free the entire tree */ + pseudoRoot->right = NULL; + + ixEthDBFreeMacTreeNode(pseudoRoot); + + return searchTree; +} + +/** + * @brief converts a tree into a vine + * + * @param root root of tree to convert + * @param size depth of vine (equal to the number of nodes in the tree) + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBRebalanceTreeToVine(MacTreeNode *root, UINT32 *size) +{ + MacTreeNode *vineTail = root; + MacTreeNode *remainder = vineTail->right; + MacTreeNode *tempPtr; + + *size = 0; + + while (remainder != NULL) + { + if (remainder->left == NULL) + { + /* move tail down one */ + vineTail = remainder; + remainder = remainder->right; + (*size)++; + } + else + { + /* rotate around remainder */ + tempPtr = remainder->left; + remainder->left = tempPtr->right; + tempPtr->right = remainder; + remainder = tempPtr; + vineTail->right = tempPtr; + } + } +} + +/** + * @brief converts a vine into a balanced tree + * + * @param root vine to convert + * @param size depth of vine + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBRebalanceVineToTree(MacTreeNode *root, UINT32 size) +{ + UINT32 leafCount = size + 1 - (1 << ixEthDBRebalanceLog2Floor(size + 1)); + + ixEthDBRebalanceCompression(root, leafCount); + + size = size - leafCount; + + while (size > 1) + { + ixEthDBRebalanceCompression(root, size / 2); + + size /= 2; + } +} + +/** + * @brief compresses a vine/tree stage into a more balanced vine/tree + * + * @param root root of the tree to compress + * @param count number of "spine" nodes + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBRebalanceCompression(MacTreeNode *root, UINT32 count) +{ + MacTreeNode *scanner = root; + MacTreeNode *child; + UINT32 local_index; + + for (local_index = 0 ; local_index < count ; local_index++) + { + child = scanner->right; + scanner->right = child->right; + scanner = scanner->right; + child->right = scanner->left; + scanner->left = child; + } +} + +/** + * @brief computes |_log2(x)_| (a.k.a. floor(log2(x))) + * + * @param x number to compute |_log2(x)_| for + * + * @return |_log2(x)_| + * + * @internal + */ +IX_ETH_DB_PRIVATE +UINT32 ixEthDBRebalanceLog2Floor(UINT32 x) +{ + UINT32 log = 0; + UINT32 val = 1; + + while (val < x) + { + log++; + val <<= 1; + } + + return val == x ? log : log - 1; +} + diff --git a/drivers/net/npe/IxEthDBReports.c b/drivers/net/npe/IxEthDBReports.c new file mode 100644 index 0000000..9c7ae1c --- /dev/null +++ b/drivers/net/npe/IxEthDBReports.c @@ -0,0 +1,652 @@ +/** + * @file IxEthDBAPI.c + * + * @brief Implementation of the public API + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxEthDB_p.h" + +extern HashTable dbHashtable; +IX_ETH_DB_PRIVATE void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter); +IX_ETH_DB_PRIVATE IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map); + +/** + * @brief displays a port dependency map + * + * @param portID ID of the port + * @param map port map to display + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBDependencyPortMapShow(IxEthDBPortId portID, IxEthDBPortMap map) +{ + UINT32 portIndex; + BOOL mapSelf = TRUE, mapNone = TRUE, firstPort = TRUE; + + /* dependency port maps */ + printf("Dependency port map: "); + + /* browse the port map */ + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + if (IS_PORT_INCLUDED(portIndex, map)) + { + mapNone = FALSE; + + if (portIndex != portID) + { + mapSelf = FALSE; + } + + printf("%s%d", firstPort ? "{" : ", ", portIndex); + + firstPort = FALSE; + } + } + + if (mapNone) + { + mapSelf = FALSE; + } + + printf("%s (%s)\n", firstPort ? "" : "}", mapSelf ? "self" : mapNone ? "none" : "group"); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief displays all the filtering records belonging to a port + * + * @param portID ID of the port to display + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords() + * instead. Calling this function is equivalent to calling + * ixEthDBFilteringDatabaseShowRecords(portID, IX_ETH_DB_FILTERING_RECORD) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID) +{ + IxEthDBStatus local_result; + HashIterator iterator; + PortInfo *portInfo; + UINT32 recordCount = 0; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + portInfo = &ixEthDBPortInfo[portID]; + + /* display table header */ + printf("Ethernet database records for port ID [%d]\n", portID); + + ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap); + + if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) + { + printf("NPE updates are %s\n\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled"); + } + else + { + printf("updates disabled (not an NPE)\n\n"); + } + + printf(" MAC address | Age | Type \n"); + printf("___________________________________\n"); + + /* browse database */ + BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); + + while (IS_ITERATOR_VALID(&iterator)) + { + MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; + + if (descriptor->portID == portID && descriptor->type == IX_ETH_DB_FILTERING_RECORD) + { + recordCount++; + + /* display entry */ + printf(" %02X:%02X:%02X:%02X:%02X:%02X | %5d | %s\n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5], + descriptor->recordData.filteringData.age, + descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic"); + } + + /* move to the next record */ + BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result); + + /* debug */ + if (local_result == IX_ETH_DB_BUSY) + { + return IX_ETH_DB_FAIL; + } + } + + /* display number of records */ + printf("\nFound %d records\n", recordCount); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief displays all the filtering records belonging to all the ports + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @warning deprecated, use @ref ixEthDBFilteringDatabaseShowRecords() + * instead. Calling this function is equivalent to calling + * ixEthDBFilteringDatabaseShowRecords(IX_ETH_DB_ALL_PORTS, IX_ETH_DB_FILTERING_RECORD) + */ +IX_ETH_DB_PUBLIC +void ixEthDBFilteringDatabaseShowAll() +{ + IxEthDBPortId portIndex; + + printf("\nEthernet learning/filtering database: listing %d ports\n\n", (UINT32) IX_ETH_DB_NUMBER_OF_PORTS); + + for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) + { + ixEthDBFilteringDatabaseShow(portIndex); + + if (portIndex < IX_ETH_DB_NUMBER_OF_PORTS - 1) + { + printf("\n"); + } + } +} + +/** + * @brief displays one record in a format depending on the record filter + * + * @param descriptor pointer to the record + * @param recordFilter format filter + * + * This function will display the fields in a record depending on the + * selected record filter. + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBRecordShow(MacDescriptor *descriptor, IxEthDBRecordType recordFilter) +{ + if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD + || recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD)) + { + /* display VLAN record header - leave this commented code in place, its purpose is to align the print format with the header + printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n"); + printf("___________________________________________________________________\n"); */ + + if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) + { + printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | %d | %d | %d\n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5], + descriptor->recordData.filteringVlanData.age, + descriptor->recordData.filteringVlanData.staticEntry ? "static" : "dynamic", + IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag), + (descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12, + IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag)); + } + else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) + { + printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s | - | - | -\n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5], + descriptor->recordData.filteringData.age, + descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic"); + } + } + else if (recordFilter == IX_ETH_DB_FILTERING_RECORD) + { + /* display filtering record header - leave this commented code in place, its purpose is to align the print format with the header + printf(" MAC address | Age | Type \n"); + printf("_______________________________________\n"); */ + + if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) + { + printf("%02X:%02X:%02X:%02X:%02X:%02X | %3d | %s \n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5], + descriptor->recordData.filteringData.age, + descriptor->recordData.filteringData.staticEntry ? "static" : "dynamic"); + } + } + else if (recordFilter == IX_ETH_DB_WIFI_RECORD) + { + /* display WiFi record header - leave this commented code in place, its purpose is to align the print format with the header + printf(" MAC address | GW MAC address \n"); + printf("_______________________________________\n"); */ + + if (descriptor->type == IX_ETH_DB_WIFI_RECORD) + { + if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP) + { + /* gateway address present */ + printf("%02X:%02X:%02X:%02X:%02X:%02X | %02X:%02X:%02X:%02X:%02X:%02X \n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5], + descriptor->recordData.wifiData.gwMacAddress[0], + descriptor->recordData.wifiData.gwMacAddress[1], + descriptor->recordData.wifiData.gwMacAddress[2], + descriptor->recordData.wifiData.gwMacAddress[3], + descriptor->recordData.wifiData.gwMacAddress[4], + descriptor->recordData.wifiData.gwMacAddress[5]); + } + else + { + /* no gateway */ + printf("%02X:%02X:%02X:%02X:%02X:%02X | ----no gateway----- \n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5]); + } + } + } + else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD) + { + /* display Firewall record header - leave this commented code in place, its purpose is to align the print format with the header + printf(" MAC address \n"); + printf("__________________\n"); */ + + if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD) + { + printf("%02X:%02X:%02X:%02X:%02X:%02X \n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5]); + } + } + else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES) + { + /* display composite record header - leave this commented code in place, its purpose is to align the print format with the header + printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n"); + printf("_______________________________________________________________________________\n"); */ + + if (descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD) + { + printf("%02X:%02X:%02X:%02X:%02X:%02X | VLAN | %2d | %s | %4d | %1d | %1d | -----------------\n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5], + descriptor->recordData.filteringVlanData.age, + descriptor->recordData.filteringVlanData.staticEntry ? "static " : "dynamic", + IX_ETH_DB_GET_VLAN_ID(descriptor->recordData.filteringVlanData.ieee802_1qTag), + (descriptor->recordData.filteringVlanData.ieee802_1qTag & 0x1000) >> 12, + IX_ETH_DB_GET_QOS_PRIORITY(descriptor->recordData.filteringVlanData.ieee802_1qTag)); + } + else if (descriptor->type == IX_ETH_DB_FILTERING_RECORD) + { + printf("%02X:%02X:%02X:%02X:%02X:%02X | Filter | %2d | %s | ---- | - | --- | -----------------\n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5], + descriptor->recordData.filteringData.age, + descriptor->recordData.filteringData.staticEntry ? "static " : "dynamic"); + } + else if (descriptor->type == IX_ETH_DB_WIFI_RECORD) + { + if (descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP) + { + /* gateway address present */ + printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>AP | ---- | - | --- | %02X:%02X:%02X:%02X:%02X:%02X\n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5], + descriptor->recordData.wifiData.gwMacAddress[0], + descriptor->recordData.wifiData.gwMacAddress[1], + descriptor->recordData.wifiData.gwMacAddress[2], + descriptor->recordData.wifiData.gwMacAddress[3], + descriptor->recordData.wifiData.gwMacAddress[4], + descriptor->recordData.wifiData.gwMacAddress[5]); + } + else + { + /* no gateway */ + printf("%02X:%02X:%02X:%02X:%02X:%02X | WiFi | -- | AP=>ST | ---- | - | --- | -- no gateway -- \n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5]); + } + } + else if (descriptor->type == IX_ETH_DB_FIREWALL_RECORD) + { + printf("%02X:%02X:%02X:%02X:%02X:%02X | FW | -- | ------- | ---- | - | --- | -----------------\n", + descriptor->macAddress[0], + descriptor->macAddress[1], + descriptor->macAddress[2], + descriptor->macAddress[3], + descriptor->macAddress[4], + descriptor->macAddress[5]); + } + } + else + { + printf("invalid record filter\n"); + } +} + +/** + * @brief displays the status, records and configuration information of a port + * + * @param portID ID of the port + * @param recordFilter record filter to display + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBPortInfoShow(IxEthDBPortId portID, IxEthDBRecordType recordFilter) +{ + PortInfo *portInfo = &ixEthDBPortInfo[portID]; + UINT32 recordCount = 0; + HashIterator iterator; + IxEthDBStatus local_result; + + /* display port status */ + printf("== Port ID %d ==\n", portID); + + /* display capabilities */ + printf("- Capabilities: "); + + if ((portInfo->featureCapability & IX_ETH_DB_LEARNING) != 0) + { + printf("Learning (%s) ", ((portInfo->featureStatus & IX_ETH_DB_LEARNING) != 0) ? "on" : "off"); + } + + if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0) + { + printf("VLAN/QoS (%s) ", ((portInfo->featureStatus & IX_ETH_DB_VLAN_QOS) != 0) ? "on" : "off"); + } + + if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0) + { + printf("Firewall (%s) ", ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0) ? "on" : "off"); + } + + if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) + { + printf("WiFi (%s) ", ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) ? "on" : "off"); + } + + if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) + { + printf("STP (%s) ", ((portInfo->featureStatus & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0) ? "on" : "off"); + } + + printf("\n"); + + /* dependency map */ + ixEthDBDependencyPortMapShow(portID, portInfo->dependencyPortMap); + + /* NPE dynamic updates */ + if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE) + { + printf(" - NPE dynamic update is %s\n", portInfo->updateMethod.updateEnabled ? "enabled" : "disabled"); + } + else + { + printf(" - dynamic update disabled (not an NPE)\n"); + } + + if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) + { + if ((portInfo->featureStatus & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0) + { + /* WiFi header conversion */ + if ((portInfo->frameControlDurationID + + portInfo->bbsid[0] + + portInfo->bbsid[1] + + portInfo->bbsid[2] + + portInfo->bbsid[3] + + portInfo->bbsid[4] + + portInfo->bbsid[5]) == 0) + { + printf(" - WiFi header conversion not configured\n"); + } + else + { + printf(" - WiFi header conversion: BBSID [%02X:%02X:%02X:%02X:%02X:%02X], Frame Control 0x%X, Duration/ID 0x%X\n", + portInfo->bbsid[0], + portInfo->bbsid[1], + portInfo->bbsid[2], + portInfo->bbsid[3], + portInfo->bbsid[4], + portInfo->bbsid[5], + portInfo->frameControlDurationID >> 16, + portInfo->frameControlDurationID & 0xFFFF); + } + } + else + { + printf(" - WiFi header conversion not enabled\n"); + } + } + + /* Firewall */ + if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0) + { + if ((portInfo->featureStatus & IX_ETH_DB_FIREWALL) != 0) + { + printf(" - Firewall is in %s-list mode\n", portInfo->firewallMode == IX_ETH_DB_FIREWALL_BLACK_LIST ? "black" : "white"); + printf(" - Invalid source MAC address filtering is %s\n", portInfo->srcAddressFilterEnabled ? "enabled" : "disabled"); + } + else + { + printf(" - Firewall not enabled\n"); + } + } + + /* browse database if asked to display records */ + if (recordFilter != IX_ETH_DB_NO_RECORD_TYPE) + { + printf("\n"); + ixEthDBHeaderShow(recordFilter); + + BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator)); + + while (IS_ITERATOR_VALID(&iterator)) + { + MacDescriptor *descriptor = (MacDescriptor *) iterator.node->data; + + if (descriptor->portID == portID && (descriptor->type & recordFilter) != 0) + { + recordCount++; + + /* display entry */ + ixEthDBRecordShow(descriptor, recordFilter); + } + + /* move to the next record */ + BUSY_RETRY_WITH_RESULT(ixEthDBIncrementHashIterator(&dbHashtable, &iterator), local_result); + + /* debug */ + if (local_result == IX_ETH_DB_BUSY) + { + printf("EthDB (API): Error, database browser failed (no access), giving up\n"); + } + } + + printf("\nFound %d records\n\n", recordCount); + } +} + +/** + * @brief displays a record header + * + * @param recordFilter record type filter + * + * This function displays a record header, depending on + * the given record type filter. It is useful when used + * in conjunction with ixEthDBRecordShow which will display + * record fields formatted for the header, provided the same + * record filter is used. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or IX_ETH_DB_INVALID_ARG if the recordFilter + * parameter is invalid or not supported + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBHeaderShow(IxEthDBRecordType recordFilter) +{ + if (recordFilter == IX_ETH_DB_FILTERING_VLAN_RECORD + || recordFilter == (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD)) + { + /* display VLAN record header */ + printf(" MAC address | Age | Type | VLAN ID | CFI | QoS class \n"); + printf("___________________________________________________________________\n"); + } + else if (recordFilter == IX_ETH_DB_FILTERING_RECORD) + { + /* display filtering record header */ + printf(" MAC address | Age | Type \n"); + printf("_______________________________________\n"); + } + else if (recordFilter == IX_ETH_DB_WIFI_RECORD) + { + /* display WiFi record header */ + printf(" MAC address | GW MAC address \n"); + printf("_______________________________________\n"); + } + else if (recordFilter == IX_ETH_DB_FIREWALL_RECORD) + { + /* display Firewall record header */ + printf(" MAC address \n"); + printf("__________________\n"); + } + else if (recordFilter == IX_ETH_DB_ALL_RECORD_TYPES) + { + /* display composite record header */ + printf(" MAC address | Record | Age| Type | VLAN |CFI| QoS | GW MAC address \n"); + printf("_______________________________________________________________________________\n"); + } + else + { + return IX_ETH_DB_INVALID_ARG; + } + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief displays database information (records and port information) + * + * @param portID ID of the port to display (or IX_ETH_DB_ALL_PORTS for all the ports) + * @param recordFilter record filter (use IX_ETH_DB_NO_RECORD_TYPE to display only + * port information) + * + * Note that this function is documented in the main component header + * file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully or + * an appropriate error code otherwise + * + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter) +{ + IxEthDBPortId currentPort; + BOOL showAllPorts = (portID == IX_ETH_DB_ALL_PORTS); + + IX_ETH_DB_CHECK_PORT_ALL(portID); + + printf("\nEthernet learning/filtering database: listing %d port(s)\n\n", showAllPorts ? (UINT32) IX_ETH_DB_NUMBER_OF_PORTS : 1); + + currentPort = showAllPorts ? 0 : portID; + + while (currentPort != IX_ETH_DB_NUMBER_OF_PORTS) + { + /* display port info */ + ixEthDBPortInfoShow(currentPort, recordFilter); + + /* next port */ + currentPort = showAllPorts ? currentPort + 1 : IX_ETH_DB_NUMBER_OF_PORTS; + } + + return IX_ETH_DB_SUCCESS; +} + diff --git a/drivers/net/npe/IxEthDBSearch.c b/drivers/net/npe/IxEthDBSearch.c new file mode 100644 index 0000000..4a10878 --- /dev/null +++ b/drivers/net/npe/IxEthDBSearch.c @@ -0,0 +1,327 @@ +/** + * @file IxEthDBSearch.c + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxEthDB_p.h" + +extern HashTable dbHashtable; + +/** + * @brief matches two database records based on their MAC addresses + * + * @param untypedReference record to match against + * @param untypedEntry record to match + * + * @return TRUE if the match is successful or FALSE otherwise + * + * @internal + */ +IX_ETH_DB_PUBLIC +BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry) +{ + MacDescriptor *entry = (MacDescriptor *) untypedEntry; + MacDescriptor *reference = (MacDescriptor *) untypedReference; + + /* check accepted record types */ + if ((entry->type & reference->type) == 0) return FALSE; + + return (ixEthDBAddressCompare((UINT8 *) entry->macAddress, (UINT8 *) reference->macAddress) == 0); +} + +/** + * @brief matches two database records based on their MAC addresses + * and VLAN IDs + * + * @param untypedReference record to match against + * @param untypedEntry record to match + * + * @return TRUE if the match is successful or FALSE otherwise + * + * @internal + */ +IX_ETH_DB_PUBLIC +BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry) +{ + MacDescriptor *entry = (MacDescriptor *) untypedEntry; + MacDescriptor *reference = (MacDescriptor *) untypedReference; + + /* check accepted record types */ + if ((entry->type & reference->type) == 0) return FALSE; + + return (IX_ETH_DB_GET_VLAN_ID(entry->recordData.filteringVlanData.ieee802_1qTag) == + IX_ETH_DB_GET_VLAN_ID(reference->recordData.filteringVlanData.ieee802_1qTag)) && + (ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0); +} + +/** + * @brief matches two database records based on their MAC addresses + * and port IDs + * + * @param untypedReference record to match against + * @param untypedEntry record to match + * + * @return TRUE if the match is successful or FALSE otherwise + * + * @internal + */ +IX_ETH_DB_PUBLIC +BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry) +{ + MacDescriptor *entry = (MacDescriptor *) untypedEntry; + MacDescriptor *reference = (MacDescriptor *) untypedReference; + + /* check accepted record types */ + if ((entry->type & reference->type) == 0) return FALSE; + + return (entry->portID == reference->portID) && + (ixEthDBAddressCompare(entry->macAddress, reference->macAddress) == 0); +} + +/** + * @brief dummy matching function, registered for safety + * + * @param reference record to match against (unused) + * @param entry record to match (unused) + * + * This function is registered in the matching functions + * array on invalid types. Calling it will display an + * error message, indicating an error in the component logic. + * + * @return FALSE + * + * @internal + */ +IX_ETH_DB_PUBLIC +BOOL ixEthDBNullMatch(void *reference, void *entry) +{ + /* display an error message */ + + ixOsalLog(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, "DB: (Search) The NullMatch function was called, wrong key type?\n", 0, 0, 0, 0, 0, 0); + + + return FALSE; +} + +/** + * @brief registers hash matching methods + * + * @param matchFunctions table of match functions to be populated + * + * This function registers the available record matching functions + * by indexing them on record types into the given function array. + * + * Note that it is compulsory to call this in ixEthDBInit(), + * otherwise hashtable searching and removal will not work + * + * @return number of registered functions + * + * @internal + */ +IX_ETH_DB_PUBLIC +UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions) +{ + UINT32 i; + + /* safety first */ + for ( i = 0 ; i < IX_ETH_DB_MAX_KEY_INDEX + 1 ; i++) + { + matchFunctions[i] = ixEthDBNullMatch; + } + + /* register MAC search method */ + matchFunctions[IX_ETH_DB_MAC_KEY] = ixEthDBAddressRecordMatch; + + /* register MAC/PortID search method */ + matchFunctions[IX_ETH_DB_MAC_PORT_KEY] = ixEthDBPortRecordMatch; + + /* register MAC/VLAN ID search method */ + matchFunctions[IX_ETH_DB_MAC_VLAN_KEY] = ixEthDBVlanRecordMatch; + + return 3; /* three methods */ +} + +/** + * @brief search a record in the Ethernet datbase + * + * @param macAddress MAC address to perform the search on + * @param typeFilter type of records to consider for matching + * + * @warning if searching is successful an implicit write lock + * to the search result is granted, therefore unlock the + * entry using @ref ixEthDBReleaseHashNode() as soon as possible. + * + * @see ixEthDBReleaseHashNode() + * + * @return the search result, or NULL if a record with the given + * MAC address was not found + * + * @internal + */ +IX_ETH_DB_PUBLIC +HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter) +{ + HashNode *searchResult = NULL; + MacDescriptor reference; + + TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; + + if (macAddress == NULL) + { + return NULL; + } + + /* fill search fields */ + memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr)); + + /* set acceptable record types */ + reference.type = typeFilter; + + BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference, &searchResult)); + + return searchResult; +} + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter) +{ + MacDescriptor reference; + IxEthDBStatus result; + + TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER; + + if (macAddress == NULL) + { + return IX_ETH_DB_INVALID_ARG; + } + + /* fill search fields */ + memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr)); + + /* set acceptable record types */ + reference.type = typeFilter; + + result = ixEthDBPeekHashEntry(&dbHashtable, IX_ETH_DB_MAC_KEY, &reference); + + return result; +} + +/** + * @brief search a record in the Ethernet datbase + * + * @param macAddress MAC address to perform the search on + * @param portID port ID to perform the search on + * @param typeFilter type of records to consider for matching + * + * @warning if searching is successful an implicit write lock + * to the search result is granted, therefore unlock the + * entry using @ref ixEthDBReleaseHashNode() as soon as possible. + * + * @see ixEthDBReleaseHashNode() + * + * @return the search result, or NULL if a record with the given + * MAC address/port ID combination was not found + * + * @internal + */ +IX_ETH_DB_PUBLIC +HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter) +{ + HashNode *searchResult = NULL; + MacDescriptor reference; + + if (macAddress == NULL) + { + return NULL; + } + + /* fill search fields */ + memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr)); + reference.portID = portID; + + /* set acceptable record types */ + reference.type = typeFilter; + + BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_PORT_KEY, &reference, &searchResult)); + + return searchResult; +} + +/** + * @brief search a record in the Ethernet datbase + * + * @param macAddress MAC address to perform the search on + * @param vlanID VLAN ID to perform the search on + * @param typeFilter type of records to consider for matching + * + * @warning if searching is successful an implicit write lock + * to the search result is granted, therefore unlock the + * entry using @ref ixEthDBReleaseHashNode() as soon as possible. + * + * @see ixEthDBReleaseHashNode() + * + * @return the search result, or NULL if a record with the given + * MAC address/VLAN ID combination was not found + * + * @internal + */ +IX_ETH_DB_PUBLIC +HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter) +{ + HashNode *searchResult = NULL; + MacDescriptor reference; + + if (macAddress == NULL) + { + return NULL; + } + + /* fill search fields */ + memcpy(reference.macAddress, macAddress, sizeof (IxEthDBMacAddr)); + reference.recordData.filteringVlanData.ieee802_1qTag = + IX_ETH_DB_SET_VLAN_ID(reference.recordData.filteringVlanData.ieee802_1qTag, vlanID); + + /* set acceptable record types */ + reference.type = typeFilter; + + BUSY_RETRY(ixEthDBSearchHashEntry(&dbHashtable, IX_ETH_DB_MAC_VLAN_KEY, &reference, &searchResult)); + + return searchResult; +} diff --git a/drivers/net/npe/IxEthDBSpanningTree.c b/drivers/net/npe/IxEthDBSpanningTree.c new file mode 100644 index 0000000..6d9fd6e --- /dev/null +++ b/drivers/net/npe/IxEthDBSpanningTree.c @@ -0,0 +1,107 @@ +/** + * @file IxEthDBSpanningTree.c + * + * @brief Implementation of the STP API + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + + +#include "IxEthDB_p.h" + +/** + * @brief sets the STP blocking state of a port + * + * @param portID ID of the port + * @param blocked TRUE to block the port or FALSE to unblock it + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked) +{ + IxNpeMhMessage message; + IX_STATUS result; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL); + + ixEthDBPortInfo[portID].stpBlocked = blocked; + + FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief retrieves the STP blocking state of a port + * + * @param portID ID of the port + * @param blocked address to write the blocked status into + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_SPANNING_TREE_PROTOCOL); + + IX_ETH_DB_CHECK_REFERENCE(blocked); + + *blocked = ixEthDBPortInfo[portID].stpBlocked; + + return IX_ETH_DB_SUCCESS; +} diff --git a/drivers/net/npe/IxEthDBUtil.c b/drivers/net/npe/IxEthDBUtil.c new file mode 100644 index 0000000..e708bf1 --- /dev/null +++ b/drivers/net/npe/IxEthDBUtil.c @@ -0,0 +1,120 @@ +/** + * @file ethUtil.c + * + * @brief Utility functions + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + + +#include "IxFeatureCtrl.h" +#include "IxEthDB_p.h" + +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portID) +{ + /* If not IXP42X A0 stepping, proceed to check for existence of coprocessors */ + if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != + (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) + || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) + { + if ((portID == 0) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + return IX_ETH_DB_FAIL; + } + + if ((portID == 1) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + return IX_ETH_DB_FAIL; + } + + if ((portID == 2) && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA_ETH) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + return IX_ETH_DB_FAIL; + } + } + + return IX_ETH_DB_SUCCESS; +} + +IX_ETH_DB_PUBLIC +BOOL ixEthDBCheckSingleBitValue(UINT32 value) +{ +#if (CPU != SIMSPARCSOLARIS) && !defined (__wince) + UINT32 shift; + + /* use the count-leading-zeros XScale instruction */ + __asm__ ("clz %0, %1\n" : "=r" (shift) : "r" (value)); + + return ((value << shift) == 0x80000000UL); + +#else + + while (value != 0) + { + if (value == 1) return TRUE; + else if ((value & 1) == 1) return FALSE; + + value >>= 1; + } + + return FALSE; + +#endif +} + +const char *mac2string(const unsigned char *mac) +{ + static char str[19]; + + if (mac == NULL) + { + return NULL; + } + + sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + return str; +} diff --git a/drivers/net/npe/IxEthDBVlan.c b/drivers/net/npe/IxEthDBVlan.c new file mode 100644 index 0000000..e2efb9b --- /dev/null +++ b/drivers/net/npe/IxEthDBVlan.c @@ -0,0 +1,1179 @@ +/** + * @file IxEthDBVlan.c + * + * @brief Implementation of the VLAN API + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxEthDB.h" +#include "IxEthDB_p.h" + +/* forward prototypes */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex); +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet); + +/* contants used by various functions as "action" parameter */ +#define ADD_VLAN (0x1) +#define REMOVE_VLAN (0x2) + +/** + * @brief adds or removes a VLAN from a VLAN set + * + * @param vlanID VLAN ID to add or remove + * @param table VLAN set to add into or remove from + * @param action ADD_VLAN or REMOVE_VLAN + * + * @internal + */ +IX_ETH_DB_PRIVATE +void ixEthDBLocalVlanMembershipChange(UINT32 vlanID, IxEthDBVlanSet table, UINT32 action) +{ + UINT32 setOffset; + + /* add/remove VID to membership table */ + setOffset = VLAN_SET_OFFSET(vlanID); /* we need 9 bits to index the 512 byte membership array */ + + if (action == ADD_VLAN) + { + table[setOffset] |= 1 << VLAN_SET_MASK(vlanID); + } + else if (action == REMOVE_VLAN) + { + table[setOffset] &= ~(1 << VLAN_SET_MASK(vlanID)); + } +} + +/** + * @brief updates a set of 8 VLANs in an NPE + * + * @param portID ID of the port + * @param setOffset offset of the 8 VLANs + * + * This function updates the VLAN membership table + * and Transmit Tagging Info table for 8 consecutive + * VLAN IDs indexed by setOffset. + * + * For example, a setOffset of 0 indexes VLAN IDs 0 + * through 7, 1 indexes VLAN IDs 8 through 9 etc. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBVlanTableEntryUpdate(IxEthDBPortId portID, UINT32 setOffset) +{ + PortInfo *portInfo = &ixEthDBPortInfo[portID]; + IxNpeMhMessage message; + IX_STATUS result; + + FILL_SETPORTVLANTABLEENTRY_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), + 2 * setOffset, + portInfo->vlanMembership[setOffset], + portInfo->transmitTaggingInfo[setOffset]); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief updates a VLAN range in an NPE + * + * @param portID ID of the port + * + * This function is similar to @ref ixEthDBVlanTableEntryUpdate + * except that it can update more than one VLAN set (up to + * the entire VLAN membership and TTI tables if the offset is 0 + * and length is sizeof (IxEthDBVlanSet) (512 bytes). + * + * Updating the NPE via this method is slower as it requires + * a memory copy from SDRAM, hence it is recommended that the + * ixEthDBVlanTableEntryUpdate function is used where possible. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBVlanTableRangeUpdate(IxEthDBPortId portID) +{ + PortInfo *portInfo = &ixEthDBPortInfo[portID]; + UINT8 *vlanUpdateZone = (UINT8 *) portInfo->updateMethod.vlanUpdateZone; + IxNpeMhMessage message; + UINT32 setIndex; + IX_STATUS result; + + /* copy membership info and transmit tagging into into exchange area */ + for (setIndex = 0 ; setIndex < sizeof (portInfo->vlanMembership) ; setIndex++) + { + /* membership and TTI data are interleaved */ + vlanUpdateZone[setIndex * 2] = portInfo->vlanMembership[setIndex]; + vlanUpdateZone[setIndex * 2 + 1] = portInfo->transmitTaggingInfo[setIndex]; + } + + IX_OSAL_CACHE_FLUSH(vlanUpdateZone, FULL_VLAN_BYTE_SIZE); + + /* build NPE message */ + FILL_SETPORTVLANTABLERANGE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 0, 0, + IX_OSAL_MMU_VIRT_TO_PHYS(vlanUpdateZone)); + + /* send message */ + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief adds or removes a VLAN from a port's VLAN membership table + * or Transmit Tagging Information table + * + * @param portID ID of the port + * @param vlanID VLAN ID to add or remove + * @param table to add or remove from + * @param action ADD_VLAN or REMOVE_VLAN + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBPortVlanMembershipChange(IxEthDBPortId portID, IxEthDBVlanId vlanID, IxEthDBVlanSet table, UINT32 action) +{ + /* change VLAN in local membership table */ + ixEthDBLocalVlanMembershipChange(vlanID, table, action); + + /* send updated entry to NPE */ + return ixEthDBVlanTableEntryUpdate(portID, VLAN_SET_OFFSET(vlanID)); +} + +/** + * @brief sets the default port VLAN tag (the lower 3 bytes are the PVID) + * + * @param portID ID of the port + * @param vlanTag port VLAN tag (802.1Q tag) + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag) +{ + IxNpeMhMessage message; + IX_STATUS result; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_VLAN_TAG(vlanTag); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + /* add VLAN ID to local membership table */ + ixEthDBPortVlanMembershipChange(portID, + vlanTag & IX_ETH_DB_802_1Q_VLAN_MASK, + ixEthDBPortInfo[portID].vlanMembership, + ADD_VLAN); + + /* set tag in portInfo */ + ixEthDBPortInfo[portID].vlanTag = vlanTag; + + /* build VLAN_SetDefaultRxVID message */ + FILL_SETDEFAULTRXVID_MSG(message, + IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), + IX_IEEE802_1Q_VLAN_TPID, + vlanTag); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief retrieves the default port VLAN tag (the lower 3 bytes are the PVID) + * + * @param portID ID of the port + * @param vlanTag address to write the port VLAN tag (802.1Q tag) into + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(vlanTag); + + *vlanTag = ixEthDBPortInfo[portID].vlanTag; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief sets the VLAN tag (the lower 3 bytes are the PVID) of a + * database filtering record + * + * @param portID ID of the port + * @param vlanTag VLAN tag (802.1Q tag) + * + * Important: filtering records are automatically converted to + * IX_ETH_DB_FILTERING_VLAN record when added a VLAN tag. + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag) +{ + HashNode *searchResult; + MacDescriptor *descriptor; + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + IX_ETH_DB_CHECK_VLAN_TAG(vlanTag); + + searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS); + + if (searchResult == NULL) + { + return IX_ETH_DB_NO_SUCH_ADDR; + } + + descriptor = (MacDescriptor *) searchResult->data; + + /* set record type to VLAN if not already set */ + descriptor->type = IX_ETH_DB_FILTERING_VLAN_RECORD; + + /* add vlan tag */ + descriptor->recordData.filteringVlanData.ieee802_1qTag = vlanTag; + + /* transaction completed */ + ixEthDBReleaseHashNode(searchResult); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief retrieves the VLAN tag (the lower 3 bytes are the PVID) from a + * database VLAN filtering record + * + * @param portID ID of the port + * @param vlanTag address to write the VLAN tag (802.1Q tag) into + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag) +{ + HashNode *searchResult; + MacDescriptor *descriptor; + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + IX_ETH_DB_CHECK_REFERENCE(vlanTag); + + searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_FILTERING_VLAN_RECORD); + + if (searchResult == NULL) + { + return IX_ETH_DB_NO_SUCH_ADDR; + } + + descriptor = (MacDescriptor *) searchResult->data; + + /* get vlan tag */ + *vlanTag = descriptor->recordData.filteringVlanData.ieee802_1qTag; + + /* transaction completed */ + ixEthDBReleaseHashNode(searchResult); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief adds a VLAN to a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanID VLAN ID to add + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_VLAN_ID(vlanID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN); +} + +/** + * @brief removes a VLAN from a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanID VLAN ID to remove + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_VLAN_ID(vlanID); + + /* for safety isolate only the VLAN ID in the tag (the lower 12 bits) */ + vlanID = vlanID & IX_ETH_DB_802_1Q_VLAN_MASK; + + /* check we're not asked to remove the default port VID */ + if (vlanID == IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag)) + { + return IX_ETH_DB_NO_PERMISSION; + } + + return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN); +} + +/** + * @brief adds or removes a VLAN range from a port's + * VLAN membership table or TTI table + * + * @param portID ID of the port + * @param vlanIDMin start of the VLAN range + * @param vlanIDMax end of the VLAN range + * @param table VLAN set to add or remove from + * @param action ADD_VLAN or REMOVE_VLAN + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBPortVlanMembershipRangeChange(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, IxEthDBVlanSet table, UINT32 action) +{ + UINT32 setOffsetMin, setOffsetMax; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_VLAN_ID(vlanIDMin); + + IX_ETH_DB_CHECK_VLAN_ID(vlanIDMax); + + /* for safety isolate only the VLAN ID in the tags (the lower 12 bits) */ + vlanIDMin = vlanIDMin & IX_ETH_DB_802_1Q_VLAN_MASK; + vlanIDMax = vlanIDMax & IX_ETH_DB_802_1Q_VLAN_MASK; + + /* is this a range? */ + if (vlanIDMax < vlanIDMin) + { + return IX_ETH_DB_INVALID_VLAN; + } + + /* check that we're not specifically asked to remove the default port VID */ + if (action == REMOVE_VLAN && vlanIDMax == vlanIDMin && IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag) == vlanIDMin) + { + return IX_ETH_DB_NO_PERMISSION; + } + + /* compute set offsets */ + setOffsetMin = VLAN_SET_OFFSET(vlanIDMin); + setOffsetMax = VLAN_SET_OFFSET(vlanIDMax); + + /* change VLAN range */ + for (; vlanIDMin <= vlanIDMax ; vlanIDMin++) + { + /* change vlan in local membership table */ + ixEthDBLocalVlanMembershipChange(vlanIDMin, table, action); + } + + /* if the range is within one set (max 8 VLANs in one table byte) we can just update that entry in the NPE */ + if (setOffsetMin == setOffsetMax) + { + /* send updated entry to NPE */ + return ixEthDBVlanTableEntryUpdate(portID, setOffsetMin); + } + else + { + /* update a zone of the membership/transmit tag info table */ + return ixEthDBVlanTableRangeUpdate(portID); + } +} + +/** + * @brief adds a VLAN range to a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanIDMin start of the VLAN range + * @param vlanIDMax end of the VLAN range + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN); +} + +/** + * @brief removes a VLAN range from a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanIDMin start of the VLAN range + * @param vlanIDMax end of the VLAN range + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN); +} + +/** + * @brief sets a port's VLAN membership table or TTI table and + * updates the NPE VLAN configuration + * + * @param portID ID of the port + * @param portVlanTable port VLAN table to set + * @param vlanSet new set contents + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(vlanSet); + + memcpy(portVlanTable, vlanSet, sizeof (IxEthDBVlanSet)); + + return ixEthDBVlanTableRangeUpdate(portID); +} + +/** + * @brief retireves a port's VLAN membership table or TTI table + * + * @param portID ID of the port + * @param portVlanTable port VLAN table to retrieve + * @param vlanSet address to + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(vlanSet); + + memcpy(vlanSet, portVlanTable, sizeof (IxEthDBVlanSet)); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief sets a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanSet new VLAN membership table + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) +{ + IxEthDBVlanId vlanID; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(vlanSet); + + /* set the bit corresponding to the PVID just in case */ + vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag); + vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID); + + return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet); +} + +/** + * @brief retrieves a port's VLAN membership table + * + * @param portID ID of the port + * @param vlanSet location to store the port's VLAN membership table + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet); +} + +/** + * @brief enables or disables Egress tagging for one VLAN ID + * + * @param portID ID of the port + * @param vlanID VLAN ID to enable or disable Egress tagging on + * @param enabled TRUE to enable and FALSE to disable tagging + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_VLAN_ID(vlanID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN); +} + +/** + * @brief retrieves the Egress tagging status for one VLAN ID + * + * @param portID ID of the port + * @param vlanID VLAN ID to retrieve the tagging status for + * @param enabled location to store the tagging status + * (TRUE - tagging enabled, FALSE - tagging disabled) + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(enabled); + + IX_ETH_DB_CHECK_VLAN_ID(vlanID); + + *enabled = ((ixEthDBPortInfo[portID].transmitTaggingInfo[VLAN_SET_OFFSET(vlanID)] & (1 << VLAN_SET_MASK(vlanID))) != 0); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief enables or disables Egress VLAN tagging for a VLAN range + * + * @param portID ID of the port + * @param vlanIDMin start of VLAN range + * @param vlanIDMax end of VLAN range + * @param enabled TRUE to enable or FALSE to disable VLAN tagging + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN); +} + +/** + * @brief sets the Egress VLAN tagging table (the Transmit Tagging + * Information table) + * + * @param portID ID of the port + * @param vlanSet new TTI table + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) +{ + IxEthDBVlanId vlanID; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(vlanSet); + + /* set the PVID bit just in case */ + vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag); + vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID); + + return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet); +} + +/** + * @brief retrieves the Egress VLAN tagging table (the Transmit + * Tagging Information table) + * + * @param portID ID of the port + * @param vlanSet location to store the port's TTI table + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet); +} + +/** + * @brief sends the NPE the updated frame filter and default + * Ingress tagging + * + * @param portID ID of the port + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBIngressVlanModeUpdate(IxEthDBPortId portID) +{ + PortInfo *portInfo = &ixEthDBPortInfo[portID]; + IxNpeMhMessage message; + IX_STATUS result; + + FILL_SETRXTAGMODE_MSG(message, portID, portInfo->npeFrameFilter, portInfo->npeTaggingAction); + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief sets the default Ingress tagging behavior + * + * @param portID ID of the port + * @param taggingAction default tagging behavior + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction) +{ + PortInfo *portInfo; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + portInfo = &ixEthDBPortInfo[portID]; + + if (taggingAction == IX_ETH_DB_PASS_THROUGH) + { + portInfo->npeTaggingAction = 0x00; + } + else if (taggingAction == IX_ETH_DB_ADD_TAG) + { + portInfo->npeTaggingAction = 0x02; + } + else if (taggingAction == IX_ETH_DB_REMOVE_TAG) + { + portInfo->npeTaggingAction = 0x01; + } + else + { + return IX_ETH_DB_INVALID_ARG; + } + + portInfo->taggingAction = taggingAction; + + return ixEthDBIngressVlanModeUpdate(portID); +} + +/** + * @brief retrieves the default Ingress tagging behavior of a port + * + * @param portID ID of the port + * @param taggingAction location to save the default tagging behavior + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(taggingAction); + + *taggingAction = ixEthDBPortInfo[portID].taggingAction; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief sets the Ingress acceptable frame type filter + * + * @param portID ID of the port + * @param frameFilter acceptable frame type filter + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter) +{ + PortInfo *portInfo; + IxEthDBStatus result = IX_ETH_DB_SUCCESS; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + /* check parameter range + the ORed value of the valid values is 0x7 + a value having extra bits is invalid */ + if ((frameFilter | 0x7) != 0x7 || frameFilter == 0) + { + return IX_ETH_DB_INVALID_ARG; + } + + portInfo = &ixEthDBPortInfo[portID]; + + portInfo->frameFilter = frameFilter; + portInfo->npeFrameFilter = 0; /* allow all by default */ + + /* if accepting priority tagged but not all VLAN tagged + set the membership table to contain only VLAN ID 0 + hence remove vlans 1-4094 and add VLAN ID 0 */ + if (((frameFilter & IX_ETH_DB_PRIORITY_TAGGED_FRAMES) != 0) + && ((frameFilter & IX_ETH_DB_VLAN_TAGGED_FRAMES) == 0)) + { + result = ixEthDBPortVlanMembershipRangeChange(portID, + 1, IX_ETH_DB_802_1Q_MAX_VLAN_ID, portInfo->vlanMembership, REMOVE_VLAN); + + if (result == IX_ETH_DB_SUCCESS) + { + ixEthDBLocalVlanMembershipChange(0, portInfo->vlanMembership, ADD_VLAN); + result = ixEthDBVlanTableRangeUpdate(portID); + } + } + + /* untagged only? */ + if (frameFilter == IX_ETH_DB_UNTAGGED_FRAMES) + { + portInfo->npeFrameFilter = 0x01; + } + + /* tagged only? */ + if ((frameFilter & IX_ETH_DB_UNTAGGED_FRAMES) == 0) + { + portInfo->npeFrameFilter = 0x02; + } + + if (result == IX_ETH_DB_SUCCESS) + { + result = ixEthDBIngressVlanModeUpdate(portID); + } + + return result; +} + +/** + * @brief retrieves the acceptable frame type filter for a port + * + * @param portID ID of the port + * @param frameFilter location to store the frame filter + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(frameFilter); + + *frameFilter = ixEthDBPortInfo[portID].frameFilter; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief sends an NPE the updated configuration related + * to one QoS priority (associated traffic class and AQM mapping) + * + * @param portID ID of the port + * @param classIndex QoS priority (traffic class index) + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex) +{ + IxNpeMhMessage message; + IX_STATUS result; + + UINT32 trafficClass = ixEthDBPortInfo[portID].priorityTable[classIndex]; + UINT32 aqmQueue = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[trafficClass]; + + FILL_SETRXQOSENTRY(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), classIndex, trafficClass, aqmQueue); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief sets the priority mapping table + * + * @param portID ID of the port + * @param priorityTable new priority mapping table + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) +{ + UINT32 classIndex; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(priorityTable); + + for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++) + { + /* check range */ + if (priorityTable[classIndex] >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) + { + return IX_ETH_DB_INVALID_PRIORITY; + } + } + + /* set new traffic classes */ + for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++) + { + ixEthDBPortInfo[portID].priorityTable[classIndex] = priorityTable[classIndex]; + + if (ixEthDBUpdateTrafficClass(portID, classIndex) != IX_ETH_DB_SUCCESS) + { + return IX_ETH_DB_FAIL; + } + } + + return IX_ETH_DB_SUCCESS; + } + +/** + * @brief retrieves a port's priority mapping table + * + * @param portID ID of the port + * @param priorityTable location to store the priority table + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(priorityTable); + + memcpy(priorityTable, ixEthDBPortInfo[portID].priorityTable, sizeof (IxEthDBPriorityTable)); + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief sets one QoS priority => traffic class mapping + * + * @param portID ID of the port + * @param userPriority QoS (user) priority + * @param trafficClass associated traffic class + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + /* check ranges for userPriority and trafficClass */ + if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT || trafficClass >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount) + { + return IX_ETH_DB_INVALID_PRIORITY; + } + + ixEthDBPortInfo[portID].priorityTable[userPriority] = trafficClass; + + return ixEthDBUpdateTrafficClass(portID, userPriority); +} + +/** + * @brief retrieves one QoS priority => traffic class mapping + * + * @param portID ID of the port + * @param userPriority QoS (user) priority + * @param trafficClass location to store the associated traffic class + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + IX_ETH_DB_CHECK_REFERENCE(trafficClass); + + /* check userPriority range */ + if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT) + { + return IX_ETH_DB_INVALID_PRIORITY; + } + + *trafficClass = ixEthDBPortInfo[portID].priorityTable[userPriority]; + + return IX_ETH_DB_SUCCESS; +} + +/** + * @brief enables or disables the source port extraction + * from the VLAN TPID field + * + * @param portID ID of the port + * @param enable TRUE to enable or FALSE to disable + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable) +{ + IxNpeMhMessage message; + IX_STATUS result; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS); + + FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} diff --git a/drivers/net/npe/IxEthDBWiFi.c b/drivers/net/npe/IxEthDBWiFi.c new file mode 100644 index 0000000..0a6043f --- /dev/null +++ b/drivers/net/npe/IxEthDBWiFi.c @@ -0,0 +1,480 @@ +/** + * @file IxEthDBAPI.c + * + * @brief Implementation of the public API + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxEthDB_p.h" + +/* forward prototypes */ +IX_ETH_DB_PUBLIC +MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations); + +/** + * @brief sets the BBSID value for the WiFi header conversion feature + * + * @param portID ID of the port + * @param bbsid pointer to the 6-byte BBSID value + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid) +{ + IxNpeMhMessage message; + IX_STATUS result; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); + + IX_ETH_DB_CHECK_REFERENCE(bbsid); + + memcpy(ixEthDBPortInfo[portID].bbsid, bbsid, sizeof (IxEthDBMacAddr)); + + FILL_SETBBSID_MSG(message, portID, bbsid); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief updates the Frame Control and Duration/ID WiFi header + * conversion parameters in an NPE + * + * @param portID ID of the port + * + * This function will send a message to the NPE updating the + * frame conversion parameters for 802.3 => 802.11 header conversion. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or IX_ETH_DB_FAIL otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBWiFiFrameControlDurationIDUpdate(IxEthDBPortId portID) +{ + IxNpeMhMessage message; + IX_STATUS result; + + FILL_SETFRAMECONTROLDURATIONID(message, portID, ixEthDBPortInfo[portID].frameControlDurationID); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + return result; +} + +/** + * @brief sets the Duration/ID WiFi frame header conversion parameter + * + * @param portID ID of the port + * @param durationID 16-bit value containing the new Duration/ID parameter + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); + + ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF0000) | durationID; + + return ixEthDBWiFiFrameControlDurationIDUpdate(portID); +} + +/** + * @brief sets the Frame Control WiFi frame header conversion parameter + * + * @param portID ID of the port + * @param durationID 16-bit value containing the new Frame Control parameter + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl) +{ + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); + + ixEthDBPortInfo[portID].frameControlDurationID = (ixEthDBPortInfo[portID].frameControlDurationID & 0xFFFF) | (frameControl << 16); + + return ixEthDBWiFiFrameControlDurationIDUpdate(portID); +} + +/** + * @brief removes a WiFi header conversion record + * + * @param portID ID of the port + * @param macAddr MAC address of the record to remove + * + * Note that this function is documented in the main + * component header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) +{ + MacDescriptor recordTemplate; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); + + memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr)); + + recordTemplate.type = IX_ETH_DB_WIFI_RECORD; + recordTemplate.portID = portID; + + return ixEthDBRemove(&recordTemplate, NULL); +} + +/** + * @brief adds a WiFi header conversion record + * + * @param portID ID of the port + * @param macAddr MAC address of the record to add + * @param gatewayMacAddr address of the gateway (or + * NULL if this is a station record) + * + * This function adds a record of type AP_TO_AP (gateway is not NULL) + * or AP_TO_STA (gateway is NULL) in the main database as a + * WiFi header conversion record. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + * + * @internal + */ +IX_ETH_DB_PRIVATE +IxEthDBStatus ixEthDBWiFiEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr) +{ + MacDescriptor recordTemplate; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_REFERENCE(macAddr); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); + + memcpy(recordTemplate.macAddress, macAddr, sizeof (IxEthDBMacAddr)); + + recordTemplate.type = IX_ETH_DB_WIFI_RECORD; + recordTemplate.portID = portID; + + if (gatewayMacAddr != NULL) + { + memcpy(recordTemplate.recordData.wifiData.gwMacAddress, gatewayMacAddr, sizeof (IxEthDBMacAddr)); + + recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_AP; + } + else + { + memset(recordTemplate.recordData.wifiData.gwMacAddress, 0, sizeof (IxEthDBMacAddr)); + + recordTemplate.recordData.wifiData.type = IX_ETH_DB_WIFI_AP_TO_STA; + } + + return ixEthDBAdd(&recordTemplate, NULL); +} + +/** + * @brief adds a WiFi header conversion record + * + * @param portID ID of the port + * @param macAddr MAC address of the record to add + * @param gatewayMacAddr address of the gateway + * + * This function adds a record of type AP_TO_AP + * in the main database as a WiFi header conversion record. + * + * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd(). + * + * Note that this function is documented in the main + * component header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr) +{ + IX_ETH_DB_CHECK_REFERENCE(gatewayMacAddr); + + return ixEthDBWiFiEntryAdd(portID, macAddr, gatewayMacAddr); +} + +/** + * @brief adds a WiFi header conversion record + * + * @param portID ID of the port + * @param macAddr MAC address of the record to add + * + * This function adds a record of type AP_TO_STA + * in the main database as a WiFi header conversion record. + * + * This is simply a wrapper over @ref ixEthDBWiFiEntryAdd(). + * + * Note that this function is documented in the main + * component header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed + * successfully or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) +{ + return ixEthDBWiFiEntryAdd(portID, macAddr, NULL); +} + +/** + * @brief selects a set of gateways from a tree of + * WiFi header conversion records + * + * @param stations binary tree containing pointers to WiFi header + * conversion records + * + * This function browses through the input binary tree, identifies + * records of type AP_TO_AP, clones these records and appends them + * to a vine (a single right-branch binary tree) which is returned + * as result. A maximum of MAX_GW_SIZE entries containing gateways + * will be cloned from the original tree. + * + * @return vine (linear binary tree) containing record + * clones of AP_TO_AP type, which have a gateway field + * + * @internal + */ +IX_ETH_DB_PUBLIC +MacTreeNode *ixEthDBGatewaySelect(MacTreeNode *stations) +{ + MacTreeNodeStack *stack; + MacTreeNode *gateways, *insertionPlace; + UINT32 gwIndex = 1; /* skip the empty root */ + + if (stations == NULL) + { + return NULL; + } + + stack = ixOsalCacheDmaMalloc(sizeof (MacTreeNodeStack)); + + if (stack == NULL) + { + ERROR_LOG("DB: (WiFi) failed to allocate the node stack for gateway tree linearization, out of memory?\n"); + return NULL; + } + + /* initialize root node */ + gateways = insertionPlace = NULL; + + /* start browsing the station tree */ + NODE_STACK_INIT(stack); + + /* initialize stack by pushing the tree root at offset 0 */ + NODE_STACK_PUSH(stack, stations, 0); + + while (NODE_STACK_NONEMPTY(stack)) + { + MacTreeNode *node; + UINT32 offset; + + NODE_STACK_POP(stack, node, offset); + + /* we can store maximum 31 (32 total, 1 empty root) entries in the gateway tree */ + if (offset > (MAX_GW_SIZE - 1)) break; + + /* check if this record has a gateway address */ + if (node->descriptor != NULL && node->descriptor->recordData.wifiData.type == IX_ETH_DB_WIFI_AP_TO_AP) + { + /* found a record, create an insertion place */ + if (insertionPlace != NULL) + { + insertionPlace->right = ixEthDBAllocMacTreeNode(); + insertionPlace = insertionPlace->right; + } + else + { + gateways = ixEthDBAllocMacTreeNode(); + insertionPlace = gateways; + } + + if (insertionPlace == NULL) + { + /* no nodes left, bail out with what we have */ + ixOsalCacheDmaFree(stack); + return gateways; + } + + /* clone the original record for the gateway tree */ + insertionPlace->descriptor = ixEthDBCloneMacDescriptor(node->descriptor); + + /* insert and update the offset in the original record */ + node->descriptor->recordData.wifiData.gwAddressIndex = gwIndex++; + } + + /* browse the tree */ + if (node->left != NULL) + { + NODE_STACK_PUSH(stack, node->left, LEFT_CHILD_OFFSET(offset)); + } + + if (node->right != NULL) + { + NODE_STACK_PUSH(stack, node->right, RIGHT_CHILD_OFFSET(offset)); + } + } + + ixOsalCacheDmaFree(stack); + return gateways; +} + +/** + * @brief downloads the WiFi header conversion table to an NPE + * + * @param portID ID of the port + * + * This function prepares the WiFi header conversion tables and + * downloads them to the specified NPE port. + * + * The header conversion tables consist in the main table of + * addresses and the secondary table of gateways. AP_TO_AP records + * from the first table contain index fields into the second table + * for gateway selection. + * + * Note that this function is documented in the main component + * header file, IxEthDB.h. + * + * @return IX_ETH_DB_SUCCESS if the operation completed successfully + * or an appropriate error message otherwise + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID) +{ + IxEthDBPortMap query; + MacTreeNode *stations = NULL, *gateways = NULL, *gateway = NULL; + IxNpeMhMessage message; + PortInfo *portInfo; + IX_STATUS result; + + IX_ETH_DB_CHECK_PORT(portID); + + IX_ETH_DB_CHECK_SINGLE_NPE(portID); + + IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_WIFI_HEADER_CONVERSION); + + portInfo = &ixEthDBPortInfo[portID]; + + SET_DEPENDENCY_MAP(query, portID); + + ixEthDBUpdateLock(); + + stations = ixEthDBQuery(NULL, query, IX_ETH_DB_WIFI_RECORD, MAX_ELT_SIZE); + gateways = ixEthDBGatewaySelect(stations); + + /* clean up gw area */ + memset((void *) portInfo->updateMethod.npeGwUpdateZone, FULL_GW_BYTE_SIZE, 0); + + /* write all gateways */ + gateway = gateways; + + while (gateway != NULL) + { + ixEthDBNPEGatewayNodeWrite((void *) (((UINT32) portInfo->updateMethod.npeGwUpdateZone) + + gateway->descriptor->recordData.wifiData.gwAddressIndex * ELT_ENTRY_SIZE), + gateway); + + gateway = gateway->right; + } + + /* free the gateway tree */ + if (gateways != NULL) + { + ixEthDBFreeMacTreeNode(gateways); + } + + FILL_SETAPMACTABLE_MSG(message, + IX_OSAL_MMU_VIRT_TO_PHYS(portInfo->updateMethod.npeGwUpdateZone)); + + IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result); + + if (result == IX_SUCCESS) + { + /* update the main tree (the stations tree) */ + portInfo->updateMethod.searchTree = stations; + + result = ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_WIFI_RECORD); + } + + ixEthDBUpdateUnlock(); + + return result; +} diff --git a/drivers/net/npe/IxEthMii.c b/drivers/net/npe/IxEthMii.c new file mode 100644 index 0000000..4d92f17 --- /dev/null +++ b/drivers/net/npe/IxEthMii.c @@ -0,0 +1,497 @@ +/** + * @file IxEthMii.c + * + * @author Intel Corporation + * @date + * + * @brief MII control functions + * + * Design Notes: + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxOsal.h" + +#include "IxEthAcc.h" +#include "IxEthMii_p.h" + +#ifdef __wince +#include "IxOsPrintf.h" +#endif + +/* Array to store the phy IDs of the discovered phys */ +PRIVATE UINT32 ixEthMiiPhyId[IXP425_ETH_ACC_MII_MAX_ADDR]; + +/********************************************************* + * + * Scan for PHYs on the MII bus. This function returns + * an array of booleans, one for each PHY address. + * If a PHY is found at a particular address, the + * corresponding entry in the array is set to TRUE. + * + */ + +PUBLIC IX_STATUS +ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount) +{ + UINT32 i; + UINT16 regval, regvalId1, regvalId2; + + /*Search for PHYs on the MII*/ + /*Search for existant phys on the MDIO bus*/ + + if ((phyPresent == NULL) || + (maxPhyCount > IXP425_ETH_ACC_MII_MAX_ADDR)) + { + return IX_FAIL; + } + + /* fill the array */ + for(i=0; + i 0 && i= IX_ETH_MII_RESET_DELAY_MS) + { + ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, + IX_ETH_MII_CR_NORM_EN); + return IX_FAIL; + } + + return IX_SUCCESS; + } /* end of if(ixEthMiiPhyId) */ + else if (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_KS8995_PHY_ID) + { + /* reset bit is reserved, just reset the control register */ + ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, + IX_ETH_MII_CR_NORM_EN); + return IX_SUCCESS; + } + else + { + /* unknown PHY, set the control register reset bit, + * wait 2 s. and clear the control register. + */ + ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, + IX_ETH_MII_CR_RESET); + + ixOsalSleep (IX_ETH_MII_RESET_DELAY_MS); + + ixEthAccMiiWriteRtn(phyAddr, IX_ETH_MII_CTRL_REG, + IX_ETH_MII_CR_NORM_EN); + return IX_SUCCESS; + } /* end of if-else(ixEthMiiPhyId) */ + } /* end of if(phyAddr) */ + return IX_FAIL; +} + +/***************************************************************** + * + * Link state query functions + */ + +PUBLIC IX_STATUS +ixEthMiiLinkStatus(UINT32 phyAddr, + BOOL *linkUp, + BOOL *speed100, + BOOL *fullDuplex, + BOOL *autoneg) +{ + UINT16 ctrlRegval, statRegval, regval, regval4, regval5; + + /* check the parameters */ + if ((linkUp == NULL) || + (speed100 == NULL) || + (fullDuplex == NULL) || + (autoneg == NULL)) + { + return IX_FAIL; + } + + *linkUp = FALSE; + *speed100 = FALSE; + *fullDuplex = FALSE; + *autoneg = FALSE; + + if ((phyAddr < IXP425_ETH_ACC_MII_MAX_ADDR) && + (ixEthMiiPhyId[phyAddr] != IX_ETH_MII_INVALID_PHY_ID)) + { + if ((ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT971_PHY_ID) || + (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT972_PHY_ID) || + (ixEthMiiPhyId[phyAddr] == IX_ETH_MII_LXT9785_PHY_ID) + ) + { + /* --------------------------------------------------*/ + /* Retrieve information from PHY specific register */ + /* --------------------------------------------------*/ + if (ixEthAccMiiReadRtn(phyAddr, + IX_ETH_MII_STAT2_REG, + ®val) != IX_ETH_ACC_SUCCESS) + { + return IX_FAIL; + } + *linkUp = ((regval & IX_ETH_MII_SR2_LINK) != 0); + *speed100 = ((regval & IX_ETH_MII_SR2_100) != 0); + *fullDuplex = ((regval & IX_ETH_MII_SR2_FD) != 0); + *autoneg = ((regval & IX_ETH_MII_SR2_AUTO) != 0); + return IX_SUCCESS; + } /* end of if(ixEthMiiPhyId) */ + else + { + /* ----------------------------------------------------*/ + /* Retrieve information from status and ctrl registers */ + /* ----------------------------------------------------*/ + if (ixEthAccMiiReadRtn(phyAddr, + IX_ETH_MII_CTRL_REG, + &ctrlRegval) != IX_ETH_ACC_SUCCESS) + { + return IX_FAIL; + } + ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &statRegval); + + *linkUp = ((statRegval & IX_ETH_MII_SR_LINK_STATUS) != 0); + if (*linkUp) + { + *autoneg = ((ctrlRegval & IX_ETH_MII_CR_AUTO_EN) != 0) && + ((statRegval & IX_ETH_MII_SR_AUTO_SEL) != 0) && + ((statRegval & IX_ETH_MII_SR_AUTO_NEG) != 0); + + if (*autoneg) + { + /* mask the current stat values with the capabilities */ + ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_ADS_REG, ®val4); + ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_AN_PRTN_REG, ®val5); + /* merge the flags from the 3 registers */ + regval = (statRegval & ((regval4 & regval5) << 6)); + /* initialise from status register values */ + if ((regval & IX_ETH_MII_SR_TX_FULL_DPX) != 0) + { + /* 100 Base X full dplx */ + *speed100 = TRUE; + *fullDuplex = TRUE; + return IX_SUCCESS; + } + if ((regval & IX_ETH_MII_SR_TX_HALF_DPX) != 0) + { + /* 100 Base X half dplx */ + *speed100 = TRUE; + return IX_SUCCESS; + } + if ((regval & IX_ETH_MII_SR_10T_FULL_DPX) != 0) + { + /* 10 mb full dplx */ + *fullDuplex = TRUE; + return IX_SUCCESS; + } + if ((regval & IX_ETH_MII_SR_10T_HALF_DPX) != 0) + { + /* 10 mb half dplx */ + return IX_SUCCESS; + } + } /* end of if(autoneg) */ + else + { + /* autonegotiate not complete, return setup parameters */ + *speed100 = ((ctrlRegval & IX_ETH_MII_CR_100) != 0); + *fullDuplex = ((ctrlRegval & IX_ETH_MII_CR_FDX) != 0); + } + } /* end of if(linkUp) */ + } /* end of if-else(ixEthMiiPhyId) */ + } /* end of if(phyAddr) */ + else + { + return IX_FAIL; + } /* end of if-else(phyAddr) */ + return IX_SUCCESS; +} + +/***************************************************************** + * + * Link state display functions + */ + +PUBLIC IX_STATUS +ixEthMiiPhyShow (UINT32 phyAddr) +{ + BOOL linkUp, speed100, fullDuplex, autoneg; + UINT16 cregval; + UINT16 sregval; + + + ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_STAT_REG, &sregval); + ixEthAccMiiReadRtn(phyAddr, IX_ETH_MII_CTRL_REG, &cregval); + + /* get link information */ + if (ixEthMiiLinkStatus(phyAddr, + &linkUp, + &speed100, + &fullDuplex, + &autoneg) != IX_ETH_ACC_SUCCESS) + { + printf("PHY Status unknown\n"); + return IX_FAIL; + } + + printf("PHY ID [phyAddr]: %8.8x\n",ixEthMiiPhyId[phyAddr]); + printf( " Status reg: %4.4x\n",sregval); + printf( " control reg: %4.4x\n",cregval); + /* display link information */ + printf("PHY Status:\n"); + printf(" Link is %s\n", + (linkUp ? "Up" : "Down")); + if((sregval & IX_ETH_MII_SR_REMOTE_FAULT) != 0) + { + printf(" Remote fault detected\n"); + } + printf(" Auto Negotiation %s\n", + (autoneg ? "Completed" : "Not Completed")); + + printf("PHY Configuration:\n"); + printf(" Speed %sMb/s\n", + (speed100 ? "100" : "10")); + printf(" %s Duplex\n", + (fullDuplex ? "Full" : "Half")); + printf(" Auto Negotiation %s\n", + (autoneg ? "Enabled" : "Disabled")); + return IX_SUCCESS; +} + diff --git a/drivers/net/npe/IxFeatureCtrl.c b/drivers/net/npe/IxFeatureCtrl.c new file mode 100644 index 0000000..2e196a1 --- /dev/null +++ b/drivers/net/npe/IxFeatureCtrl.c @@ -0,0 +1,422 @@ +/** + * @file IxFeatureCtrl.c + * + * @author Intel Corporation + * @date 29-Jan-2003 + * + * @brief Feature Control Public API Implementation + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +#include "IxOsal.h" +#include "IxVersionId.h" +#include "IxFeatureCtrl.h" + +/* Macro to read from the Feature Control Register */ +#define IX_FEATURE_CTRL_READ(result) \ +do { \ +ixFeatureCtrlExpMap(); \ +(result) = IX_OSAL_READ_LONG(ixFeatureCtrlRegister); \ +} while (0) + +/* Macro to write to the Feature Control Register */ +#define IX_FEATURE_CTRL_WRITE(value) \ +do { \ +ixFeatureCtrlExpMap(); \ +IX_OSAL_WRITE_LONG(ixFeatureCtrlRegister, (value)); \ +} while (0) + +/* + * This is the offset of the feature register relative to the base of the + * Expansion Bus Controller MMR. + */ +#define IX_FEATURE_CTRL_REG_OFFSET (0x00000028) + + +/* Boolean to mark the fact that the EXP_CONFIG address space was mapped */ +PRIVATE BOOL ixFeatureCtrlExpCfgRegionMapped = FALSE; + +/* Pointer holding the virtual address of the Feature Control Register */ +PRIVATE VUINT32 *ixFeatureCtrlRegister = NULL; + +/* Place holder to store the software configuration */ +PRIVATE BOOL swConfiguration[IX_FEATURECTRL_SWCONFIG_MAX]; + +/* Flag to control swConfiguration[] is initialized once */ +PRIVATE BOOL swConfigurationFlag = FALSE ; + +/* Array containing component mask values */ +#ifdef __ixp42X +UINT32 componentMask[IX_FEATURECTRL_MAX_COMPONENTS] = { + (0x1<> IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET) + & IX_FEATURE_CTRL_DEVICE_TYPE_MASK); +} /* End function ixFeatureCtrlDeviceRead */ + + +/** + * Function definition: ixFeatureCtrlSwConfigurationCheck + */ +IX_STATUS +ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType) +{ + if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX) + { + ixOsalLog(IX_OSAL_LOG_LVL_WARNING, + IX_OSAL_LOG_DEV_STDOUT, + "FeatureCtrl: Invalid software configuraiton input.\n", + 0, 0, 0, 0, 0, 0); + + return IX_FEATURE_CTRL_SWCONFIG_DISABLED; + } + + /* The function will only initialize once. */ + ixFeatureCtrlSwConfigurationInit(); + + /* Check and return software configuration */ + return ((swConfiguration[(UINT32)swConfigType] == TRUE) ? IX_FEATURE_CTRL_SWCONFIG_ENABLED: IX_FEATURE_CTRL_SWCONFIG_DISABLED); +} + +/** + * Function definition: ixFeatureCtrlSwConfigurationWrite + */ +void +ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled) +{ + if (swConfigType >= IX_FEATURECTRL_SWCONFIG_MAX) + { + ixOsalLog(IX_OSAL_LOG_LVL_WARNING, + IX_OSAL_LOG_DEV_STDOUT, + "FeatureCtrl: Invalid software configuraiton input.\n", + 0, 0, 0, 0, 0, 0); + + return; + } + + /* The function will only initialize once. */ + ixFeatureCtrlSwConfigurationInit(); + + /* Write software configuration */ + swConfiguration[(UINT32)swConfigType]=enabled ; +} + +/** + * Function definition: ixFeatureCtrlIxp400SwVersionShow + */ +void +ixFeatureCtrlIxp400SwVersionShow (void) +{ + printf ("\nIXP400 Software Release %s %s\n\n", IX_VERSION_ID, IX_VERSION_INTERNAL_ID); + +} + +/** + * Function definition: ixFeatureCtrlSoftwareBuildGet + */ +IxFeatureCtrlBuildDevice +ixFeatureCtrlSoftwareBuildGet (void) +{ + #ifdef __ixp42X + return IX_FEATURE_CTRL_SW_BUILD_IXP42X; + #else + return IX_FEATURE_CTRL_SW_BUILD_IXP46X; + #endif +} diff --git a/drivers/net/npe/IxNpeDl.c b/drivers/net/npe/IxNpeDl.c new file mode 100644 index 0000000..3738337 --- /dev/null +++ b/drivers/net/npe/IxNpeDl.c @@ -0,0 +1,940 @@ +/** + * @file IxNpeDl.c + * + * @author Intel Corporation + * @date 08 January 2002 + * + * @brief This file contains the implementation of the public API for the + * IXP425 NPE Downloader component + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * Put the system defined include files required + */ + +/* + * Put the user defined include files required + */ +#include "IxNpeDl.h" +#include "IxNpeDlImageMgr_p.h" +#include "IxNpeDlNpeMgr_p.h" +#include "IxNpeDlMacros_p.h" +#include "IxFeatureCtrl.h" +#include "IxOsal.h" +/* + * #defines used in this file + */ + #define IMAGEID_MAJOR_NUMBER_DEFAULT 0 + #define IMAGEID_MINOR_NUMBER_DEFAULT 0 + +/* + * Typedefs whose scope is limited to this file. + */ +typedef struct +{ + BOOL validImage; + IxNpeDlImageId imageId; +} IxNpeDlNpeState; + +/* module statistics counters */ +typedef struct +{ + UINT32 attemptedDownloads; + UINT32 successfulDownloads; + UINT32 criticalFailDownloads; +} IxNpeDlStats; + +/* + * Variable declarations global to this file only. Externs are followed + * by static variables. + */ +static IxNpeDlNpeState ixNpeDlNpeState[IX_NPEDL_NPEID_MAX] = +{ + {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}}, + {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}}, + {FALSE, {IX_NPEDL_NPEID_MAX, 0, 0, 0}} +}; + +static IxNpeDlStats ixNpeDlStats; + +/* + * Software guard to prevent NPE from being started multiple times. + */ +static BOOL ixNpeDlNpeStarted[IX_NPEDL_NPEID_MAX] ={FALSE, FALSE, FALSE} ; + + +/* + * static function prototypes. + */ +PRIVATE IX_STATUS +ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary, UINT32 imageId); + +/* + * Function definition: ixNpeDlImageDownload + */ +PUBLIC IX_STATUS +ixNpeDlImageDownload (IxNpeDlImageId *imageIdPtr, + BOOL verify) +{ + UINT32 imageSize; + UINT32 *imageCodePtr = NULL; + IX_STATUS status; + IxNpeDlNpeId npeId = imageIdPtr->npeId; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlImageDownload\n"); + + ixNpeDlStats.attemptedDownloads++; + + /* Check input parameters */ + if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0)) + { + status = IX_NPEDL_PARAM_ERR; + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageDownload - invalid parameter\n"); + } + else + { + /* Ensure initialisation has been completed */ + ixNpeDlNpeMgrInit(); + + /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ + if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != + (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) + || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) + { + if (npeId == IX_NPEDL_NPEID_NPEA) + { + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) == + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does" + " not exist\n"); + return IX_SUCCESS; + } + } /* end of if(npeId) */ + else if (npeId == IX_NPEDL_NPEID_NPEB) + { + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified" + " does not exist\n"); + return IX_SUCCESS; + } + } /* end of elseif(npeId) */ + else if (npeId == IX_NPEDL_NPEID_NPEC) + { + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified" + " does not exist\n"); + return IX_SUCCESS; + } + } /* end of elseif(npeId) */ + } /* end of if(IX_FEATURE_CTRL_SILICON_TYPE_B0) */ /*End of Silicon Type Check*/ + + /* stop and reset the NPE */ + if (IX_SUCCESS != ixNpeDlNpeStopAndReset (npeId)) + { + IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n"); + return IX_FAIL; + } + + /* Locate image */ + status = ixNpeDlImageMgrImageLocate (imageIdPtr, &imageCodePtr, + &imageSize); + if (IX_SUCCESS == status) + { + /* + * If download was successful, store image Id in list of + * currently loaded images. If a critical error occured + * during download, record that the NPE has an invalid image + */ + status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr, + verify); + if (IX_SUCCESS == status) + { + ixNpeDlNpeState[npeId].imageId = *imageIdPtr; + ixNpeDlNpeState[npeId].validImage = TRUE; + ixNpeDlStats.successfulDownloads++; + + status = ixNpeDlNpeExecutionStart (npeId); + } + else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) || + (status == IX_NPEDL_CRITICAL_MICROCODE_ERR)) + { + ixNpeDlNpeState[npeId].imageId = *imageIdPtr; + ixNpeDlNpeState[npeId].validImage = FALSE; + ixNpeDlStats.criticalFailDownloads++; + } + } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */ + } /* end of if-else(npeId) */ /* condition: parameter checks ok */ + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlImageDownload : status = %d\n", status); + return status; +} + +/* + * Function definition: ixNpeDlAvailableImagesCountGet + */ +PUBLIC IX_STATUS +ixNpeDlAvailableImagesCountGet (UINT32 *numImagesPtr) +{ + IX_STATUS status; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlAvailableImagesCountGet\n"); + + /* Check input parameters */ + if (numImagesPtr == NULL) + { + status = IX_NPEDL_PARAM_ERR; + IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesCountGet - " + "invalid parameter\n"); + } + else + { + /* + * Use ImageMgr module to get no. of images listed in Image Library Header. + * If NULL is passed as imageListPtr parameter to following function, + * it will only fill number of images into numImagesPtr + */ + status = ixNpeDlImageMgrImageListExtract (NULL, numImagesPtr); + } /* end of if-else(numImagesPtr) */ + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlAvailableImagesCountGet : " + "status = %d\n", status); + return status; +} + +/* + * Function definition: ixNpeDlAvailableImagesListGet + */ +PUBLIC IX_STATUS +ixNpeDlAvailableImagesListGet (IxNpeDlImageId *imageIdListPtr, + UINT32 *listSizePtr) +{ + IX_STATUS status; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlAvailableImagesListGet\n"); + + /* Check input parameters */ + if ((imageIdListPtr == NULL) || (listSizePtr == NULL)) + { + status = IX_NPEDL_PARAM_ERR; + IX_NPEDL_ERROR_REPORT ("ixNpeDlAvailableImagesListGet - " + "invalid parameter\n"); + } + else + { + /* Call ImageMgr to get list of images listed in Image Library Header */ + status = ixNpeDlImageMgrImageListExtract (imageIdListPtr, + listSizePtr); + } /* end of if-else(imageIdListPtr) */ + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlAvailableImagesListGet : status = %d\n", + status); + return status; +} + +/* + * Function definition: ixNpeDlLoadedImageGet + */ +PUBLIC IX_STATUS +ixNpeDlLoadedImageGet (IxNpeDlNpeId npeId, + IxNpeDlImageId *imageIdPtr) +{ + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlLoadedImageGet\n"); + + /* Check input parameters */ + if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0) || (imageIdPtr == NULL)) + { + status = IX_NPEDL_PARAM_ERR; + IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageGet - invalid parameter\n"); + } + else + { + + /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ + if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != + (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) + || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) + { + if (npeId == IX_NPEDL_NPEID_NPEA && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does" + " not exist\n"); + return IX_SUCCESS; + } /* end of if(npeId) */ + + if (npeId == IX_NPEDL_NPEID_NPEB && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does" + " not exist\n"); + return IX_SUCCESS; + } /* end of if(npeId) */ + + if (npeId == IX_NPEDL_NPEID_NPEC && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does" + " not exist\n"); + return IX_SUCCESS; + } /* end of if(npeId) */ + } /* end of if not IXP42x-A0 silicon */ + + if (ixNpeDlNpeState[npeId].validImage) + { + /* use npeId to get imageId from list of currently loaded + images */ + *imageIdPtr = ixNpeDlNpeState[npeId].imageId; + } + else + { + status = IX_FAIL; + } /* end of if-else(ixNpeDlNpeState) */ + } /* end of if-else(npeId) */ + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlLoadedImageGet : status = %d\n", + status); + return status; +} + +/* + * Function definition: ixNpeDlLatestImageGet + */ +PUBLIC IX_STATUS +ixNpeDlLatestImageGet ( + IxNpeDlNpeId npeId, + IxNpeDlFunctionalityId functionalityId, + IxNpeDlImageId *imageIdPtr) +{ + IX_STATUS status; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlLatestImageGet\n"); + + /* Check input parameters */ + if ((npeId >= IX_NPEDL_NPEID_MAX) || + (npeId < 0) || + (imageIdPtr == NULL)) + { + status = IX_NPEDL_PARAM_ERR; + IX_NPEDL_ERROR_REPORT ("ixNpeDlLatestImageGet - " + "invalid parameter\n"); + } /* end of if(npeId) */ + else + { + + /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ + if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != + (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) + || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) + { + if (npeId == IX_NPEDL_NPEID_NPEA && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does" + " not exist\n"); + return IX_SUCCESS; + } /* end of if(npeId) */ + + if (npeId == IX_NPEDL_NPEID_NPEB && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified does" + " not exist\n"); + return IX_SUCCESS; + } /* end of if(npeId) */ + + if (npeId == IX_NPEDL_NPEID_NPEC && + (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC) == + IX_FEATURE_CTRL_COMPONENT_DISABLED)) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified does" + " not exist\n"); + return IX_SUCCESS; + } /* end of if(npeId) */ + } /* end of if not IXP42x-A0 silicon */ + + imageIdPtr->npeId = npeId; + imageIdPtr->functionalityId = functionalityId; + imageIdPtr->major = IMAGEID_MAJOR_NUMBER_DEFAULT; + imageIdPtr->minor = IMAGEID_MINOR_NUMBER_DEFAULT; + /* Call ImageMgr to get list of images listed in Image Library Header */ + status = ixNpeDlImageMgrLatestImageExtract(imageIdPtr); + } /* end of if-else(npeId) */ + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlLatestImageGet : status = %d\n", + status); + + return status; +} + +/* + * Function definition: ixNpeDlNpeStopAndReset + */ +PUBLIC IX_STATUS +ixNpeDlNpeStopAndReset (IxNpeDlNpeId npeId) +{ + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeStopAndReset\n"); + + /* Ensure initialisation has been completed */ + ixNpeDlNpeMgrInit(); + + /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ + if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != + (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) + || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) + { + /* + * Check whether NPE is present + */ + if (IX_NPEDL_NPEID_NPEA == npeId) + { + /* Check whether NPE A is present */ + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + /* NPE A does not present */ + IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEA does not present.\n"); + return IX_SUCCESS; + } + } /* end of if(IX_NPEDL_NPEID_NPEA) */ + else if (IX_NPEDL_NPEID_NPEB == npeId) + { + /* Check whether NPE B is present */ + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + /* NPE B does not present */ + IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEB does not present.\n"); + return IX_SUCCESS; + } + } /* end of elseif(IX_NPEDL_NPEID_NPEB) */ + else if (IX_NPEDL_NPEID_NPEC == npeId) + { + /* Check whether NPE C is present */ + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + /* NPE C does not present */ + IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeStopAndReset - Warning:NPEC does not present.\n"); + return IX_SUCCESS; + } + } /* end of elseif(IX_NPEDL_NPEID_NPEC) */ + else + { + /* Invalid NPE ID */ + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeStopAndReset - invalid Npe ID\n"); + status = IX_NPEDL_PARAM_ERR; + } /* end of if-else(IX_NPEDL_NPEID_NPEC) */ + } /* end of if not IXP42x-A0 Silicon */ + + if (status == IX_SUCCESS) + { + /* call NpeMgr function to stop the NPE */ + status = ixNpeDlNpeMgrNpeStop (npeId); + if (status == IX_SUCCESS) + { + /* call NpeMgr function to reset the NPE */ + status = ixNpeDlNpeMgrNpeReset (npeId); + } + } /* end of if(status) */ + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeStopAndReset : status = %d\n", status); + + if (IX_SUCCESS == status) + { + /* Indicate NPE has been stopped */ + ixNpeDlNpeStarted[npeId] = FALSE ; + } + + return status; +} + +/* + * Function definition: ixNpeDlNpeExecutionStart + */ +PUBLIC IX_STATUS +ixNpeDlNpeExecutionStart (IxNpeDlNpeId npeId) +{ + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeExecutionStart\n"); + + /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ + if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != + (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) + || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) + { + /* + * Check whether NPE is present + */ + if (IX_NPEDL_NPEID_NPEA == npeId) + { + /* Check whether NPE A is present */ + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + /* NPE A does not present */ + IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEA does not present.\n"); + return IX_SUCCESS; + } + } /* end of if(IX_NPEDL_NPEID_NPEA) */ + else if (IX_NPEDL_NPEID_NPEB == npeId) + { + /* Check whether NPE B is present */ + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + /* NPE B does not present */ + IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEB does not present.\n"); + return IX_SUCCESS; + } + } /* end of elseif(IX_NPEDL_NPEID_NPEB) */ + else if (IX_NPEDL_NPEID_NPEC == npeId) + { + /* Check whether NPE C is present */ + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + /* NPE C does not present */ + IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStart - Warning:NPEC does not present.\n"); + return IX_SUCCESS; + } + } /* end of elseif(IX_NPEDL_NPEID_NPEC) */ + else + { + /* Invalid NPE ID */ + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStart - invalid Npe ID\n"); + return IX_NPEDL_PARAM_ERR; + } /* end of if-else(IX_NPEDL_NPEID_NPEC) */ + } /* end of if not IXP42x-A0 Silicon */ + + if (TRUE == ixNpeDlNpeStarted[npeId]) + { + /* NPE has been started. */ + return IX_SUCCESS ; + } + + /* Ensure initialisation has been completed */ + ixNpeDlNpeMgrInit(); + + /* call NpeMgr function to start the NPE */ + status = ixNpeDlNpeMgrNpeStart (npeId); + + if (IX_SUCCESS == status) + { + /* Indicate NPE has started */ + ixNpeDlNpeStarted[npeId] = TRUE ; + } + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeExecutionStart : status = %d\n", + status); + + return status; +} + +/* + * Function definition: ixNpeDlNpeExecutionStop + */ +PUBLIC IX_STATUS +ixNpeDlNpeExecutionStop (IxNpeDlNpeId npeId) +{ + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeExecutionStop\n"); + + /* Ensure initialisation has been completed */ + ixNpeDlNpeMgrInit(); + + /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ + if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != + (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) + || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) + { + /* + * Check whether NPE is present + */ + if (IX_NPEDL_NPEID_NPEA == npeId) + { + /* Check whether NPE A is present */ + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + /* NPE A does not present */ + IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEA does not present.\n"); + return IX_SUCCESS; + } + } /* end of if(IX_NPEDL_NPEID_NPEA) */ + else if (IX_NPEDL_NPEID_NPEB == npeId) + { + /* Check whether NPE B is present */ + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + /* NPE B does not present */ + IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEB does not present.\n"); + return IX_SUCCESS; + } + } /* end of elseif(IX_NPEDL_NPEID_NPEB) */ + else if (IX_NPEDL_NPEID_NPEC == npeId) + { + /* Check whether NPE C is present */ + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + /* NPE C does not present */ + IX_NPEDL_WARNING_REPORT ("ixNpeDlNpeExecutionStop - Warning:NPEC does not present.\n"); + return IX_SUCCESS; + } + } /* end of elseif(IX_NPEDL_NPEID_NPEC) */ + else + { + /* Invalid NPE ID */ + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeExecutionStop - invalid Npe ID\n"); + status = IX_NPEDL_PARAM_ERR; + } /* end of if-else(IX_NPEDL_NPEID_NPEC) */ + } /* end of if not IXP42X-AO Silicon */ + + if (status == IX_SUCCESS) + { + /* call NpeMgr function to stop the NPE */ + status = ixNpeDlNpeMgrNpeStop (npeId); + } + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeExecutionStop : status = %d\n", + status); + + if (IX_SUCCESS == status) + { + /* Indicate NPE has been stopped */ + ixNpeDlNpeStarted[npeId] = FALSE ; + } + + return status; +} + +/* + * Function definition: ixNpeDlUnload + */ +PUBLIC IX_STATUS +ixNpeDlUnload (void) +{ + IX_STATUS status; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlUnload\n"); + + status = ixNpeDlNpeMgrUninit(); + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlUnload : status = %d\n", + status); + return status; +} + +/* + * Function definition: ixNpeDlStatsShow + */ +PUBLIC void +ixNpeDlStatsShow (void) +{ + ixOsalLog (IX_OSAL_LOG_LVL_USER, + IX_OSAL_LOG_DEV_STDOUT, + "\nixNpeDlStatsShow:\n" + "\tDownloads Attempted by user: %u\n" + "\tSuccessful Downloads: %u\n" + "\tFailed Downloads (due to Critical Error): %u\n\n", + ixNpeDlStats.attemptedDownloads, + ixNpeDlStats.successfulDownloads, + ixNpeDlStats.criticalFailDownloads, + 0,0,0); + + ixNpeDlImageMgrStatsShow (); + ixNpeDlNpeMgrStatsShow (); +} + +/* + * Function definition: ixNpeDlStatsReset + */ +PUBLIC void +ixNpeDlStatsReset (void) +{ + ixNpeDlStats.attemptedDownloads = 0; + ixNpeDlStats.successfulDownloads = 0; + ixNpeDlStats.criticalFailDownloads = 0; + + ixNpeDlImageMgrStatsReset (); + ixNpeDlNpeMgrStatsReset (); +} + +/* + * Function definition: ixNpeDlNpeInitAndStartInternal + */ +PRIVATE IX_STATUS +ixNpeDlNpeInitAndStartInternal (UINT32 *imageLibrary, + UINT32 imageId) +{ + UINT32 imageSize; + UINT32 *imageCodePtr = NULL; + IX_STATUS status; + IxNpeDlNpeId npeId = IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId); + IxFeatureCtrlDeviceId deviceId = IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId); + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeInitAndStartInternal\n"); + + ixNpeDlStats.attemptedDownloads++; + + /* Check input parameter device correctness */ + if ((deviceId >= IX_FEATURE_CTRL_DEVICE_TYPE_MAX) || + (deviceId < IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X)) + { + status = IX_NPEDL_PARAM_ERR; + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - " + "invalid parameter\n"); + } /* End valid device id checking */ + + /* Check input parameters */ + else if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0)) + { + status = IX_NPEDL_PARAM_ERR; + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - " + "invalid parameter\n"); + } + + else + { + /* Ensure initialisation has been completed */ + ixNpeDlNpeMgrInit(); + + /* Checking if image being loaded is meant for device that is running. + * Image is forward compatible. i.e Image built for IXP42X should run + * on IXP46X but not vice versa.*/ + if (deviceId > (ixFeatureCtrlDeviceRead() & IX_FEATURE_CTRL_DEVICE_TYPE_MASK)) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeInitAndStartInternal - " + "Device type mismatch. NPE Image not " + "meant for device in use \n"); + return IX_NPEDL_DEVICE_ERR; + }/* if statement - matching image device and current device */ + + /* If not IXP42X A0 stepping, proceed to check for existence of npe's */ + if ((IX_FEATURE_CTRL_SILICON_TYPE_A0 != + (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK)) + || (IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X != ixFeatureCtrlDeviceRead ())) + { + if (npeId == IX_NPEDL_NPEID_NPEA) + { + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEA) == + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE A component you specified does" + " not exist\n"); + return IX_SUCCESS; + } + } /* end of if(npeId) */ + else if (npeId == IX_NPEDL_NPEID_NPEB) + { + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEB)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE B component you specified" + " does not exist\n"); + return IX_SUCCESS; + } + } /* end of elseif(npeId) */ + else if (npeId == IX_NPEDL_NPEID_NPEC) + { + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_NPEC)== + IX_FEATURE_CTRL_COMPONENT_DISABLED) + { + IX_NPEDL_WARNING_REPORT("Warning: the NPE C component you specified" + " does not exist\n"); + return IX_SUCCESS; + } + } /* end of elseif(npeId) */ + } /* end of if not IXP42X-A0 Silicon */ + + /* stop and reset the NPE */ + status = ixNpeDlNpeStopAndReset (npeId); + if (IX_SUCCESS != status) + { + IX_NPEDL_ERROR_REPORT ("Failed to stop and reset NPE\n"); + return status; + } + + /* Locate image */ + status = ixNpeDlImageMgrImageFind (imageLibrary, imageId, + &imageCodePtr, &imageSize); + if (IX_SUCCESS == status) + { + /* + * If download was successful, store image Id in list of + * currently loaded images. If a critical error occured + * during download, record that the NPE has an invalid image + */ + status = ixNpeDlNpeMgrImageLoad (npeId, imageCodePtr, TRUE); + if (IX_SUCCESS == status) + { + ixNpeDlNpeState[npeId].validImage = TRUE; + ixNpeDlStats.successfulDownloads++; + + status = ixNpeDlNpeExecutionStart (npeId); + } + else if ((status == IX_NPEDL_CRITICAL_NPE_ERR) || + (status == IX_NPEDL_CRITICAL_MICROCODE_ERR)) + { + ixNpeDlNpeState[npeId].validImage = FALSE; + ixNpeDlStats.criticalFailDownloads++; + } + + /* NOTE - The following section of code is here to support + * a deprecated function ixNpeDlLoadedImageGet(). When that + * function is removed from the API, this code should be revised. + */ + ixNpeDlNpeState[npeId].imageId.npeId = npeId; + ixNpeDlNpeState[npeId].imageId.functionalityId = + IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId); + ixNpeDlNpeState[npeId].imageId.major = + IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId); + ixNpeDlNpeState[npeId].imageId.minor = + IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId); + } /* end of if(IX_SUCCESS) */ /* condition: image located successfully in microcode image */ + } /* end of if-else(npeId-deviceId) */ /* condition: parameter checks ok */ + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeInitAndStartInternal : " + "status = %d\n", status); + return status; +} + +/* + * Function definition: ixNpeDlCustomImageNpeInitAndStart + */ +PUBLIC IX_STATUS +ixNpeDlCustomImageNpeInitAndStart (UINT32 *imageLibrary, + UINT32 imageId) +{ + IX_STATUS status; + + if (imageLibrary == NULL) + { + status = IX_NPEDL_PARAM_ERR; + IX_NPEDL_ERROR_REPORT ("ixNpeDlCustomImageNpeInitAndStart " + "- invalid parameter\n"); + } + else + { + status = ixNpeDlNpeInitAndStartInternal (imageLibrary, imageId); + } /* end of if-else(imageLibrary) */ + + return status; +} + +/* + * Function definition: ixNpeDlNpeInitAndStart + */ +PUBLIC IX_STATUS +ixNpeDlNpeInitAndStart (UINT32 imageId) +{ + return ixNpeDlNpeInitAndStartInternal (NULL, imageId); +} + +/* + * Function definition: ixNpeDlLoadedImageFunctionalityGet + */ +PUBLIC IX_STATUS +ixNpeDlLoadedImageFunctionalityGet (IxNpeDlNpeId npeId, + UINT8 *functionalityId) +{ + /* Check input parameters */ + if ((npeId >= IX_NPEDL_NPEID_MAX) || (npeId < 0)) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet " + "- invalid parameter\n"); + return IX_NPEDL_PARAM_ERR; + } + if (functionalityId == NULL) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlLoadedImageFunctionalityGet " + "- invalid parameter\n"); + return IX_NPEDL_PARAM_ERR; + } + + if (ixNpeDlNpeState[npeId].validImage) + { + *functionalityId = ixNpeDlNpeState[npeId].imageId.functionalityId; + return IX_SUCCESS; + } + else + { + return IX_FAIL; + } +} diff --git a/drivers/net/npe/IxNpeDlImageMgr.c b/drivers/net/npe/IxNpeDlImageMgr.c new file mode 100644 index 0000000..9bcdc9c --- /dev/null +++ b/drivers/net/npe/IxNpeDlImageMgr.c @@ -0,0 +1,687 @@ +/** + * @file IxNpeDlImageMgr.c + * + * @author Intel Corporation + * @date 09 January 2002 + * + * @brief This file contains the implementation of the private API for the + * IXP425 NPE Downloader ImageMgr module + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + + +/* + * Put the system defined include files required. + */ +#include "IxOsal.h" + +/* + * Put the user defined include files required. + */ +#include "IxNpeDlImageMgr_p.h" +#include "IxNpeDlMacros_p.h" + +/* + * define the flag which toggles the firmare inclusion + */ +#define IX_NPE_MICROCODE_FIRMWARE_INCLUDED 1 +#include "IxNpeMicrocode.h" + +/* + * Indicates the start of an NPE Image, in new NPE Image Library format. + * 2 consecutive occurances indicates the end of the NPE Image Library + */ +#define NPE_IMAGE_MARKER 0xfeedf00d + +/* + * Typedefs whose scope is limited to this file. + */ + +/* + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * TO BE DEPRECATED IN A FUTURE RELEASE + */ +typedef struct +{ + UINT32 size; + UINT32 offset; + UINT32 id; +} IxNpeDlImageMgrImageEntry; + +/* + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * TO BE DEPRECATED IN A FUTURE RELEASE + */ +typedef union +{ + IxNpeDlImageMgrImageEntry image; + UINT32 eohMarker; +} IxNpeDlImageMgrHeaderEntry; + +/* + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * TO BE DEPRECATED IN A FUTURE RELEASE + */ +typedef struct +{ + UINT32 signature; + /* 1st entry in the header (there may be more than one) */ + IxNpeDlImageMgrHeaderEntry entry[1]; +} IxNpeDlImageMgrImageLibraryHeader; + + +/* + * NPE Image Header definition, used in new NPE Image Library format + */ +typedef struct +{ + UINT32 marker; + UINT32 id; + UINT32 size; +} IxNpeDlImageMgrImageHeader; + +/* module statistics counters */ +typedef struct +{ + UINT32 invalidSignature; + UINT32 imageIdListOverflow; + UINT32 imageIdNotFound; +} IxNpeDlImageMgrStats; + + +/* + * Variable declarations global to this file only. Externs are followed by + * static variables. + */ +static IxNpeDlImageMgrStats ixNpeDlImageMgrStats; + +static UINT32* getIxNpeMicroCodeImageLibrary(void) +{ + char *s; + + if ((s = getenv("npe_ucode")) != NULL) + return (UINT32*) simple_strtoul(s, NULL, 16); + else + return NULL; +} + +/* + * static function prototypes. + */ +PRIVATE BOOL +ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary); + +PRIVATE void +ixNpeDlImageMgrImageIdFormat (UINT32 rawImageId, IxNpeDlImageId *imageId); + +PRIVATE BOOL +ixNpeDlImageMgrImageIdCompare (IxNpeDlImageId *imageIdA, + IxNpeDlImageId *imageIdB); + +PRIVATE BOOL +ixNpeDlImageMgrNpeFunctionIdCompare (IxNpeDlImageId *imageIdA, + IxNpeDlImageId *imageIdB); + +#if 0 +PRIVATE IX_STATUS +ixNpeDlImageMgrImageFind_legacy (UINT32 *imageLibrary, + UINT32 imageId, + UINT32 **imagePtr, + UINT32 *imageSize); + +/* + * Function definition: ixNpeDlImageMgrMicrocodeImageLibraryOverride + * + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE + */ +IX_STATUS +ixNpeDlImageMgrMicrocodeImageLibraryOverride ( + UINT32 *clientImageLibrary) +{ + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlImageMgrMicrocodeImageLibraryOverride\n"); + + if (ixNpeDlImageMgrSignatureCheck (clientImageLibrary)) + { + IxNpeMicroCodeImageLibrary = clientImageLibrary; + } + else + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrMicrocodeImageLibraryOverride: " + "Client-supplied image has invalid signature\n"); + status = IX_FAIL; + } + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlImageMgrMicrocodeImageLibraryOverride: status = %d\n", + status); + return status; +} +#endif + +/* + * Function definition: ixNpeDlImageMgrImageListExtract + * + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE + */ +IX_STATUS +ixNpeDlImageMgrImageListExtract ( + IxNpeDlImageId *imageListPtr, + UINT32 *numImages) +{ + UINT32 rawImageId; + IxNpeDlImageId formattedImageId; + IX_STATUS status = IX_SUCCESS; + UINT32 imageCount = 0; + IxNpeDlImageMgrImageLibraryHeader *header; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlImageMgrImageListExtract\n"); + + header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary(); + + if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary())) + { + /* for each image entry in the image header ... */ + while (header->entry[imageCount].eohMarker != + IX_NPEDL_IMAGEMGR_END_OF_HEADER) + { + /* + * if the image list container from calling function has capacity, + * add the image id to the list + */ + if ((imageListPtr != NULL) && (imageCount < *numImages)) + { + rawImageId = header->entry[imageCount].image.id; + ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId); + imageListPtr[imageCount] = formattedImageId; + } + /* imageCount reflects no. of image entries in image library header */ + imageCount++; + } + + /* + * if image list container from calling function was too small to + * contain all image ids in the header, set return status to FAIL + */ + if ((imageListPtr != NULL) && (imageCount > *numImages)) + { + status = IX_FAIL; + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: " + "number of Ids found exceeds list capacity\n"); + ixNpeDlImageMgrStats.imageIdListOverflow++; + } + /* return number of image ids found in image library header */ + *numImages = imageCount; + } + else + { + status = IX_FAIL; + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageListExtract: " + "invalid signature in image\n"); + } + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlImageMgrImageListExtract: status = %d\n", + status); + return status; +} + + +/* + * Function definition: ixNpeDlImageMgrImageLocate + * + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE + */ +IX_STATUS +ixNpeDlImageMgrImageLocate ( + IxNpeDlImageId *imageId, + UINT32 **imagePtr, + UINT32 *imageSize) +{ + UINT32 imageOffset; + UINT32 rawImageId; + IxNpeDlImageId formattedImageId; + /* used to index image entries in image library header */ + UINT32 imageCount = 0; + IX_STATUS status = IX_FAIL; + IxNpeDlImageMgrImageLibraryHeader *header; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlImageMgrImageLocate\n"); + + header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary(); + + if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary())) + { + /* for each image entry in the image library header ... */ + while (header->entry[imageCount].eohMarker != + IX_NPEDL_IMAGEMGR_END_OF_HEADER) + { + rawImageId = header->entry[imageCount].image.id; + ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId); + /* if a match for imageId is found in the image library header... */ + if (ixNpeDlImageMgrImageIdCompare (imageId, &formattedImageId)) + { + /* + * get pointer to the image in the image library using offset from + * 1st word in image library + */ + UINT32 *tmp=getIxNpeMicroCodeImageLibrary(); + imageOffset = header->entry[imageCount].image.offset; + *imagePtr = &tmp[imageOffset]; + /* get the image size */ + *imageSize = header->entry[imageCount].image.size; + status = IX_SUCCESS; + break; + } + imageCount++; + } + if (status != IX_SUCCESS) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: " + "imageId not found in image library header\n"); + ixNpeDlImageMgrStats.imageIdNotFound++; + } + } + else + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageLocate: " + "invalid signature in image library\n"); + } + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlImageMgrImageLocate: status = %d\n", status); + return status; +} + +/* + * Function definition: ixNpeDlImageMgrLatestImageExtract + * + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE + */ +IX_STATUS +ixNpeDlImageMgrLatestImageExtract (IxNpeDlImageId *imageId) +{ + UINT32 imageCount = 0; + UINT32 rawImageId; + IxNpeDlImageId formattedImageId; + IX_STATUS status = IX_FAIL; + IxNpeDlImageMgrImageLibraryHeader *header; + + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlImageMgrLatestImageExtract\n"); + + header = (IxNpeDlImageMgrImageLibraryHeader *) getIxNpeMicroCodeImageLibrary(); + + if (ixNpeDlImageMgrSignatureCheck (getIxNpeMicroCodeImageLibrary())) + { + /* for each image entry in the image library header ... */ + while (header->entry[imageCount].eohMarker != + IX_NPEDL_IMAGEMGR_END_OF_HEADER) + { + rawImageId = header->entry[imageCount].image.id; + ixNpeDlImageMgrImageIdFormat (rawImageId, &formattedImageId); + /* + * if a match for the npe Id and functionality Id of the imageId is + * found in the image library header... + */ + if(ixNpeDlImageMgrNpeFunctionIdCompare(imageId, &formattedImageId)) + { + if(imageId->major <= formattedImageId.major) + { + if(imageId->minor < formattedImageId.minor) + { + imageId->minor = formattedImageId.minor; + } + imageId->major = formattedImageId.major; + } + status = IX_SUCCESS; + } + imageCount++; + } + if (status != IX_SUCCESS) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageExtract: " + "imageId not found in image library header\n"); + ixNpeDlImageMgrStats.imageIdNotFound++; + } + } + else + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrLatestImageGet: " + "invalid signature in image library\n"); + } + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlImageMgrLatestImageGet: status = %d\n", status); + return status; +} + +/* + * Function definition: ixNpeDlImageMgrSignatureCheck + * + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE + */ +PRIVATE BOOL +ixNpeDlImageMgrSignatureCheck (UINT32 *microCodeImageLibrary) +{ + IxNpeDlImageMgrImageLibraryHeader *header = + (IxNpeDlImageMgrImageLibraryHeader *) microCodeImageLibrary; + BOOL result = TRUE; + + if (!header || header->signature != IX_NPEDL_IMAGEMGR_SIGNATURE) + { + result = FALSE; + ixNpeDlImageMgrStats.invalidSignature++; + } + + return result; +} + + +/* + * Function definition: ixNpeDlImageMgrImageIdFormat + * + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE + */ +PRIVATE void +ixNpeDlImageMgrImageIdFormat ( + UINT32 rawImageId, + IxNpeDlImageId *imageId) +{ + imageId->npeId = (rawImageId >> + IX_NPEDL_IMAGEID_NPEID_OFFSET) & + IX_NPEDL_NPEIMAGE_FIELD_MASK; + imageId->functionalityId = (rawImageId >> + IX_NPEDL_IMAGEID_FUNCTIONID_OFFSET) & + IX_NPEDL_NPEIMAGE_FIELD_MASK; + imageId->major = (rawImageId >> + IX_NPEDL_IMAGEID_MAJOR_OFFSET) & + IX_NPEDL_NPEIMAGE_FIELD_MASK; + imageId->minor = (rawImageId >> + IX_NPEDL_IMAGEID_MINOR_OFFSET) & + IX_NPEDL_NPEIMAGE_FIELD_MASK; + +} + + +/* + * Function definition: ixNpeDlImageMgrImageIdCompare + * + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE + */ +PRIVATE BOOL +ixNpeDlImageMgrImageIdCompare ( + IxNpeDlImageId *imageIdA, + IxNpeDlImageId *imageIdB) +{ + if ((imageIdA->npeId == imageIdB->npeId) && + (imageIdA->functionalityId == imageIdB->functionalityId) && + (imageIdA->major == imageIdB->major) && + (imageIdA->minor == imageIdB->minor)) + { + return TRUE; + } + else + { + return FALSE; + } +} + +/* + * Function definition: ixNpeDlImageMgrNpeFunctionIdCompare + * + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE + */ +PRIVATE BOOL +ixNpeDlImageMgrNpeFunctionIdCompare ( + IxNpeDlImageId *imageIdA, + IxNpeDlImageId *imageIdB) +{ + if ((imageIdA->npeId == imageIdB->npeId) && + (imageIdA->functionalityId == imageIdB->functionalityId)) + { + return TRUE; + } + else + { + return FALSE; + } +} + + +/* + * Function definition: ixNpeDlImageMgrStatsShow + */ +void +ixNpeDlImageMgrStatsShow (void) +{ + ixOsalLog (IX_OSAL_LOG_LVL_USER, + IX_OSAL_LOG_DEV_STDOUT, + "\nixNpeDlImageMgrStatsShow:\n" + "\tInvalid Image Signatures: %u\n" + "\tImage Id List capacity too small: %u\n" + "\tImage Id not found: %u\n\n", + ixNpeDlImageMgrStats.invalidSignature, + ixNpeDlImageMgrStats.imageIdListOverflow, + ixNpeDlImageMgrStats.imageIdNotFound, + 0,0,0); +} + + +/* + * Function definition: ixNpeDlImageMgrStatsReset + */ +void +ixNpeDlImageMgrStatsReset (void) +{ + ixNpeDlImageMgrStats.invalidSignature = 0; + ixNpeDlImageMgrStats.imageIdListOverflow = 0; + ixNpeDlImageMgrStats.imageIdNotFound = 0; +} + + +#if 0 +/* + * Function definition: ixNpeDlImageMgrImageFind_legacy + * + * FOR BACKWARD-COMPATIBILITY WITH OLD NPE IMAGE LIBRARY FORMAT + * AND/OR LEGACY API FUNCTIONS. TO BE DEPRECATED IN A FUTURE RELEASE + */ +PRIVATE IX_STATUS +ixNpeDlImageMgrImageFind_legacy ( + UINT32 *imageLibrary, + UINT32 imageId, + UINT32 **imagePtr, + UINT32 *imageSize) +{ + UINT32 imageOffset; + /* used to index image entries in image library header */ + UINT32 imageCount = 0; + IX_STATUS status = IX_FAIL; + IxNpeDlImageMgrImageLibraryHeader *header; + BOOL imageFound = FALSE; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlImageMgrImageFind\n"); + + + /* If user didn't specify a library to use, use the default + * one from IxNpeMicrocode.h + */ + if (imageLibrary == NULL) + { + imageLibrary = IxNpeMicroCodeImageLibrary; + } + + if (ixNpeDlImageMgrSignatureCheck (imageLibrary)) + { + header = (IxNpeDlImageMgrImageLibraryHeader *) imageLibrary; + + /* for each image entry in the image library header ... */ + while ((header->entry[imageCount].eohMarker != + IX_NPEDL_IMAGEMGR_END_OF_HEADER) && !(imageFound)) + { + /* if a match for imageId is found in the image library header... */ + if (imageId == header->entry[imageCount].image.id) + { + /* + * get pointer to the image in the image library using offset from + * 1st word in image library + */ + imageOffset = header->entry[imageCount].image.offset; + *imagePtr = &imageLibrary[imageOffset]; + /* get the image size */ + *imageSize = header->entry[imageCount].image.size; + status = IX_SUCCESS; + imageFound = TRUE; + } + imageCount++; + } + if (status != IX_SUCCESS) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: " + "imageId not found in image library header\n"); + ixNpeDlImageMgrStats.imageIdNotFound++; + } + } + else + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: " + "invalid signature in image library\n"); + } + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlImageMgrImageFind: status = %d\n", status); + return status; +} +#endif + +/* + * Function definition: ixNpeDlImageMgrImageFind + */ +IX_STATUS +ixNpeDlImageMgrImageFind ( + UINT32 *imageLibrary, + UINT32 imageId, + UINT32 **imagePtr, + UINT32 *imageSize) +{ + IxNpeDlImageMgrImageHeader *image; + UINT32 offset = 0; + + /* If user didn't specify a library to use, use the default + * one from IxNpeMicrocode.h + */ + if (imageLibrary == NULL) + { +#ifdef IX_NPEDL_READ_MICROCODE_FROM_FILE + if (ixNpeMicrocode_binaryArray == NULL) + { + printk (KERN_ERR "ixp400.o: ERROR, no Microcode found in memory\n"); + return IX_FAIL; + } + else + { + imageLibrary = ixNpeMicrocode_binaryArray; + } +#else + imageLibrary = getIxNpeMicroCodeImageLibrary(); + if (imageLibrary == NULL) + { + printf ("npe: ERROR, no Microcode found in memory\n"); + return IX_FAIL; + } +#endif /* IX_NPEDL_READ_MICROCODE_FROM_FILE */ + } + +#if 0 + /* For backward's compatibility with previous image format */ + if (ixNpeDlImageMgrSignatureCheck(imageLibrary)) + { + return ixNpeDlImageMgrImageFind_legacy(imageLibrary, + imageId, + imagePtr, + imageSize); + } +#endif + + while (*(imageLibrary+offset) == NPE_IMAGE_MARKER) + { + image = (IxNpeDlImageMgrImageHeader *)(imageLibrary+offset); + offset += sizeof(IxNpeDlImageMgrImageHeader)/sizeof(UINT32); + + if (image->id == imageId) + { + *imagePtr = imageLibrary + offset; + *imageSize = image->size; + return IX_SUCCESS; + } + /* 2 consecutive NPE_IMAGE_MARKER's indicates end of library */ + else if (image->id == NPE_IMAGE_MARKER) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: " + "imageId not found in image library header\n"); + ixNpeDlImageMgrStats.imageIdNotFound++; + /* reached end of library, image not found */ + return IX_FAIL; + } + offset += image->size; + } + + /* If we get here, our image library may be corrupted */ + IX_NPEDL_ERROR_REPORT ("ixNpeDlImageMgrImageFind: " + "image library format may be invalid or corrupted\n"); + return IX_FAIL; +} + diff --git a/drivers/net/npe/IxNpeDlNpeMgr.c b/drivers/net/npe/IxNpeDlNpeMgr.c new file mode 100644 index 0000000..a9ea8bc --- /dev/null +++ b/drivers/net/npe/IxNpeDlNpeMgr.c @@ -0,0 +1,931 @@ +/** + * @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. + */ +#include "IxOsal.h" +#include "IxNpeDl.h" +#include "IxNpeDlNpeMgr_p.h" +#include "IxNpeDlNpeMgrUtils_p.h" +#include "IxNpeDlNpeMgrEcRegisters_p.h" +#include "IxNpeDlMacros_p.h" +#include "IxFeatureCtrl.h" + +/* + * #defines and macros used in this file. + */ +#define IX_NPEDL_BYTES_PER_WORD 4 + +/* used to read download map from version in microcode image */ +#define IX_NPEDL_BLOCK_TYPE_INSTRUCTION 0x00000000 +#define IX_NPEDL_BLOCK_TYPE_DATA 0x00000001 +#define IX_NPEDL_BLOCK_TYPE_STATE 0x00000002 +#define IX_NPEDL_END_OF_DOWNLOAD_MAP 0x0000000F + +/* + * masks used to extract address info from State information context + * register addresses as read from microcode image + */ +#define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG 0x0000000F +#define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM 0x000000F0 + +/* LSB offset of Context Number field in State-Info Context Address */ +#define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM 4 + +/* size (in words) of single State Information entry (ctxt reg address|data) */ +#define IX_NPEDL_STATE_INFO_ENTRY_SIZE 2 + + + #define IX_NPEDL_RESET_NPE_PARITY 0x0800 + #define IX_NPEDL_PARITY_BIT_MASK 0x3F00FFFF + #define IX_NPEDL_CONFIG_CTRL_REG_MASK 0x3F3FFFFF + + +/* + * Typedefs whose scope is limited to this file. + */ + +typedef struct +{ + UINT32 type; + UINT32 offset; +} IxNpeDlNpeMgrDownloadMapBlockEntry; + +typedef union +{ + IxNpeDlNpeMgrDownloadMapBlockEntry block; + UINT32 eodmMarker; +} IxNpeDlNpeMgrDownloadMapEntry; + +typedef struct +{ + /* 1st entry in the download map (there may be more than one) */ + IxNpeDlNpeMgrDownloadMapEntry entry[1]; +} IxNpeDlNpeMgrDownloadMap; + + +/* used to access an instruction or data block in a microcode image */ +typedef struct +{ + UINT32 npeMemAddress; + UINT32 size; + UINT32 data[1]; +} IxNpeDlNpeMgrCodeBlock; + +/* used to access each Context Reg entry state-information block */ +typedef struct +{ + UINT32 addressInfo; + UINT32 value; +} IxNpeDlNpeMgrStateInfoCtxtRegEntry; + +/* used to access a state-information block in a microcode image */ +typedef struct +{ + UINT32 size; + IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1]; +} IxNpeDlNpeMgrStateInfoBlock; + +/* used to store some useful NPE information for easy access */ +typedef struct +{ + UINT32 baseAddress; + UINT32 insMemSize; + UINT32 dataMemSize; +} IxNpeDlNpeInfo; + +/* used to distinguish instruction and data memory operations */ +typedef enum +{ + IX_NPEDL_MEM_TYPE_INSTRUCTION = 0, + IX_NPEDL_MEM_TYPE_DATA +} IxNpeDlNpeMemType; + +/* used to hold a reset value for a particular ECS register */ +typedef struct +{ + UINT32 regAddr; + UINT32 regResetVal; +} IxNpeDlEcsRegResetValue; + +/* prototype of function to write either Instruction or Data memory */ +typedef IX_STATUS (*IxNpeDlNpeMgrMemWrite) (UINT32 npeBaseAddress, + UINT32 npeMemAddress, + UINT32 npeMemData, + BOOL verify); + +/* module statistics counters */ +typedef struct +{ + UINT32 instructionBlocksLoaded; + UINT32 dataBlocksLoaded; + UINT32 stateInfoBlocksLoaded; + UINT32 criticalNpeErrors; + UINT32 criticalMicrocodeErrors; + UINT32 npeStarts; + UINT32 npeStops; + UINT32 npeResets; +} IxNpeDlNpeMgrStats; + + +/* + * Variable declarations global to this file only. Externs are followed by + * static variables. + */ +static IxNpeDlNpeInfo ixNpeDlNpeInfo[] = +{ + { + 0, + IX_NPEDL_INS_MEMSIZE_WORDS_NPEA, + IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA + }, + { + 0, + IX_NPEDL_INS_MEMSIZE_WORDS_NPEB, + IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB + }, + { + 0, + IX_NPEDL_INS_MEMSIZE_WORDS_NPEC, + IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC + } +}; + +/* contains Reset values for Context Store Registers */ +static UINT32 ixNpeDlCtxtRegResetValues[] = +{ + IX_NPEDL_CTXT_REG_RESET_STEVT, + IX_NPEDL_CTXT_REG_RESET_STARTPC, + IX_NPEDL_CTXT_REG_RESET_REGMAP, + IX_NPEDL_CTXT_REG_RESET_CINDEX, +}; + +/* contains Reset values for Context Store Registers */ +static IxNpeDlEcsRegResetValue ixNpeDlEcsRegResetValues[] = +{ + {IX_NPEDL_ECS_BG_CTXT_REG_0, IX_NPEDL_ECS_BG_CTXT_REG_0_RESET}, + {IX_NPEDL_ECS_BG_CTXT_REG_1, IX_NPEDL_ECS_BG_CTXT_REG_1_RESET}, + {IX_NPEDL_ECS_BG_CTXT_REG_2, IX_NPEDL_ECS_BG_CTXT_REG_2_RESET}, + {IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET}, + {IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET}, + {IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET}, + {IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET}, + {IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET}, + {IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET}, + {IX_NPEDL_ECS_DBG_CTXT_REG_0, IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET}, + {IX_NPEDL_ECS_DBG_CTXT_REG_1, IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET}, + {IX_NPEDL_ECS_DBG_CTXT_REG_2, IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET}, + {IX_NPEDL_ECS_INSTRUCT_REG, IX_NPEDL_ECS_INSTRUCT_REG_RESET} +}; + +static IxNpeDlNpeMgrStats ixNpeDlNpeMgrStats; + +/* Set when NPE register memory has been mapped */ +static BOOL ixNpeDlMemInitialised = FALSE; + + +/* + * static function prototypes. + */ +PRIVATE IX_STATUS +ixNpeDlNpeMgrMemLoad (IxNpeDlNpeId npeId, UINT32 npeBaseAddress, + IxNpeDlNpeMgrCodeBlock *codeBlockPtr, + BOOL verify, IxNpeDlNpeMemType npeMemType); +PRIVATE IX_STATUS +ixNpeDlNpeMgrStateInfoLoad (UINT32 npeBaseAddress, + IxNpeDlNpeMgrStateInfoBlock *codeBlockPtr, + BOOL verify); +PRIVATE BOOL +ixNpeDlNpeMgrBitsSetCheck (UINT32 npeBaseAddress, UINT32 regOffset, + UINT32 expectedBitsSet); + +PRIVATE UINT32 +ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId); + +/* + * Function definition: ixNpeDlNpeMgrBaseAddressGet + */ +PRIVATE UINT32 +ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId) +{ + IX_OSAL_ASSERT (ixNpeDlMemInitialised); + return ixNpeDlNpeInfo[npeId].baseAddress; +} + + +/* + * Function definition: ixNpeDlNpeMgrInit + */ +void +ixNpeDlNpeMgrInit (void) +{ + /* Only map the memory once */ + if (!ixNpeDlMemInitialised) + { + UINT32 virtAddr; + + /* map the register memory for NPE-A */ + virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEA, + IX_OSAL_IXP400_NPEA_MAP_SIZE); + IX_OSAL_ASSERT(virtAddr); + ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = virtAddr; + + /* map the register memory for NPE-B */ + virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEB, + IX_OSAL_IXP400_NPEB_MAP_SIZE); + IX_OSAL_ASSERT(virtAddr); + ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = virtAddr; + + /* map the register memory for NPE-C */ + virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEC, + IX_OSAL_IXP400_NPEC_MAP_SIZE); + IX_OSAL_ASSERT(virtAddr); + ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = virtAddr; + + ixNpeDlMemInitialised = TRUE; + } +} + + +/* + * Function definition: ixNpeDlNpeMgrUninit + */ +IX_STATUS +ixNpeDlNpeMgrUninit (void) +{ + if (!ixNpeDlMemInitialised) + { + return IX_FAIL; + } + + IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress); + IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress); + IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress); + + ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = 0; + ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = 0; + ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = 0; + + ixNpeDlMemInitialised = FALSE; + + return IX_SUCCESS; +} + +/* + * Function definition: ixNpeDlNpeMgrImageLoad + */ +IX_STATUS +ixNpeDlNpeMgrImageLoad ( + IxNpeDlNpeId npeId, + UINT32 *imageCodePtr, + BOOL verify) +{ + UINT32 npeBaseAddress; + IxNpeDlNpeMgrDownloadMap *downloadMap; + UINT32 *blockPtr; + UINT32 mapIndex = 0; + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrImageLoad\n"); + + /* get base memory address of NPE from npeId */ + npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId); + + /* check execution status of NPE to verify NPE Stop was successful */ + if (!ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, + IX_NPEDL_EXCTL_STATUS_STOP)) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageDownload - " + "NPE was not stopped before download\n"); + status = IX_FAIL; + } + else + { + /* + * Read Download Map, checking each block type and calling + * appropriate function to perform download + */ + downloadMap = (IxNpeDlNpeMgrDownloadMap *) imageCodePtr; + while ((downloadMap->entry[mapIndex].eodmMarker != + IX_NPEDL_END_OF_DOWNLOAD_MAP) + && (status == IX_SUCCESS)) + { + /* calculate pointer to block to be downloaded */ + blockPtr = imageCodePtr + + downloadMap->entry[mapIndex].block.offset; + + switch (downloadMap->entry[mapIndex].block.type) + { + case IX_NPEDL_BLOCK_TYPE_INSTRUCTION: + status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress, + (IxNpeDlNpeMgrCodeBlock *)blockPtr, + verify, + IX_NPEDL_MEM_TYPE_INSTRUCTION); + break; + case IX_NPEDL_BLOCK_TYPE_DATA: + status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress, + (IxNpeDlNpeMgrCodeBlock *)blockPtr, + verify, IX_NPEDL_MEM_TYPE_DATA); + break; + case IX_NPEDL_BLOCK_TYPE_STATE: + status = ixNpeDlNpeMgrStateInfoLoad (npeBaseAddress, + (IxNpeDlNpeMgrStateInfoBlock *) blockPtr, + verify); + break; + default: + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageLoad: " + "unknown block type in download map\n"); + status = IX_NPEDL_CRITICAL_MICROCODE_ERR; + ixNpeDlNpeMgrStats.criticalMicrocodeErrors++; + break; + } + mapIndex++; + }/* loop: for each entry in download map, while status == SUCCESS */ + }/* condition: NPE stopped before attempting download */ + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrImageLoad : status = %d\n", + status); + return status; +} + + +/* + * Function definition: ixNpeDlNpeMgrMemLoad + */ +PRIVATE IX_STATUS +ixNpeDlNpeMgrMemLoad ( + IxNpeDlNpeId npeId, + UINT32 npeBaseAddress, + IxNpeDlNpeMgrCodeBlock *blockPtr, + BOOL verify, + IxNpeDlNpeMemType npeMemType) +{ + UINT32 npeMemAddress; + UINT32 blockSize; + UINT32 memSize = 0; + IxNpeDlNpeMgrMemWrite memWriteFunc = NULL; + UINT32 localIndex = 0; + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrMemLoad\n"); + + /* + * select NPE EXCTL reg read/write commands depending on memory + * type (instruction/data) to be accessed + */ + if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION) + { + memSize = ixNpeDlNpeInfo[npeId].insMemSize; + memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrInsMemWrite; + } + else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA) + { + memSize = ixNpeDlNpeInfo[npeId].dataMemSize; + memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrDataMemWrite; + } + + /* + * NPE memory is loaded contiguously from each block, so only address + * of 1st word in block is needed + */ + npeMemAddress = blockPtr->npeMemAddress; + /* number of words of instruction/data microcode in block to download */ + blockSize = blockPtr->size; + if ((npeMemAddress + blockSize) > memSize) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: " + "Block size too big for NPE memory\n"); + status = IX_NPEDL_CRITICAL_MICROCODE_ERR; + ixNpeDlNpeMgrStats.criticalMicrocodeErrors++; + } + else + { + for (localIndex = 0; localIndex < blockSize; localIndex++) + { + status = memWriteFunc (npeBaseAddress, npeMemAddress, + blockPtr->data[localIndex], verify); + + if (status != IX_SUCCESS) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: " + "write to NPE memory failed\n"); + status = IX_NPEDL_CRITICAL_NPE_ERR; + ixNpeDlNpeMgrStats.criticalNpeErrors++; + break; /* abort download */ + } + /* increment target (word)address in NPE memory */ + npeMemAddress++; + } + }/* condition: block size will fit in NPE memory */ + + if (status == IX_SUCCESS) + { + if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION) + { + ixNpeDlNpeMgrStats.instructionBlocksLoaded++; + } + else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA) + { + ixNpeDlNpeMgrStats.dataBlocksLoaded++; + } + } + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrMemLoad : status = %d\n", status); + return status; +} + + +/* + * Function definition: ixNpeDlNpeMgrStateInfoLoad + */ +PRIVATE IX_STATUS +ixNpeDlNpeMgrStateInfoLoad ( + UINT32 npeBaseAddress, + IxNpeDlNpeMgrStateInfoBlock *blockPtr, + BOOL verify) +{ + UINT32 blockSize; + UINT32 ctxtRegAddrInfo; + UINT32 ctxtRegVal; + IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */ + UINT32 ctxtNum; /* identifies Context number (0-16) */ + UINT32 i; + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrStateInfoLoad\n"); + + /* block size contains number of words of state-info in block */ + blockSize = blockPtr->size; + + ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress); + + /* for each state-info context register entry in block */ + for (i = 0; i < (blockSize/IX_NPEDL_STATE_INFO_ENTRY_SIZE); i++) + { + /* each state-info entry is 2 words (address, value) in length */ + ctxtRegAddrInfo = (blockPtr->ctxtRegEntry[i]).addressInfo; + ctxtRegVal = (blockPtr->ctxtRegEntry[i]).value; + + ctxtReg = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_REG); + ctxtNum = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM) >> + IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM; + + /* error-check Context Register No. and Context Number values */ + /* NOTE that there is no STEVT register for Context 0 */ + if ((ctxtReg < 0) || + (ctxtReg >= IX_NPEDL_CTXT_REG_MAX) || + (ctxtNum > IX_NPEDL_CTXT_NUM_MAX) || + ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT))) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: " + "invalid Context Register Address\n"); + status = IX_NPEDL_CRITICAL_MICROCODE_ERR; + ixNpeDlNpeMgrStats.criticalMicrocodeErrors++; + break; /* abort download */ + } + + status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum, ctxtReg, + ctxtRegVal, verify); + if (status != IX_SUCCESS) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: " + "write of state-info to NPE failed\n"); + status = IX_NPEDL_CRITICAL_NPE_ERR; + ixNpeDlNpeMgrStats.criticalNpeErrors++; + break; /* abort download */ + } + }/* loop: for each context reg entry in State Info block */ + + ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress); + + if (status == IX_SUCCESS) + { + ixNpeDlNpeMgrStats.stateInfoBlocksLoaded++; + } + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrStateInfoLoad : status = %d\n", + status); + return status; +} + + +/* + * Function definition: ixNpeDlNpeMgrNpeReset + */ +IX_STATUS +ixNpeDlNpeMgrNpeReset ( + IxNpeDlNpeId npeId) +{ + UINT32 npeBaseAddress; + IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */ + UINT32 ctxtNum; /* identifies Context number (0-16) */ + UINT32 regAddr; + UINT32 regVal; + UINT32 localIndex; + UINT32 indexMax; + IX_STATUS status = IX_SUCCESS; + IxFeatureCtrlReg unitFuseReg; + UINT32 ixNpeConfigCtrlRegVal; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrNpeReset\n"); + + /* get base memory address of NPE from npeId */ + npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId); + + /* pre-store the NPE Config Control Register Value */ + IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, &ixNpeConfigCtrlRegVal); + + ixNpeConfigCtrlRegVal |= 0x3F000000; + + /* disable the parity interrupt */ + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK)); + + ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress); + + /* + * clear the FIFOs + */ + while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, + IX_NPEDL_REG_OFFSET_WFIFO, + IX_NPEDL_MASK_WFIFO_VALID)) + { + /* read from the Watch-point FIFO until empty */ + IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WFIFO, + ®Val); + } + + while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, + IX_NPEDL_REG_OFFSET_STAT, + IX_NPEDL_MASK_STAT_OFNE)) + { + /* read from the outFIFO until empty */ + IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_FIFO, + ®Val); + } + + while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, + IX_NPEDL_REG_OFFSET_STAT, + IX_NPEDL_MASK_STAT_IFNE)) + { + /* + * step execution of the NPE intruction to read inFIFO using + * the Debug Executing Context stack + */ + status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, + IX_NPEDL_INSTR_RD_FIFO, 0, 0); + + if (IX_SUCCESS != status) + { + return status; + } + + } + + /* + * Reset the mailbox reg + */ + /* ...from XScale side */ + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_MBST, + IX_NPEDL_REG_RESET_MBST); + /* ...from NPE side */ + status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, + IX_NPEDL_INSTR_RESET_MBOX, 0, 0); + + if (IX_SUCCESS != status) + { + return status; + } + + /* + * Reset the physical registers in the NPE register file: + * Note: no need to save/restore REGMAP for Context 0 here + * since all Context Store regs are reset in subsequent code + */ + for (regAddr = 0; + (regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG) && (status != IX_FAIL); + regAddr++) + { + /* for each physical register in the NPE reg file, write 0 : */ + status = ixNpeDlNpeMgrPhysicalRegWrite (npeBaseAddress, regAddr, + 0, TRUE); + if (status != IX_SUCCESS) + { + return status; /* abort reset */ + } + } + + + /* + * Reset the context store: + */ + for (ctxtNum = IX_NPEDL_CTXT_NUM_MIN; + ctxtNum <= IX_NPEDL_CTXT_NUM_MAX; ctxtNum++) + { + /* set each context's Context Store registers to reset values: */ + for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++) + { + /* NOTE that there is no STEVT register for Context 0 */ + if (!((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT))) + { + regVal = ixNpeDlCtxtRegResetValues[ctxtReg]; + status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum, + ctxtReg, regVal, TRUE); + if (status != IX_SUCCESS) + { + return status; /* abort reset */ + } + } + } + } + + ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress); + + /* write Reset values to Execution Context Stack registers */ + indexMax = sizeof (ixNpeDlEcsRegResetValues) / + sizeof (IxNpeDlEcsRegResetValue); + for (localIndex = 0; localIndex < indexMax; localIndex++) + { + regAddr = ixNpeDlEcsRegResetValues[localIndex].regAddr; + regVal = ixNpeDlEcsRegResetValues[localIndex].regResetVal; + ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, regAddr, regVal); + } + + /* clear the profile counter */ + ixNpeDlNpeMgrCommandIssue (npeBaseAddress, + IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT); + + /* clear registers EXCT, AP0, AP1, AP2 and AP3 */ + for (regAddr = IX_NPEDL_REG_OFFSET_EXCT; + regAddr <= IX_NPEDL_REG_OFFSET_AP3; + regAddr += IX_NPEDL_BYTES_PER_WORD) + { + IX_NPEDL_REG_WRITE (npeBaseAddress, regAddr, 0); + } + + /* Reset the Watch-count register */ + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, 0); + + /* + * WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation + */ + + /* + * Call the feature control API to fused out and reset the NPE and its + * coprocessor - to reset internal states and remove parity error + */ + unitFuseReg = ixFeatureCtrlRead (); + unitFuseReg |= (IX_NPEDL_RESET_NPE_PARITY << npeId); + ixFeatureCtrlWrite (unitFuseReg); + + /* call the feature control API to un-fused and un-reset the NPE & COP */ + unitFuseReg &= (~(IX_NPEDL_RESET_NPE_PARITY << npeId)); + ixFeatureCtrlWrite (unitFuseReg); + + /* + * Call NpeMgr function to stop the NPE again after the Feature Control + * has unfused and Un-Reset the NPE and its associated Coprocessors + */ + status = ixNpeDlNpeMgrNpeStop (npeId); + + /* restore NPE configuration bus Control Register - Parity Settings */ + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, + (ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK)); + + ixNpeDlNpeMgrStats.npeResets++; + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrNpeReset : status = %d\n", status); + return status; +} + + +/* + * Function definition: ixNpeDlNpeMgrNpeStart + */ +IX_STATUS +ixNpeDlNpeMgrNpeStart ( + IxNpeDlNpeId npeId) +{ + UINT32 npeBaseAddress; + UINT32 ecsRegVal; + BOOL npeRunning; + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrNpeStart\n"); + + /* get base memory address of NPE from npeId */ + npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId); + + /* + * ensure only Background Context Stack Level is Active by turning off + * the Active bit in each of the other Executing Context Stack levels + */ + ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress, + IX_NPEDL_ECS_PRI_1_CTXT_REG_0); + ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE; + ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_1_CTXT_REG_0, + ecsRegVal); + + ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress, + IX_NPEDL_ECS_PRI_2_CTXT_REG_0); + ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE; + ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_2_CTXT_REG_0, + ecsRegVal); + + ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress, + IX_NPEDL_ECS_DBG_CTXT_REG_0); + ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE; + ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0, + ecsRegVal); + + /* clear the pipeline */ + ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE); + + /* start NPE execution by issuing command through EXCTL register on NPE */ + ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_START); + + /* + * check execution status of NPE to verify NPE Start operation was + * successful + */ + npeRunning = ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, + IX_NPEDL_REG_OFFSET_EXCTL, + IX_NPEDL_EXCTL_STATUS_RUN); + if (npeRunning) + { + ixNpeDlNpeMgrStats.npeStarts++; + } + else + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStart: " + "failed to start NPE execution\n"); + status = IX_FAIL; + } + + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrNpeStart : status = %d\n", status); + return status; +} + + +/* + * Function definition: ixNpeDlNpeMgrNpeStop + */ +IX_STATUS +ixNpeDlNpeMgrNpeStop ( + IxNpeDlNpeId npeId) +{ + UINT32 npeBaseAddress; + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrNpeStop\n"); + + /* get base memory address of NPE from npeId */ + npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId); + + /* stop NPE execution by issuing command through EXCTL register on NPE */ + ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STOP); + + /* verify that NPE Stop was successful */ + if (! ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, + IX_NPEDL_EXCTL_STATUS_STOP)) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStop: " + "failed to stop NPE execution\n"); + status = IX_FAIL; + } + + ixNpeDlNpeMgrStats.npeStops++; + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrNpeStop : status = %d\n", status); + return status; +} + + +/* + * Function definition: ixNpeDlNpeMgrBitsSetCheck + */ +PRIVATE BOOL +ixNpeDlNpeMgrBitsSetCheck ( + UINT32 npeBaseAddress, + UINT32 regOffset, + UINT32 expectedBitsSet) +{ + UINT32 regVal; + IX_NPEDL_REG_READ (npeBaseAddress, regOffset, ®Val); + + return expectedBitsSet == (expectedBitsSet & regVal); +} + + +/* + * Function definition: ixNpeDlNpeMgrStatsShow + */ +void +ixNpeDlNpeMgrStatsShow (void) +{ + ixOsalLog (IX_OSAL_LOG_LVL_USER, + IX_OSAL_LOG_DEV_STDOUT, + "\nixNpeDlNpeMgrStatsShow:\n" + "\tInstruction Blocks loaded: %u\n" + "\tData Blocks loaded: %u\n" + "\tState Information Blocks loaded: %u\n" + "\tCritical NPE errors: %u\n" + "\tCritical Microcode errors: %u\n", + ixNpeDlNpeMgrStats.instructionBlocksLoaded, + ixNpeDlNpeMgrStats.dataBlocksLoaded, + ixNpeDlNpeMgrStats.stateInfoBlocksLoaded, + ixNpeDlNpeMgrStats.criticalNpeErrors, + ixNpeDlNpeMgrStats.criticalMicrocodeErrors, + 0); + + ixOsalLog (IX_OSAL_LOG_LVL_USER, + IX_OSAL_LOG_DEV_STDOUT, + "\tSuccessful NPE Starts: %u\n" + "\tSuccessful NPE Stops: %u\n" + "\tSuccessful NPE Resets: %u\n\n", + ixNpeDlNpeMgrStats.npeStarts, + ixNpeDlNpeMgrStats.npeStops, + ixNpeDlNpeMgrStats.npeResets, + 0,0,0); + + ixNpeDlNpeMgrUtilsStatsShow (); +} + + +/* + * Function definition: ixNpeDlNpeMgrStatsReset + */ +void +ixNpeDlNpeMgrStatsReset (void) +{ + ixNpeDlNpeMgrStats.instructionBlocksLoaded = 0; + ixNpeDlNpeMgrStats.dataBlocksLoaded = 0; + ixNpeDlNpeMgrStats.stateInfoBlocksLoaded = 0; + ixNpeDlNpeMgrStats.criticalNpeErrors = 0; + ixNpeDlNpeMgrStats.criticalMicrocodeErrors = 0; + ixNpeDlNpeMgrStats.npeStarts = 0; + ixNpeDlNpeMgrStats.npeStops = 0; + ixNpeDlNpeMgrStats.npeResets = 0; + + ixNpeDlNpeMgrUtilsStatsReset (); +} diff --git a/drivers/net/npe/IxNpeDlNpeMgrUtils.c b/drivers/net/npe/IxNpeDlNpeMgrUtils.c new file mode 100644 index 0000000..18cac50 --- /dev/null +++ b/drivers/net/npe/IxNpeDlNpeMgrUtils.c @@ -0,0 +1,806 @@ +/** + * @file IxNpeDlNpeMgrUtils.c + * + * @author Intel Corporation + * @date 18 February 2002 + * + * @brief This file contains the implementation of the private API for the + * IXP425 NPE Downloader NpeMgr Utils module + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + + +/* + * Put the system defined include files required. + */ +#define IX_NPE_DL_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of + * retries before + * timeout + */ + +/* + * Put the user defined include files required. + */ +#include "IxOsal.h" +#include "IxNpeDl.h" +#include "IxNpeDlNpeMgrUtils_p.h" +#include "IxNpeDlNpeMgrEcRegisters_p.h" +#include "IxNpeDlMacros_p.h" + +/* + * #defines and macros used in this file. + */ + +/* used to bit-mask a number of bytes */ +#define IX_NPEDL_MASK_LOWER_BYTE_OF_WORD 0x000000FF +#define IX_NPEDL_MASK_LOWER_SHORT_OF_WORD 0x0000FFFF +#define IX_NPEDL_MASK_FULL_WORD 0xFFFFFFFF + +#define IX_NPEDL_BYTES_PER_WORD 4 +#define IX_NPEDL_BYTES_PER_SHORT 2 + +#define IX_NPEDL_REG_SIZE_BYTE 8 +#define IX_NPEDL_REG_SIZE_SHORT 16 +#define IX_NPEDL_REG_SIZE_WORD 32 + +/* + * Introduce extra read cycles after issuing read command to NPE + * so that we read the register after the NPE has updated it + * This is to overcome race condition between XScale and NPE + */ +#define IX_NPEDL_DELAY_READ_CYCLES 2 +/* + * To mask top three MSBs of 32bit word to download into NPE IMEM + */ +#define IX_NPEDL_MASK_UNUSED_IMEM_BITS 0x1FFFFFFF; + + +/* + * typedefs + */ +typedef struct +{ + UINT32 regAddress; + UINT32 regSize; +} IxNpeDlCtxtRegAccessInfo; + +/* module statistics counters */ +typedef struct +{ + UINT32 insMemWrites; + UINT32 insMemWriteFails; + UINT32 dataMemWrites; + UINT32 dataMemWriteFails; + UINT32 ecsRegWrites; + UINT32 ecsRegReads; + UINT32 dbgInstructionExecs; + UINT32 contextRegWrites; + UINT32 physicalRegWrites; + UINT32 nextPcWrites; +} IxNpeDlNpeMgrUtilsStats; + + +/* + * Variable declarations global to this file only. Externs are followed by + * static variables. + */ + +/* + * contains useful address and function pointers to read/write Context Regs, + * eliminating some switch or if-else statements in places + */ +static IxNpeDlCtxtRegAccessInfo ixNpeDlCtxtRegAccInfo[IX_NPEDL_CTXT_REG_MAX] = +{ + { + IX_NPEDL_CTXT_REG_ADDR_STEVT, + IX_NPEDL_REG_SIZE_BYTE + }, + { + IX_NPEDL_CTXT_REG_ADDR_STARTPC, + IX_NPEDL_REG_SIZE_SHORT + }, + { + IX_NPEDL_CTXT_REG_ADDR_REGMAP, + IX_NPEDL_REG_SIZE_SHORT + }, + { + IX_NPEDL_CTXT_REG_ADDR_CINDEX, + IX_NPEDL_REG_SIZE_BYTE + } +}; + +static UINT32 ixNpeDlSavedExecCount = 0; +static UINT32 ixNpeDlSavedEcsDbgCtxtReg2 = 0; + +static IxNpeDlNpeMgrUtilsStats ixNpeDlNpeMgrUtilsStats; + + +/* + * static function prototypes. + */ +PRIVATE __inline__ void +ixNpeDlNpeMgrWriteCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, + UINT32 addr, UINT32 data); + +PRIVATE __inline__ UINT32 +ixNpeDlNpeMgrReadCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr); + +PRIVATE IX_STATUS +ixNpeDlNpeMgrLogicalRegRead (UINT32 npeBaseAddress, UINT32 regAddr, + UINT32 regSize, UINT32 ctxtNum, UINT32 *regVal); + +PRIVATE IX_STATUS +ixNpeDlNpeMgrLogicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr, + UINT32 regVal, UINT32 regSize, + UINT32 ctxtNum, BOOL verify); + +/* + * Function definition: ixNpeDlNpeMgrWriteCommandIssue + */ +PRIVATE __inline__ void +ixNpeDlNpeMgrWriteCommandIssue ( + UINT32 npeBaseAddress, + UINT32 cmd, + UINT32 addr, + UINT32 data) +{ + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, data); + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr); + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd); +} + + +/* + * Function definition: ixNpeDlNpeMgrReadCommandIssue + */ +PRIVATE __inline__ UINT32 +ixNpeDlNpeMgrReadCommandIssue ( + UINT32 npeBaseAddress, + UINT32 cmd, + UINT32 addr) +{ + UINT32 data = 0; + int i; + + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr); + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd); + for (i = 0; i <= IX_NPEDL_DELAY_READ_CYCLES; i++) + { + IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, &data); + } + + return data; +} + +/* + * Function definition: ixNpeDlNpeMgrInsMemWrite + */ +IX_STATUS +ixNpeDlNpeMgrInsMemWrite ( + UINT32 npeBaseAddress, + UINT32 insMemAddress, + UINT32 insMemData, + BOOL verify) +{ + UINT32 insMemDataRtn; + + ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress, + IX_NPEDL_EXCTL_CMD_WR_INS_MEM, + insMemAddress, insMemData); + if (verify) + { + /* write invalid data to this reg, so we can see if we're reading + the EXDATA register too early */ + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, + ~insMemData); + + /*Disabled since top 3 MSB are not used for Azusa hardware Refer WR:IXA00053900*/ + insMemData&=IX_NPEDL_MASK_UNUSED_IMEM_BITS; + + insMemDataRtn=ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress, + IX_NPEDL_EXCTL_CMD_RD_INS_MEM, + insMemAddress); + + insMemDataRtn&=IX_NPEDL_MASK_UNUSED_IMEM_BITS; + + if (insMemData != insMemDataRtn) + { + ixNpeDlNpeMgrUtilsStats.insMemWriteFails++; + return IX_FAIL; + } + } + + ixNpeDlNpeMgrUtilsStats.insMemWrites++; + return IX_SUCCESS; +} + + +/* + * Function definition: ixNpeDlNpeMgrDataMemWrite + */ +IX_STATUS +ixNpeDlNpeMgrDataMemWrite ( + UINT32 npeBaseAddress, + UINT32 dataMemAddress, + UINT32 dataMemData, + BOOL verify) +{ + ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress, + IX_NPEDL_EXCTL_CMD_WR_DATA_MEM, + dataMemAddress, dataMemData); + if (verify) + { + /* write invalid data to this reg, so we can see if we're reading + the EXDATA register too early */ + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, ~dataMemData); + + if (dataMemData != + ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress, + IX_NPEDL_EXCTL_CMD_RD_DATA_MEM, + dataMemAddress)) + { + ixNpeDlNpeMgrUtilsStats.dataMemWriteFails++; + return IX_FAIL; + } + } + + ixNpeDlNpeMgrUtilsStats.dataMemWrites++; + return IX_SUCCESS; +} + + +/* + * Function definition: ixNpeDlNpeMgrExecAccRegWrite + */ +void +ixNpeDlNpeMgrExecAccRegWrite ( + UINT32 npeBaseAddress, + UINT32 regAddress, + UINT32 regData) +{ + ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress, + IX_NPEDL_EXCTL_CMD_WR_ECS_REG, + regAddress, regData); + ixNpeDlNpeMgrUtilsStats.ecsRegWrites++; +} + + +/* + * Function definition: ixNpeDlNpeMgrExecAccRegRead + */ +UINT32 +ixNpeDlNpeMgrExecAccRegRead ( + UINT32 npeBaseAddress, + UINT32 regAddress) +{ + ixNpeDlNpeMgrUtilsStats.ecsRegReads++; + return ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress, + IX_NPEDL_EXCTL_CMD_RD_ECS_REG, + regAddress); +} + + +/* + * Function definition: ixNpeDlNpeMgrCommandIssue + */ +void +ixNpeDlNpeMgrCommandIssue ( + UINT32 npeBaseAddress, + UINT32 command) +{ + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrCommandIssue\n"); + + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, command); + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrCommandIssue\n"); +} + + +/* + * Function definition: ixNpeDlNpeMgrDebugInstructionPreExec + */ +void +ixNpeDlNpeMgrDebugInstructionPreExec( + UINT32 npeBaseAddress) +{ + /* turn off the halt bit by clearing Execution Count register. */ + /* save reg contents 1st and restore later */ + IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, + &ixNpeDlSavedExecCount); + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, 0); + + /* ensure that IF and IE are on (temporarily), so that we don't end up + * stepping forever */ + ixNpeDlSavedEcsDbgCtxtReg2 = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress, + IX_NPEDL_ECS_DBG_CTXT_REG_2); + + ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2, + (ixNpeDlSavedEcsDbgCtxtReg2 | + IX_NPEDL_MASK_ECS_DBG_REG_2_IF | + IX_NPEDL_MASK_ECS_DBG_REG_2_IE)); +} + + +/* + * Function definition: ixNpeDlNpeMgrDebugInstructionExec + */ +IX_STATUS +ixNpeDlNpeMgrDebugInstructionExec( + UINT32 npeBaseAddress, + UINT32 npeInstruction, + UINT32 ctxtNum, + UINT32 ldur) +{ + UINT32 ecsDbgRegVal; + UINT32 oldWatchcount, newWatchcount; + UINT32 retriesCount = 0; + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrDebugInstructionExec\n"); + + /* set the Active bit, and the LDUR, in the debug level */ + ecsDbgRegVal = IX_NPEDL_MASK_ECS_REG_0_ACTIVE | + (ldur << IX_NPEDL_OFFSET_ECS_REG_0_LDUR); + + ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0, + ecsDbgRegVal); + + /* + * set CCTXT at ECS DEBUG L3 to specify in which context to execute the + * instruction, and set SELCTXT at ECS DEBUG Level to specify which context + * store to access. + * Debug ECS Level Reg 1 has form 0x000n000n, where n = context number + */ + ecsDbgRegVal = (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_CCTXT) | + (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT); + + ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_1, + ecsDbgRegVal); + + /* clear the pipeline */ + ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE); + + /* load NPE instruction into the instruction register */ + ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_INSTRUCT_REG, + npeInstruction); + + /* we need this value later to wait for completion of NPE execution step */ + IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, &oldWatchcount); + + /* issue a Step One command via the Execution Control register */ + ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STEP); + + /* Watch Count register increments when NPE completes an instruction */ + IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, + &newWatchcount); + + /* + * force the XScale to wait until the NPE has finished execution step + * NOTE that this delay will be very small, just long enough to allow a + * single NPE instruction to complete execution; if instruction execution + * is not completed before timeout retries, exit the while loop + */ + while ((IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount) + && (newWatchcount == oldWatchcount)) + { + /* Watch Count register increments when NPE completes an instruction */ + IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, + &newWatchcount); + + retriesCount++; + } + + if (IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount) + { + ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs++; + } + else + { + /* Return timeout status as the instruction has not been executed + * after maximum retries */ + status = IX_NPEDL_CRITICAL_NPE_ERR; + } + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrDebugInstructionExec\n"); + + return status; +} + + +/* + * Function definition: ixNpeDlNpeMgrDebugInstructionPostExec + */ +void +ixNpeDlNpeMgrDebugInstructionPostExec( + UINT32 npeBaseAddress) +{ + /* clear active bit in debug level */ + ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0, + 0); + + /* clear the pipeline */ + ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE); + + /* restore Execution Count register contents. */ + IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, + ixNpeDlSavedExecCount); + + /* restore IF and IE bits to original values */ + ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2, + ixNpeDlSavedEcsDbgCtxtReg2); +} + + +/* + * Function definition: ixNpeDlNpeMgrLogicalRegRead + */ +PRIVATE IX_STATUS +ixNpeDlNpeMgrLogicalRegRead ( + UINT32 npeBaseAddress, + UINT32 regAddr, + UINT32 regSize, + UINT32 ctxtNum, + UINT32 *regVal) +{ + IX_STATUS status = IX_SUCCESS; + UINT32 npeInstruction = 0; + UINT32 mask = 0; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrLogicalRegRead\n"); + + switch (regSize) + { + case IX_NPEDL_REG_SIZE_BYTE: + npeInstruction = IX_NPEDL_INSTR_RD_REG_BYTE; + mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD; break; + case IX_NPEDL_REG_SIZE_SHORT: + npeInstruction = IX_NPEDL_INSTR_RD_REG_SHORT; + mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD; break; + case IX_NPEDL_REG_SIZE_WORD: + npeInstruction = IX_NPEDL_INSTR_RD_REG_WORD; + mask = IX_NPEDL_MASK_FULL_WORD; break; + } + + /* make regAddr be the SRC and DEST operands (e.g. movX d0, d0) */ + npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_SRC) | + (regAddr << IX_NPEDL_OFFSET_INSTR_DEST); + + /* step execution of NPE intruction using Debug Executing Context stack */ + status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, npeInstruction, + ctxtNum, IX_NPEDL_RD_INSTR_LDUR); + + if (IX_SUCCESS != status) + { + return status; + } + + /* read value of register from Execution Data register */ + IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, regVal); + + /* align value from left to right */ + *regVal = (*regVal >> (IX_NPEDL_REG_SIZE_WORD - regSize)) & mask; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrLogicalRegRead\n"); + + return IX_SUCCESS; +} + + +/* + * Function definition: ixNpeDlNpeMgrLogicalRegWrite + */ +PRIVATE IX_STATUS +ixNpeDlNpeMgrLogicalRegWrite ( + UINT32 npeBaseAddress, + UINT32 regAddr, + UINT32 regVal, + UINT32 regSize, + UINT32 ctxtNum, + BOOL verify) +{ + UINT32 npeInstruction = 0; + UINT32 mask = 0; + IX_STATUS status = IX_SUCCESS; + UINT32 retRegVal; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrLogicalRegWrite\n"); + + if (regSize == IX_NPEDL_REG_SIZE_WORD) + { + /* NPE register addressing is left-to-right: e.g. |d0|d1|d2|d3| */ + /* Write upper half-word (short) to |d0|d1| */ + status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr, + regVal >> IX_NPEDL_REG_SIZE_SHORT, + IX_NPEDL_REG_SIZE_SHORT, + ctxtNum, verify); + + if (IX_SUCCESS != status) + { + return status; + } + + /* Write lower half-word (short) to |d2|d3| */ + status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, + regAddr + IX_NPEDL_BYTES_PER_SHORT, + regVal & IX_NPEDL_MASK_LOWER_SHORT_OF_WORD, + IX_NPEDL_REG_SIZE_SHORT, + ctxtNum, verify); + + if (IX_SUCCESS != status) + { + return status; + } + } + else + { + switch (regSize) + { + case IX_NPEDL_REG_SIZE_BYTE: + npeInstruction = IX_NPEDL_INSTR_WR_REG_BYTE; + mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD; break; + case IX_NPEDL_REG_SIZE_SHORT: + npeInstruction = IX_NPEDL_INSTR_WR_REG_SHORT; + mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD; break; + } + /* mask out any redundant bits, so verify will work later */ + regVal &= mask; + + /* fill dest operand field of instruction with destination reg addr */ + npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_DEST); + + /* fill src operand field of instruction with least-sig 5 bits of val*/ + npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA) << + IX_NPEDL_OFFSET_INSTR_SRC); + + /* fill coprocessor field of instruction with most-sig 11 bits of val*/ + npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) << + IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA); + + /* step execution of NPE intruction using Debug ECS */ + status = ixNpeDlNpeMgrDebugInstructionExec(npeBaseAddress, npeInstruction, + ctxtNum, IX_NPEDL_WR_INSTR_LDUR); + + if (IX_SUCCESS != status) + { + return status; + } + }/* condition: if reg to be written is 8-bit or 16-bit (not 32-bit) */ + + if (verify) + { + status = ixNpeDlNpeMgrLogicalRegRead (npeBaseAddress, regAddr, + regSize, ctxtNum, &retRegVal); + + if (IX_SUCCESS == status) + { + if (regVal != retRegVal) + { + status = IX_FAIL; + } + } + } + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrLogicalRegWrite : status = %d\n", + status); + + return status; +} + + +/* + * Function definition: ixNpeDlNpeMgrPhysicalRegWrite + */ +IX_STATUS +ixNpeDlNpeMgrPhysicalRegWrite ( + UINT32 npeBaseAddress, + UINT32 regAddr, + UINT32 regValue, + BOOL verify) +{ + IX_STATUS status; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrPhysicalRegWrite\n"); + +/* + * There are 32 physical registers used in an NPE. These are + * treated as 16 pairs of 32-bit registers. To write one of the pair, + * write the pair number (0-16) to the REGMAP for Context 0. Then write + * the value to register 0 or 4 in the regfile, depending on which + * register of the pair is to be written + */ + + /* + * set REGMAP for context 0 to (regAddr >> 1) to choose which pair (0-16) + * of physical registers to write + */ + status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, + IX_NPEDL_CTXT_REG_ADDR_REGMAP, + (regAddr >> + IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP), + IX_NPEDL_REG_SIZE_SHORT, 0, verify); + if (status == IX_SUCCESS) + { + /* regAddr = 0 or 4 */ + regAddr = (regAddr & IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR) * + IX_NPEDL_BYTES_PER_WORD; + + status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr, regValue, + IX_NPEDL_REG_SIZE_WORD, 0, verify); + } + + if (status != IX_SUCCESS) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrPhysicalRegWrite: " + "error writing to physical register\n"); + } + + ixNpeDlNpeMgrUtilsStats.physicalRegWrites++; + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrPhysicalRegWrite : status = %d\n", + status); + return status; +} + + +/* + * Function definition: ixNpeDlNpeMgrCtxtRegWrite + */ +IX_STATUS +ixNpeDlNpeMgrCtxtRegWrite ( + UINT32 npeBaseAddress, + UINT32 ctxtNum, + IxNpeDlCtxtRegNum ctxtReg, + UINT32 ctxtRegVal, + BOOL verify) +{ + UINT32 tempRegVal; + UINT32 ctxtRegAddr; + UINT32 ctxtRegSize; + IX_STATUS status = IX_SUCCESS; + + IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, + "Entering ixNpeDlNpeMgrCtxtRegWrite\n"); + + /* + * Context 0 has no STARTPC. Instead, this value is used to set + * NextPC for Background ECS, to set where NPE starts executing code + */ + if ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STARTPC)) + { + /* read BG_CTXT_REG_0, update NEXTPC bits, and write back to reg */ + tempRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress, + IX_NPEDL_ECS_BG_CTXT_REG_0); + tempRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_NEXTPC; + tempRegVal |= (ctxtRegVal << IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC) & + IX_NPEDL_MASK_ECS_REG_0_NEXTPC; + + ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, + IX_NPEDL_ECS_BG_CTXT_REG_0, tempRegVal); + + ixNpeDlNpeMgrUtilsStats.nextPcWrites++; + } + else + { + ctxtRegAddr = ixNpeDlCtxtRegAccInfo[ctxtReg].regAddress; + ctxtRegSize = ixNpeDlCtxtRegAccInfo[ctxtReg].regSize; + status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, ctxtRegAddr, + ctxtRegVal, ctxtRegSize, + ctxtNum, verify); + if (status != IX_SUCCESS) + { + IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrCtxtRegWrite: " + "error writing to context store register\n"); + } + + ixNpeDlNpeMgrUtilsStats.contextRegWrites++; + } + + IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, + "Exiting ixNpeDlNpeMgrCtxtRegWrite : status = %d\n", + status); + + return status; +} + + +/* + * Function definition: ixNpeDlNpeMgrUtilsStatsShow + */ +void +ixNpeDlNpeMgrUtilsStatsShow (void) +{ + ixOsalLog (IX_OSAL_LOG_LVL_USER, + IX_OSAL_LOG_DEV_STDOUT, + "\nixNpeDlNpeMgrUtilsStatsShow:\n" + "\tInstruction Memory writes: %u\n" + "\tInstruction Memory writes failed: %u\n" + "\tData Memory writes: %u\n" + "\tData Memory writes failed: %u\n", + ixNpeDlNpeMgrUtilsStats.insMemWrites, + ixNpeDlNpeMgrUtilsStats.insMemWriteFails, + ixNpeDlNpeMgrUtilsStats.dataMemWrites, + ixNpeDlNpeMgrUtilsStats.dataMemWriteFails, + 0,0); + + ixOsalLog (IX_OSAL_LOG_LVL_USER, + IX_OSAL_LOG_DEV_STDOUT, + "\tExecuting Context Stack Register writes: %u\n" + "\tExecuting Context Stack Register reads: %u\n" + "\tPhysical Register writes: %u\n" + "\tContext Store Register writes: %u\n" + "\tExecution Backgound Context NextPC writes: %u\n" + "\tDebug Instructions Executed: %u\n\n", + ixNpeDlNpeMgrUtilsStats.ecsRegWrites, + ixNpeDlNpeMgrUtilsStats.ecsRegReads, + ixNpeDlNpeMgrUtilsStats.physicalRegWrites, + ixNpeDlNpeMgrUtilsStats.contextRegWrites, + ixNpeDlNpeMgrUtilsStats.nextPcWrites, + ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs); +} + + +/* + * Function definition: ixNpeDlNpeMgrUtilsStatsReset + */ +void +ixNpeDlNpeMgrUtilsStatsReset (void) +{ + ixNpeDlNpeMgrUtilsStats.insMemWrites = 0; + ixNpeDlNpeMgrUtilsStats.insMemWriteFails = 0; + ixNpeDlNpeMgrUtilsStats.dataMemWrites = 0; + ixNpeDlNpeMgrUtilsStats.dataMemWriteFails = 0; + ixNpeDlNpeMgrUtilsStats.ecsRegWrites = 0; + ixNpeDlNpeMgrUtilsStats.ecsRegReads = 0; + ixNpeDlNpeMgrUtilsStats.physicalRegWrites = 0; + ixNpeDlNpeMgrUtilsStats.contextRegWrites = 0; + ixNpeDlNpeMgrUtilsStats.nextPcWrites = 0; + ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs = 0; +} diff --git a/drivers/net/npe/IxNpeMh.c b/drivers/net/npe/IxNpeMh.c new file mode 100644 index 0000000..8703def --- /dev/null +++ b/drivers/net/npe/IxNpeMh.c @@ -0,0 +1,582 @@ +/** + * @file IxNpeMh.c + * + * @author Intel Corporation + * @date 18 Jan 2002 + * + * @brief This file contains the implementation of the public API for the + * IXP425 NPE Message Handler component. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * Put the system defined include files required. + */ + +/* + * Put the user defined include files required. + */ + +#include "IxOsal.h" +#include "IxNpeMhMacros_p.h" + +#include "IxNpeMh.h" + +#include "IxNpeMhConfig_p.h" +#include "IxNpeMhReceive_p.h" +#include "IxNpeMhSend_p.h" +#include "IxNpeMhSolicitedCbMgr_p.h" +#include "IxNpeMhUnsolicitedCbMgr_p.h" + +/* + * #defines and macros used in this file. + */ + +/* + * Typedefs whose scope is limited to this file. + */ + +/* + * Variable declarations global to this file only. Externs are followed by + * static variables. + */ + +PRIVATE BOOL ixNpeMhInitialized = FALSE; + +/* + * Extern function prototypes. + */ + +/* + * Static function prototypes. + */ + +/* + * Function definition: ixNpeMhInitialize + */ + +PUBLIC IX_STATUS ixNpeMhInitialize ( + IxNpeMhNpeInterrupts npeInterrupts) +{ + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhInitialize\n"); + + /* check the npeInterrupts parameter */ + if ((npeInterrupts != IX_NPEMH_NPEINTERRUPTS_NO) && + (npeInterrupts != IX_NPEMH_NPEINTERRUPTS_YES)) + { + IX_NPEMH_ERROR_REPORT ("Illegal npeInterrupts parameter value\n"); + return IX_FAIL; + } + + /* parameters are ok ... */ + + /* initialize the Receive module */ + ixNpeMhReceiveInitialize (); + + /* initialize the Solicited Callback Manager module */ + ixNpeMhSolicitedCbMgrInitialize (); + + /* initialize the Unsolicited Callback Manager module */ + ixNpeMhUnsolicitedCbMgrInitialize (); + + /* initialize the Configuration module + * + * NOTE: This module was originally configured before the + * others, but the sequence was changed so that interrupts + * would only be enabled after the handler functions were + * set up. The above modules need to be initialised to + * handle the NPE interrupts. See SCR #2231. + */ + ixNpeMhConfigInitialize (npeInterrupts); + + ixNpeMhInitialized = TRUE; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhInitialize\n"); + + return IX_SUCCESS; +} + +/* + * Function definition: ixNpeMhUnload + */ + +PUBLIC IX_STATUS ixNpeMhUnload (void) +{ + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhUnload\n"); + + if (!ixNpeMhInitialized) + { + return IX_FAIL; + } + + /* Uninitialize the Configuration module */ + ixNpeMhConfigUninit (); + + ixNpeMhInitialized = FALSE; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhUnload\n"); + + return IX_SUCCESS; +} + + +/* + * Function definition: ixNpeMhUnsolicitedCallbackRegister + */ + +PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackRegister ( + IxNpeMhNpeId npeId, + IxNpeMhMessageId messageId, + IxNpeMhCallback unsolicitedCallback) +{ + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhUnsolicitedCallbackRegister\n"); + + /* check that we are initialized */ + if (!ixNpeMhInitialized) + { + IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); + return IX_FAIL; + } + + /* check the npeId parameter */ + if (!ixNpeMhConfigNpeIdIsValid (npeId)) + { + IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); + return IX_FAIL; + } + + /* check the messageId parameter */ + if ((messageId < IX_NPEMH_MIN_MESSAGE_ID) + || (messageId > IX_NPEMH_MAX_MESSAGE_ID)) + { + IX_NPEMH_ERROR_REPORT ("Message ID is out of range\n"); + return IX_FAIL; + } + + /* the unsolicitedCallback parameter is allowed to be NULL */ + + /* parameters are ok ... */ + + /* get the lock to prevent other clients from entering */ + ixNpeMhConfigLockGet (npeId); + + /* save the unsolicited callback for the message ID */ + ixNpeMhUnsolicitedCbMgrCallbackSave ( + npeId, messageId, unsolicitedCallback); + + /* release the lock to allow other clients back in */ + ixNpeMhConfigLockRelease (npeId); + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhUnsolicitedCallbackRegister\n"); + + return IX_SUCCESS; +} + +/* + * Function definition: ixNpeMhUnsolicitedCallbackForRangeRegister + */ + +PUBLIC IX_STATUS ixNpeMhUnsolicitedCallbackForRangeRegister ( + IxNpeMhNpeId npeId, + IxNpeMhMessageId minMessageId, + IxNpeMhMessageId maxMessageId, + IxNpeMhCallback unsolicitedCallback) +{ + IxNpeMhMessageId messageId; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhUnsolicitedCallbackForRangeRegister\n"); + + /* check that we are initialized */ + if (!ixNpeMhInitialized) + { + IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); + return IX_FAIL; + } + + /* check the npeId parameter */ + if (!ixNpeMhConfigNpeIdIsValid (npeId)) + { + IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); + return IX_FAIL; + } + + /* check the minMessageId parameter */ + if ((minMessageId < IX_NPEMH_MIN_MESSAGE_ID) + || (minMessageId > IX_NPEMH_MAX_MESSAGE_ID)) + { + IX_NPEMH_ERROR_REPORT ("Min message ID is out of range\n"); + return IX_FAIL; + } + + /* check the maxMessageId parameter */ + if ((maxMessageId < IX_NPEMH_MIN_MESSAGE_ID) + || (maxMessageId > IX_NPEMH_MAX_MESSAGE_ID)) + { + IX_NPEMH_ERROR_REPORT ("Max message ID is out of range\n"); + return IX_FAIL; + } + + /* check the semantics of the message range parameters */ + if (minMessageId > maxMessageId) + { + IX_NPEMH_ERROR_REPORT ("Min message ID greater than max message " + "ID\n"); + return IX_FAIL; + } + + /* the unsolicitedCallback parameter is allowed to be NULL */ + + /* parameters are ok ... */ + + /* get the lock to prevent other clients from entering */ + ixNpeMhConfigLockGet (npeId); + + /* for each message ID in the range ... */ + for (messageId = minMessageId; messageId <= maxMessageId; messageId++) + { + /* save the unsolicited callback for the message ID */ + ixNpeMhUnsolicitedCbMgrCallbackSave ( + npeId, messageId, unsolicitedCallback); + } + + /* release the lock to allow other clients back in */ + ixNpeMhConfigLockRelease (npeId); + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhUnsolicitedCallbackForRangeRegister\n"); + + return IX_SUCCESS; +} + +/* + * Function definition: ixNpeMhMessageSend + */ + +PUBLIC IX_STATUS ixNpeMhMessageSend ( + IxNpeMhNpeId npeId, + IxNpeMhMessage message, + UINT32 maxSendRetries) +{ + IX_STATUS status = IX_SUCCESS; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhMessageSend\n"); + + /* check that we are initialized */ + if (!ixNpeMhInitialized) + { + IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); + return IX_FAIL; + } + + /* check the npeId parameter */ + if (!ixNpeMhConfigNpeIdIsValid (npeId)) + { + IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); + return IX_FAIL; + } + + /* parameters are ok ... */ + + /* get the lock to prevent other clients from entering */ + ixNpeMhConfigLockGet (npeId); + + /* send the message */ + status = ixNpeMhSendMessageSend (npeId, message, maxSendRetries); + if (status != IX_SUCCESS) + { + IX_NPEMH_ERROR_REPORT ("Failed to send message\n"); + } + + /* release the lock to allow other clients back in */ + ixNpeMhConfigLockRelease (npeId); + + IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhMessageSend" + " : status = %d\n", status); + + return status; +} + +/* + * Function definition: ixNpeMhMessageWithResponseSend + */ + +PUBLIC IX_STATUS ixNpeMhMessageWithResponseSend ( + IxNpeMhNpeId npeId, + IxNpeMhMessage message, + IxNpeMhMessageId solicitedMessageId, + IxNpeMhCallback solicitedCallback, + UINT32 maxSendRetries) +{ + IX_STATUS status = IX_SUCCESS; + IxNpeMhCallback unsolicitedCallback = NULL; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhMessageWithResponseSend\n"); + + /* check that we are initialized */ + if (!ixNpeMhInitialized) + { + IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); + return IX_FAIL; + } + + /* the solicitecCallback parameter is allowed to be NULL. this */ + /* signifies the client is not interested in the response message */ + + /* check the npeId parameter */ + if (!ixNpeMhConfigNpeIdIsValid (npeId)) + { + IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); + return IX_FAIL; + } + + /* check the solicitedMessageId parameter */ + if ((solicitedMessageId < IX_NPEMH_MIN_MESSAGE_ID) + || (solicitedMessageId > IX_NPEMH_MAX_MESSAGE_ID)) + { + IX_NPEMH_ERROR_REPORT ("Solicited message ID is out of range\n"); + return IX_FAIL; + } + + /* check the solicitedMessageId parameter. if an unsolicited */ + /* callback has been registered for the specified message ID then */ + /* report an error and return failure */ + ixNpeMhUnsolicitedCbMgrCallbackRetrieve ( + npeId, solicitedMessageId, &unsolicitedCallback); + if (unsolicitedCallback != NULL) + { + IX_NPEMH_ERROR_REPORT ("Solicited message ID conflicts with " + "unsolicited message ID\n"); + return IX_FAIL; + } + + /* parameters are ok ... */ + + /* get the lock to prevent other clients from entering */ + ixNpeMhConfigLockGet (npeId); + + /* send the message */ + status = ixNpeMhSendMessageWithResponseSend ( + npeId, message, solicitedMessageId, solicitedCallback, + maxSendRetries); + if (status != IX_SUCCESS) + { + IX_NPEMH_ERROR_REPORT ("Failed to send message\n"); + } + + /* release the lock to allow other clients back in */ + ixNpeMhConfigLockRelease (npeId); + + IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhMessageWithResponseSend" + " : status = %d\n", status); + + return status; +} + +/* + * Function definition: ixNpeMhMessagesReceive + */ + +PUBLIC IX_STATUS ixNpeMhMessagesReceive ( + IxNpeMhNpeId npeId) +{ + IX_STATUS status = IX_SUCCESS; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhMessagesReceive\n"); + + /* check that we are initialized */ + if (!ixNpeMhInitialized) + { + IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); + return IX_FAIL; + } + + /* check the npeId parameter */ + if (!ixNpeMhConfigNpeIdIsValid (npeId)) + { + IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); + return IX_FAIL; + } + + /* parameters are ok ... */ + + /* get the lock to prevent other clients from entering */ + ixNpeMhConfigLockGet (npeId); + + /* receive messages from the NPE */ + status = ixNpeMhReceiveMessagesReceive (npeId); + + if (status != IX_SUCCESS) + { + IX_NPEMH_ERROR_REPORT ("Failed to receive message\n"); + } + + /* release the lock to allow other clients back in */ + ixNpeMhConfigLockRelease (npeId); + + IX_NPEMH_TRACE1 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhMessagesReceive" + " : status = %d\n", status); + + return status; +} + +/* + * Function definition: ixNpeMhShow + */ + +PUBLIC IX_STATUS ixNpeMhShow ( + IxNpeMhNpeId npeId) +{ + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhShow\n"); + + /* check that we are initialized */ + if (!ixNpeMhInitialized) + { + IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); + return IX_FAIL; + } + + /* check the npeId parameter */ + if (!ixNpeMhConfigNpeIdIsValid (npeId)) + { + IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); + return IX_FAIL; + } + + /* parameters are ok ... */ + + /* note we don't get the lock here as printing the statistics */ + /* to a console may take some time and we don't want to impact */ + /* system performance. this means that the statistics displayed */ + /* may be in a state of flux and make not represent a consistent */ + /* snapshot. */ + + /* display a header */ + ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, + "Current state of NPE ID %d:\n\n", npeId, 0, 0, 0, 0, 0); + + /* show the current state of each module */ + + /* show the current state of the Configuration module */ + ixNpeMhConfigShow (npeId); + + /* show the current state of the Receive module */ + ixNpeMhReceiveShow (npeId); + + /* show the current state of the Send module */ + ixNpeMhSendShow (npeId); + + /* show the current state of the Solicited Callback Manager module */ + ixNpeMhSolicitedCbMgrShow (npeId); + + /* show the current state of the Unsolicited Callback Manager module */ + ixNpeMhUnsolicitedCbMgrShow (npeId); + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhShow\n"); + + return IX_SUCCESS; +} + +/* + * Function definition: ixNpeMhShowReset + */ + +PUBLIC IX_STATUS ixNpeMhShowReset ( + IxNpeMhNpeId npeId) +{ + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhShowReset\n"); + + /* check that we are initialized */ + if (!ixNpeMhInitialized) + { + IX_NPEMH_ERROR_REPORT ("IxNpeMh component is not initialized\n"); + return IX_FAIL; + } + + /* check the npeId parameter */ + if (!ixNpeMhConfigNpeIdIsValid (npeId)) + { + IX_NPEMH_ERROR_REPORT ("NPE ID invalid\n"); + return IX_FAIL; + } + + /* parameters are ok ... */ + + /* note we don't get the lock here as resetting the statistics */ + /* shouldn't impact system performance. */ + + /* reset the current state of each module */ + + /* reset the current state of the Configuration module */ + ixNpeMhConfigShowReset (npeId); + + /* reset the current state of the Receive module */ + ixNpeMhReceiveShowReset (npeId); + + /* reset the current state of the Send module */ + ixNpeMhSendShowReset (npeId); + + /* reset the current state of the Solicited Callback Manager module */ + ixNpeMhSolicitedCbMgrShowReset (npeId); + + /* reset the current state of the Unsolicited Callback Manager module */ + ixNpeMhUnsolicitedCbMgrShowReset (npeId); + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhShowReset\n"); + + return IX_SUCCESS; +} diff --git a/drivers/net/npe/IxNpeMhConfig.c b/drivers/net/npe/IxNpeMhConfig.c new file mode 100644 index 0000000..50c8f21 --- /dev/null +++ b/drivers/net/npe/IxNpeMhConfig.c @@ -0,0 +1,608 @@ +/** + * @file IxNpeMhConfig.c + * + * @author Intel Corporation + * @date 18 Jan 2002 + * + * @brief This file contains the implementation of the private API for the + * Configuration module. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * Put the system defined include files required. + */ + + +/* + * Put the user defined include files required. + */ + +#include "IxOsal.h" + +#include "IxNpeMhMacros_p.h" + +#include "IxNpeMhConfig_p.h" + +/* + * #defines and macros used in this file. + */ +#define IX_NPE_MH_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of + * retries before + * timeout + */ + +/* + * Typedefs whose scope is limited to this file. + */ + +/** + * @struct IxNpeMhConfigStats + * + * @brief This structure is used to maintain statistics for the + * Configuration module. + */ + +typedef struct +{ + UINT32 outFifoReads; /**< outFifo reads */ + UINT32 inFifoWrites; /**< inFifo writes */ + UINT32 maxInFifoFullRetries; /**< max retries if inFIFO full */ + UINT32 maxOutFifoEmptyRetries; /**< max retries if outFIFO empty */ +} IxNpeMhConfigStats; + +/* + * Variable declarations global to this file only. Externs are followed by + * static variables. + */ + +IxNpeMhConfigNpeInfo ixNpeMhConfigNpeInfo[IX_NPEMH_NUM_NPES] = +{ + { + 0, + IX_NPEMH_NPEA_INT, + 0, + 0, + 0, + 0, + 0, + NULL, + FALSE + }, + { + 0, + IX_NPEMH_NPEB_INT, + 0, + 0, + 0, + 0, + 0, + NULL, + FALSE + }, + { + 0, + IX_NPEMH_NPEC_INT, + 0, + 0, + 0, + 0, + 0, + NULL, + FALSE + } +}; + +PRIVATE IxNpeMhConfigStats ixNpeMhConfigStats[IX_NPEMH_NUM_NPES]; + +/* + * Extern function prototypes. + */ + +/* + * Static function prototypes. + */ +PRIVATE +void ixNpeMhConfigIsr (void *parameter); + +/* + * Function definition: ixNpeMhConfigIsr + */ + +PRIVATE +void ixNpeMhConfigIsr (void *parameter) +{ + IxNpeMhNpeId npeId = (IxNpeMhNpeId)parameter; + UINT32 ofint; + volatile UINT32 *statusReg = + (UINT32 *)ixNpeMhConfigNpeInfo[npeId].statusRegister; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhConfigIsr\n"); + + /* get the OFINT (OutFifo interrupt) bit of the status register */ + IX_NPEMH_REGISTER_READ_BITS (statusReg, &ofint, IX_NPEMH_NPE_STAT_OFINT); + + /* if the OFINT status bit is set */ + if (ofint) + { + /* if there is an ISR registered for this NPE */ + if (ixNpeMhConfigNpeInfo[npeId].isr != NULL) + { + /* invoke the ISR routine */ + ixNpeMhConfigNpeInfo[npeId].isr (npeId); + } + else + { + /* if we don't service the interrupt the NPE will continue */ + /* to trigger the interrupt indefinitely */ + IX_NPEMH_ERROR_REPORT ("No ISR registered to service " + "interrupt\n"); + } + } + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhConfigIsr\n"); +} + +/* + * Function definition: ixNpeMhConfigInitialize + */ + +void ixNpeMhConfigInitialize ( + IxNpeMhNpeInterrupts npeInterrupts) +{ + IxNpeMhNpeId npeId; + UINT32 virtualAddr[IX_NPEMH_NUM_NPES]; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhConfigInitialize\n"); + + /* Request a mapping for the NPE-A config register address space */ + virtualAddr[IX_NPEMH_NPEID_NPEA] = + (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEA_BASE, + IX_OSAL_IXP400_NPEA_MAP_SIZE); + IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEA]); + + /* Request a mapping for the NPE-B config register address space */ + virtualAddr[IX_NPEMH_NPEID_NPEB] = + (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEB_BASE, + IX_OSAL_IXP400_NPEB_MAP_SIZE); + IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEB]); + + /* Request a mapping for the NPE-C config register address space */ + virtualAddr[IX_NPEMH_NPEID_NPEC] = + (UINT32) IX_OSAL_MEM_MAP (IX_NPEMH_NPEC_BASE, + IX_OSAL_IXP400_NPEC_MAP_SIZE); + IX_OSAL_ASSERT (virtualAddr[IX_NPEMH_NPEID_NPEC]); + + /* for each NPE ... */ + for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) + { + /* declare a convenience pointer */ + IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId]; + + /* store the virtual addresses of the NPE registers for later use */ + npeInfo->virtualRegisterBase = virtualAddr[npeId]; + npeInfo->statusRegister = virtualAddr[npeId] + IX_NPEMH_NPESTAT_OFFSET; + npeInfo->controlRegister = virtualAddr[npeId] + IX_NPEMH_NPECTL_OFFSET; + npeInfo->inFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET; + npeInfo->outFifoRegister = virtualAddr[npeId] + IX_NPEMH_NPEFIFO_OFFSET; + + /* for test purposes - to verify the register addresses */ + IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d status register = " + "0x%08X\n", npeId, npeInfo->statusRegister); + IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d control register = " + "0x%08X\n", npeId, npeInfo->controlRegister); + IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d inFifo register = " + "0x%08X\n", npeId, npeInfo->inFifoRegister); + IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NPE %d outFifo register = " + "0x%08X\n", npeId, npeInfo->outFifoRegister); + + /* connect our ISR to the NPE interrupt */ + (void) ixOsalIrqBind ( + npeInfo->interruptId, ixNpeMhConfigIsr, (void *)npeId); + + /* initialise a mutex for this NPE */ + (void) ixOsalMutexInit (&npeInfo->mutex); + + /* if we should service the NPE's "outFIFO not empty" interrupt */ + if (npeInterrupts == IX_NPEMH_NPEINTERRUPTS_YES) + { + /* enable the NPE's "outFIFO not empty" interrupt */ + ixNpeMhConfigNpeInterruptEnable (npeId); + } + else + { + /* disable the NPE's "outFIFO not empty" interrupt */ + ixNpeMhConfigNpeInterruptDisable (npeId); + } + } + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhConfigInitialize\n"); +} + +/* + * Function definition: ixNpeMhConfigUninit + */ + +void ixNpeMhConfigUninit (void) +{ + IxNpeMhNpeId npeId; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhConfigUninit\n"); + + /* for each NPE ... */ + for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) + { + /* declare a convenience pointer */ + IxNpeMhConfigNpeInfo *npeInfo = &ixNpeMhConfigNpeInfo[npeId]; + + /* disconnect ISR */ + ixOsalIrqUnbind(npeInfo->interruptId); + + /* destroy mutex associated with this NPE */ + ixOsalMutexDestroy(&npeInfo->mutex); + + IX_OSAL_MEM_UNMAP (npeInfo->virtualRegisterBase); + + npeInfo->virtualRegisterBase = 0; + npeInfo->statusRegister = 0; + npeInfo->controlRegister = 0; + npeInfo->inFifoRegister = 0; + npeInfo->outFifoRegister = 0; + } + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhConfigUninit\n"); +} + +/* + * Function definition: ixNpeMhConfigIsrRegister + */ + +void ixNpeMhConfigIsrRegister ( + IxNpeMhNpeId npeId, + IxNpeMhConfigIsr isr) +{ + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhConfigIsrRegister\n"); + + /* check if there is already an ISR registered for this NPE */ + if (ixNpeMhConfigNpeInfo[npeId].isr != NULL) + { + IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Over-writing registered NPE ISR\n"); + } + + /* save the ISR routine with the NPE info */ + ixNpeMhConfigNpeInfo[npeId].isr = isr; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhConfigIsrRegister\n"); +} + +/* + * Function definition: ixNpeMhConfigNpeInterruptEnable + */ + +BOOL ixNpeMhConfigNpeInterruptEnable ( + IxNpeMhNpeId npeId) +{ + UINT32 ofe; + volatile UINT32 *controlReg = + (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister; + + /* get the OFE (OutFifoEnable) bit of the control register */ + IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE); + + /* if the interrupt is disabled then we must enable it */ + if (!ofe) + { + /* set the OFE (OutFifoEnable) bit of the control register */ + /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */ + /* time for the write to have effect */ + IX_NPEMH_REGISTER_WRITE_BITS (controlReg, + (IX_NPEMH_NPE_CTL_OFE | + IX_NPEMH_NPE_CTL_OFEWE), + (IX_NPEMH_NPE_CTL_OFE | + IX_NPEMH_NPE_CTL_OFEWE)); + } + + /* return the previous state of the interrupt */ + return (ofe != 0); +} + +/* + * Function definition: ixNpeMhConfigNpeInterruptDisable + */ + +BOOL ixNpeMhConfigNpeInterruptDisable ( + IxNpeMhNpeId npeId) +{ + UINT32 ofe; + volatile UINT32 *controlReg = + (UINT32 *)ixNpeMhConfigNpeInfo[npeId].controlRegister; + + /* get the OFE (OutFifoEnable) bit of the control register */ + IX_NPEMH_REGISTER_READ_BITS (controlReg, &ofe, IX_NPEMH_NPE_CTL_OFE); + + /* if the interrupt is enabled then we must disable it */ + if (ofe) + { + /* unset the OFE (OutFifoEnable) bit of the control register */ + /* we must set the OFEWE (OutFifoEnableWriteEnable) at the same */ + /* time for the write to have effect */ + IX_NPEMH_REGISTER_WRITE_BITS (controlReg, + (0 | + IX_NPEMH_NPE_CTL_OFEWE), + (IX_NPEMH_NPE_CTL_OFE | + IX_NPEMH_NPE_CTL_OFEWE)); + } + + /* return the previous state of the interrupt */ + return (ofe != 0); +} + +/* + * Function definition: ixNpeMhConfigMessageIdGet + */ + +IxNpeMhMessageId ixNpeMhConfigMessageIdGet ( + IxNpeMhMessage message) +{ + /* return the most-significant byte of the first word of the */ + /* message */ + return ((IxNpeMhMessageId) ((message.data[0] >> 24) & 0xFF)); +} + +/* + * Function definition: ixNpeMhConfigNpeIdIsValid + */ + +BOOL ixNpeMhConfigNpeIdIsValid ( + IxNpeMhNpeId npeId) +{ + /* check that the npeId parameter is within the range of valid IDs */ + return (npeId >= 0 && npeId < IX_NPEMH_NUM_NPES); +} + +/* + * Function definition: ixNpeMhConfigLockGet + */ + +void ixNpeMhConfigLockGet ( + IxNpeMhNpeId npeId) +{ + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhConfigLockGet\n"); + + /* lock the mutex for this NPE */ + (void) ixOsalMutexLock (&ixNpeMhConfigNpeInfo[npeId].mutex, + IX_OSAL_WAIT_FOREVER); + + /* disable the NPE's "outFIFO not empty" interrupt */ + ixNpeMhConfigNpeInfo[npeId].oldInterruptState = + ixNpeMhConfigNpeInterruptDisable (npeId); + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhConfigLockGet\n"); +} + +/* + * Function definition: ixNpeMhConfigLockRelease + */ + +void ixNpeMhConfigLockRelease ( + IxNpeMhNpeId npeId) +{ + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhConfigLockRelease\n"); + + /* if the interrupt was previously enabled */ + if (ixNpeMhConfigNpeInfo[npeId].oldInterruptState) + { + /* enable the NPE's "outFIFO not empty" interrupt */ + ixNpeMhConfigNpeInfo[npeId].oldInterruptState = + ixNpeMhConfigNpeInterruptEnable (npeId); + } + + /* unlock the mutex for this NPE */ + (void) ixOsalMutexUnlock (&ixNpeMhConfigNpeInfo[npeId].mutex); + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhConfigLockRelease\n"); +} + +/* + * Function definition: ixNpeMhConfigInFifoWrite + */ + +IX_STATUS ixNpeMhConfigInFifoWrite ( + IxNpeMhNpeId npeId, + IxNpeMhMessage message) +{ + volatile UINT32 *npeInFifo = + (UINT32 *)ixNpeMhConfigNpeInfo[npeId].inFifoRegister; + UINT32 retriesCount = 0; + + /* write the first word of the message to the NPE's inFIFO */ + IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[0]); + + /* need to wait for room to write second word - see SCR #493, + poll for maximum number of retries, if exceed maximum + retries, exit from while loop */ + while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount) + && ixNpeMhConfigInFifoIsFull (npeId)) + { + retriesCount++; + } + + /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */ + if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount) + { + return IX_NPEMH_CRITICAL_NPE_ERR; + } + + /* write the second word of the message to the NPE's inFIFO */ + IX_NPEMH_REGISTER_WRITE (npeInFifo, message.data[1]); + + /* record in the stats the maximum number of retries needed */ + if (ixNpeMhConfigStats[npeId].maxInFifoFullRetries < retriesCount) + { + ixNpeMhConfigStats[npeId].maxInFifoFullRetries = retriesCount; + } + + /* update statistical info */ + ixNpeMhConfigStats[npeId].inFifoWrites++; + + return IX_SUCCESS; +} + +/* + * Function definition: ixNpeMhConfigOutFifoRead + */ + +IX_STATUS ixNpeMhConfigOutFifoRead ( + IxNpeMhNpeId npeId, + IxNpeMhMessage *message) +{ + volatile UINT32 *npeOutFifo = + (UINT32 *)ixNpeMhConfigNpeInfo[npeId].outFifoRegister; + UINT32 retriesCount = 0; + + /* read the first word of the message from the NPE's outFIFO */ + IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[0]); + + /* need to wait for NPE to write second word - see SCR #493 + poll for maximum number of retries, if exceed maximum + retries, exit from while loop */ + while ((IX_NPE_MH_MAX_NUM_OF_RETRIES > retriesCount) + && ixNpeMhConfigOutFifoIsEmpty (npeId)) + { + retriesCount++; + } + + /* Return TIMEOUT status to caller, indicate that NPE Hang / Halt */ + if (IX_NPE_MH_MAX_NUM_OF_RETRIES == retriesCount) + { + return IX_NPEMH_CRITICAL_NPE_ERR; + } + + /* read the second word of the message from the NPE's outFIFO */ + IX_NPEMH_REGISTER_READ (npeOutFifo, &message->data[1]); + + /* record in the stats the maximum number of retries needed */ + if (ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries < retriesCount) + { + ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = retriesCount; + } + + /* update statistical info */ + ixNpeMhConfigStats[npeId].outFifoReads++; + + return IX_SUCCESS; +} + +/* + * Function definition: ixNpeMhConfigShow + */ + +void ixNpeMhConfigShow ( + IxNpeMhNpeId npeId) +{ + /* show the message fifo read counter */ + IX_NPEMH_SHOW ("Message FIFO reads", + ixNpeMhConfigStats[npeId].outFifoReads); + + /* show the message fifo write counter */ + IX_NPEMH_SHOW ("Message FIFO writes", + ixNpeMhConfigStats[npeId].inFifoWrites); + + /* show the max retries performed when inFIFO full */ + IX_NPEMH_SHOW ("Max inFIFO Full retries", + ixNpeMhConfigStats[npeId].maxInFifoFullRetries); + + /* show the max retries performed when outFIFO empty */ + IX_NPEMH_SHOW ("Max outFIFO Empty retries", + ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries); + + /* show the current status of the inFifo */ + ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, + "InFifo is %s and %s\n", + (ixNpeMhConfigInFifoIsEmpty (npeId) ? + (int) "EMPTY" : (int) "NOT EMPTY"), + (ixNpeMhConfigInFifoIsFull (npeId) ? + (int) "FULL" : (int) "NOT FULL"), + 0, 0, 0, 0); + + /* show the current status of the outFifo */ + ixOsalLog (IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, + "OutFifo is %s and %s\n", + (ixNpeMhConfigOutFifoIsEmpty (npeId) ? + (int) "EMPTY" : (int) "NOT EMPTY"), + (ixNpeMhConfigOutFifoIsFull (npeId) ? + (int) "FULL" : (int) "NOT FULL"), + 0, 0, 0, 0); +} + +/* + * Function definition: ixNpeMhConfigShowReset + */ + +void ixNpeMhConfigShowReset ( + IxNpeMhNpeId npeId) +{ + /* reset the message fifo read counter */ + ixNpeMhConfigStats[npeId].outFifoReads = 0; + + /* reset the message fifo write counter */ + ixNpeMhConfigStats[npeId].inFifoWrites = 0; + + /* reset the max inFIFO Full retries counter */ + ixNpeMhConfigStats[npeId].maxInFifoFullRetries = 0; + + /* reset the max outFIFO empty retries counter */ + ixNpeMhConfigStats[npeId].maxOutFifoEmptyRetries = 0; +} + + diff --git a/drivers/net/npe/IxNpeMhReceive.c b/drivers/net/npe/IxNpeMhReceive.c new file mode 100644 index 0000000..57c8be3 --- /dev/null +++ b/drivers/net/npe/IxNpeMhReceive.c @@ -0,0 +1,320 @@ +/** + * @file IxNpeMhReceive.c + * + * @author Intel Corporation + * @date 18 Jan 2002 + * + * @brief This file contains the implementation of the private API for the + * Receive module. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * Put the system defined include files required. + */ + + +/* + * Put the user defined include files required. + */ +#include "IxOsal.h" +#include "IxNpeMhMacros_p.h" +#include "IxNpeMhConfig_p.h" +#include "IxNpeMhReceive_p.h" +#include "IxNpeMhSolicitedCbMgr_p.h" +#include "IxNpeMhUnsolicitedCbMgr_p.h" + +/* + * #defines and macros used in this file. + */ + +/* + * Typedefs whose scope is limited to this file. + */ + +/** + * @struct IxNpeMhReceiveStats + * + * @brief This structure is used to maintain statistics for the Receive + * module. + */ + +typedef struct +{ + UINT32 isrs; /**< receive ISR invocations */ + UINT32 receives; /**< receive messages invocations */ + UINT32 messages; /**< messages received */ + UINT32 solicited; /**< solicited messages received */ + UINT32 unsolicited; /**< unsolicited messages received */ + UINT32 callbacks; /**< callbacks invoked */ +} IxNpeMhReceiveStats; + +/* + * Variable declarations global to this file only. Externs are followed by + * static variables. + */ + +PRIVATE IxNpeMhReceiveStats ixNpeMhReceiveStats[IX_NPEMH_NUM_NPES]; + +/* + * Extern function prototypes. + */ + +/* + * Static function prototypes. + */ +PRIVATE +void ixNpeMhReceiveIsr (int npeId); + +PRIVATE +void ixNpeMhReceiveIsr (int npeId) +{ + int lockKey; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhReceiveIsr\n"); + + lockKey = ixOsalIrqLock (); + + /* invoke the message receive routine to get messages from the NPE */ + ixNpeMhReceiveMessagesReceive (npeId); + + /* update statistical info */ + ixNpeMhReceiveStats[npeId].isrs++; + + ixOsalIrqUnlock (lockKey); + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhReceiveIsr\n"); +} + +/* + * Function definition: ixNpeMhReceiveInitialize + */ + +void ixNpeMhReceiveInitialize (void) +{ + IxNpeMhNpeId npeId = 0; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhReceiveInitialize\n"); + + /* for each NPE ... */ + for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) + { + /* register our internal ISR for the NPE to handle "outFIFO not */ + /* empty" interrupts */ + ixNpeMhConfigIsrRegister (npeId, ixNpeMhReceiveIsr); + } + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhReceiveInitialize\n"); +} + +/* + * Function definition: ixNpeMhReceiveMessagesReceive + */ + +IX_STATUS ixNpeMhReceiveMessagesReceive ( + IxNpeMhNpeId npeId) +{ + IxNpeMhMessage message = { { 0, 0 } }; + IxNpeMhMessageId messageId = 0; + IxNpeMhCallback callback = NULL; + IX_STATUS status; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhReceiveMessagesReceive\n"); + + /* update statistical info */ + ixNpeMhReceiveStats[npeId].receives++; + + /* while the NPE has messages in its outFIFO */ + while (!ixNpeMhConfigOutFifoIsEmpty (npeId)) + { + /* read a message from the NPE's outFIFO */ + status = ixNpeMhConfigOutFifoRead (npeId, &message); + + if (IX_SUCCESS != status) + { + return status; + } + + /* get the ID of the message */ + messageId = ixNpeMhConfigMessageIdGet (message); + + IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, + "Received message from NPE %d with ID 0x%02X\n", + npeId, messageId); + + /* update statistical info */ + ixNpeMhReceiveStats[npeId].messages++; + + /* try to find a matching unsolicited callback for this message. */ + + /* we assume the message is unsolicited. only if there is no */ + /* unsolicited callback for this message type do we assume the */ + /* message is solicited. it is much faster to check for an */ + /* unsolicited callback, so doing this check first should result */ + /* in better performance. */ + + ixNpeMhUnsolicitedCbMgrCallbackRetrieve ( + npeId, messageId, &callback); + + if (callback != NULL) + { + IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, + "Found matching unsolicited callback\n"); + + /* update statistical info */ + ixNpeMhReceiveStats[npeId].unsolicited++; + } + + /* if no unsolicited callback was found try to find a matching */ + /* solicited callback for this message */ + if (callback == NULL) + { + ixNpeMhSolicitedCbMgrCallbackRetrieve ( + npeId, messageId, &callback); + + if (callback != NULL) + { + IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, + "Found matching solicited callback\n"); + + /* update statistical info */ + ixNpeMhReceiveStats[npeId].solicited++; + } + } + + /* if a callback (either unsolicited or solicited) was found */ + if (callback != NULL) + { + /* invoke the callback to pass the message back to the client */ + callback (npeId, message); + + /* update statistical info */ + ixNpeMhReceiveStats[npeId].callbacks++; + } + else /* no callback (neither unsolicited nor solicited) was found */ + { + IX_NPEMH_TRACE2 (IX_NPEMH_WARNING, + "No matching callback for NPE %d" + " and ID 0x%02X, discarding message\n", + npeId, messageId); + + /* the message will be discarded. this is normal behaviour */ + /* if the client passes a NULL solicited callback when */ + /* sending a message. this indicates that the client is not */ + /* interested in receiving the response. alternatively a */ + /* NULL callback here may signify an unsolicited message */ + /* with no appropriate registered callback. */ + } + } + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhReceiveMessagesReceive\n"); + + return IX_SUCCESS; +} + +/* + * Function definition: ixNpeMhReceiveShow + */ + +void ixNpeMhReceiveShow ( + IxNpeMhNpeId npeId) +{ + /* show the ISR invocation counter */ + IX_NPEMH_SHOW ("Receive ISR invocations", + ixNpeMhReceiveStats[npeId].isrs); + + /* show the receive message invocation counter */ + IX_NPEMH_SHOW ("Receive messages invocations", + ixNpeMhReceiveStats[npeId].receives); + + /* show the message received counter */ + IX_NPEMH_SHOW ("Messages received", + ixNpeMhReceiveStats[npeId].messages); + + /* show the solicited message counter */ + IX_NPEMH_SHOW ("Solicited messages received", + ixNpeMhReceiveStats[npeId].solicited); + + /* show the unsolicited message counter */ + IX_NPEMH_SHOW ("Unsolicited messages received", + ixNpeMhReceiveStats[npeId].unsolicited); + + /* show the callback invoked counter */ + IX_NPEMH_SHOW ("Callbacks invoked", + ixNpeMhReceiveStats[npeId].callbacks); + + /* show the message discarded counter */ + IX_NPEMH_SHOW ("Received messages discarded", + (ixNpeMhReceiveStats[npeId].messages - + ixNpeMhReceiveStats[npeId].callbacks)); +} + +/* + * Function definition: ixNpeMhReceiveShowReset + */ + +void ixNpeMhReceiveShowReset ( + IxNpeMhNpeId npeId) +{ + /* reset the ISR invocation counter */ + ixNpeMhReceiveStats[npeId].isrs = 0; + + /* reset the receive message invocation counter */ + ixNpeMhReceiveStats[npeId].receives = 0; + + /* reset the message received counter */ + ixNpeMhReceiveStats[npeId].messages = 0; + + /* reset the solicited message counter */ + ixNpeMhReceiveStats[npeId].solicited = 0; + + /* reset the unsolicited message counter */ + ixNpeMhReceiveStats[npeId].unsolicited = 0; + + /* reset the callback invoked counter */ + ixNpeMhReceiveStats[npeId].callbacks = 0; +} diff --git a/drivers/net/npe/IxNpeMhSend.c b/drivers/net/npe/IxNpeMhSend.c new file mode 100644 index 0000000..318913a --- /dev/null +++ b/drivers/net/npe/IxNpeMhSend.c @@ -0,0 +1,307 @@ +/** + * @file IxNpeMhSend.c + * + * @author Intel Corporation + * @date 18 Jan 2002 + * + * @brief This file contains the implementation of the private API for the + * Send module. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * Put the system defined include files required. + */ + + +/* + * Put the user defined include files required. + */ + +#include "IxNpeMhMacros_p.h" + +#include "IxNpeMhConfig_p.h" +#include "IxNpeMhSend_p.h" +#include "IxNpeMhSolicitedCbMgr_p.h" + +/* + * #defines and macros used in this file. + */ + +/** + * @def IX_NPEMH_INFIFO_RETRY_DELAY_US + * + * @brief Amount of time (uSecs) to delay between retries + * while inFIFO is Full when attempting to send a message + */ +#define IX_NPEMH_INFIFO_RETRY_DELAY_US (1) + + +/* + * Typedefs whose scope is limited to this file. + */ + +/** + * @struct IxNpeMhSendStats + * + * @brief This structure is used to maintain statistics for the Send + * module. + */ + +typedef struct +{ + UINT32 sends; /**< send invocations */ + UINT32 sendWithResponses; /**< send with response invocations */ + UINT32 queueFulls; /**< fifo queue full occurrences */ + UINT32 queueFullRetries; /**< fifo queue full retry occurrences */ + UINT32 maxQueueFullRetries; /**< max fifo queue full retries */ + UINT32 callbackFulls; /**< callback list full occurrences */ +} IxNpeMhSendStats; + +/* + * Variable declarations global to this file only. Externs are followed by + * static variables. + */ + +PRIVATE IxNpeMhSendStats ixNpeMhSendStats[IX_NPEMH_NUM_NPES]; + +/* + * Extern function prototypes. + */ + +/* + * Static function prototypes. + */ +PRIVATE +BOOL ixNpeMhSendInFifoIsFull( + IxNpeMhNpeId npeId, + UINT32 maxSendRetries); + +/* + * Function definition: ixNpeMhSendInFifoIsFull + */ + +PRIVATE +BOOL ixNpeMhSendInFifoIsFull( + IxNpeMhNpeId npeId, + UINT32 maxSendRetries) +{ + BOOL isFull = FALSE; + UINT32 numRetries = 0; + + /* check the NPE's inFIFO */ + isFull = ixNpeMhConfigInFifoIsFull (npeId); + + /* we retry a few times, just to give the NPE a chance to read from */ + /* the FIFO if the FIFO is currently full */ + while (isFull && (numRetries++ < maxSendRetries)) + { + if (numRetries >= IX_NPEMH_SEND_RETRIES_DEFAULT) + { + /* Delay here for as short a time as possible (1 us). */ + /* Adding a delay here should ensure we are not hogging */ + /* the AHB bus while we are retrying */ + ixOsalBusySleep (IX_NPEMH_INFIFO_RETRY_DELAY_US); + } + + /* re-check the NPE's inFIFO */ + isFull = ixNpeMhConfigInFifoIsFull (npeId); + + /* update statistical info */ + ixNpeMhSendStats[npeId].queueFullRetries++; + } + + /* record the highest number of retries that occurred */ + if (ixNpeMhSendStats[npeId].maxQueueFullRetries < numRetries) + { + ixNpeMhSendStats[npeId].maxQueueFullRetries = numRetries; + } + + if (isFull) + { + /* update statistical info */ + ixNpeMhSendStats[npeId].queueFulls++; + } + + return isFull; +} + +/* + * Function definition: ixNpeMhSendMessageSend + */ + +IX_STATUS ixNpeMhSendMessageSend ( + IxNpeMhNpeId npeId, + IxNpeMhMessage message, + UINT32 maxSendRetries) +{ + IX_STATUS status; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhSendMessageSend\n"); + + /* update statistical info */ + ixNpeMhSendStats[npeId].sends++; + + /* check if the NPE's inFIFO is full - if so return an error */ + if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries)) + { + IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n"); + return IX_FAIL; + } + + /* write the message to the NPE's inFIFO */ + status = ixNpeMhConfigInFifoWrite (npeId, message); + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhSendMessageSend\n"); + + return status; +} + +/* + * Function definition: ixNpeMhSendMessageWithResponseSend + */ + +IX_STATUS ixNpeMhSendMessageWithResponseSend ( + IxNpeMhNpeId npeId, + IxNpeMhMessage message, + IxNpeMhMessageId solicitedMessageId, + IxNpeMhCallback solicitedCallback, + UINT32 maxSendRetries) +{ + IX_STATUS status = IX_SUCCESS; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhSendMessageWithResponseSend\n"); + + /* update statistical info */ + ixNpeMhSendStats[npeId].sendWithResponses++; + + /* sr: this sleep will call the receive routine (no interrupts used!!!) */ + ixOsalSleep (IX_NPEMH_INFIFO_RETRY_DELAY_US); + + /* check if the NPE's inFIFO is full - if so return an error */ + if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries)) + { + IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n"); + return IX_FAIL; + } + + /* save the solicited callback */ + status = ixNpeMhSolicitedCbMgrCallbackSave ( + npeId, solicitedMessageId, solicitedCallback); + if (status != IX_SUCCESS) + { + IX_NPEMH_ERROR_REPORT ("Failed to save solicited callback\n"); + + /* update statistical info */ + ixNpeMhSendStats[npeId].callbackFulls++; + + return status; + } + + /* write the message to the NPE's inFIFO */ + status = ixNpeMhConfigInFifoWrite (npeId, message); + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhSendMessageWithResponseSend\n"); + + return status; +} + +/* + * Function definition: ixNpeMhSendShow + */ + +void ixNpeMhSendShow ( + IxNpeMhNpeId npeId) +{ + /* show the message send invocation counter */ + IX_NPEMH_SHOW ("Send invocations", + ixNpeMhSendStats[npeId].sends); + + /* show the message send with response invocation counter */ + IX_NPEMH_SHOW ("Send with response invocations", + ixNpeMhSendStats[npeId].sendWithResponses); + + /* show the fifo queue full occurrence counter */ + IX_NPEMH_SHOW ("Fifo queue full occurrences", + ixNpeMhSendStats[npeId].queueFulls); + + /* show the fifo queue full retry occurrence counter */ + IX_NPEMH_SHOW ("Fifo queue full retry occurrences", + ixNpeMhSendStats[npeId].queueFullRetries); + + /* show the fifo queue full maximum retries counter */ + IX_NPEMH_SHOW ("Maximum fifo queue full retries", + ixNpeMhSendStats[npeId].maxQueueFullRetries); + + /* show the callback list full occurrence counter */ + IX_NPEMH_SHOW ("Solicited callback list full occurrences", + ixNpeMhSendStats[npeId].callbackFulls); +} + +/* + * Function definition: ixNpeMhSendShowReset + */ + +void ixNpeMhSendShowReset ( + IxNpeMhNpeId npeId) +{ + /* reset the message send invocation counter */ + ixNpeMhSendStats[npeId].sends = 0; + + /* reset the message send with response invocation counter */ + ixNpeMhSendStats[npeId].sendWithResponses = 0; + + /* reset the fifo queue full occurrence counter */ + ixNpeMhSendStats[npeId].queueFulls = 0; + + /* reset the fifo queue full retry occurrence counter */ + ixNpeMhSendStats[npeId].queueFullRetries = 0; + + /* reset the max fifo queue full retries counter */ + ixNpeMhSendStats[npeId].maxQueueFullRetries = 0; + + /* reset the callback list full occurrence counter */ + ixNpeMhSendStats[npeId].callbackFulls = 0; +} diff --git a/drivers/net/npe/IxNpeMhSolicitedCbMgr.c b/drivers/net/npe/IxNpeMhSolicitedCbMgr.c new file mode 100644 index 0000000..8e083a6 --- /dev/null +++ b/drivers/net/npe/IxNpeMhSolicitedCbMgr.c @@ -0,0 +1,358 @@ +/** + * @file IxNpeMhSolicitedCbMgr.c + * + * @author Intel Corporation + * @date 18 Jan 2002 + * + * @brief This file contains the implementation of the private API for the + * Solicited Callback Manager module. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ +#ifndef IXNPEMHCONFIG_P_H +# define IXNPEMHSOLICITEDCBMGR_C +#else +# error "Error, IxNpeMhConfig_p.h should not be included before this definition." +#endif + +/* + * Put the system defined include files required. + */ + + +/* + * Put the user defined include files required. + */ + +#include "IxOsal.h" + +#include "IxNpeMhMacros_p.h" +#include "IxNpeMhSolicitedCbMgr_p.h" +#include "IxNpeMhConfig_p.h" +/* + * #defines and macros used in this file. + */ + +/* + * Typedefs whose scope is limited to this file. + */ + +/** + * @struct IxNpeMhSolicitedCallbackListEntry + * + * @brief This structure is used to store the information associated with + * an entry in the callback list. This consists of the ID of the send + * message (which indicates the ID of the corresponding response message) + * and the callback function pointer itself. + * + */ + +typedef struct IxNpeMhSolicitedCallbackListEntry +{ + /** message ID */ + IxNpeMhMessageId messageId; + + /** callback function pointer */ + IxNpeMhCallback callback; + + /** pointer to next entry in the list */ + struct IxNpeMhSolicitedCallbackListEntry *next; +} IxNpeMhSolicitedCallbackListEntry; + +/** + * @struct IxNpeMhSolicitedCallbackList + * + * @brief This structure is used to maintain the list of response + * callbacks. The number of entries in this list will be variable, and + * they will be stored in a linked list fashion for ease of addition and + * removal. The entries themselves are statically allocated, and are + * organised into a "free" list and a "callback" list. Adding an entry + * means taking an entry from the "free" list and adding it to the + * "callback" list. Removing an entry means removing it from the + * "callback" list and returning it to the "free" list. + */ + +typedef struct +{ + /** pointer to the head of the free list */ + IxNpeMhSolicitedCallbackListEntry *freeHead; + + /** pointer to the head of the callback list */ + IxNpeMhSolicitedCallbackListEntry *callbackHead; + + /** pointer to the tail of the callback list */ + IxNpeMhSolicitedCallbackListEntry *callbackTail; + + /** array of entries - the first entry is used as a dummy entry to */ + /* avoid the scenario of having an empty list, hence '+ 1' */ + IxNpeMhSolicitedCallbackListEntry entries[IX_NPEMH_MAX_CALLBACKS + 1]; +} IxNpeMhSolicitedCallbackList; + +/** + * @struct IxNpeMhSolicitedCbMgrStats + * + * @brief This structure is used to maintain statistics for the Solicited + * Callback Manager module. + */ + +typedef struct +{ + UINT32 saves; /**< callback list saves */ + UINT32 retrieves; /**< callback list retrieves */ +} IxNpeMhSolicitedCbMgrStats; + +/* + * Variable declarations global to this file only. Externs are followed by + * static variables. + */ + +PRIVATE IxNpeMhSolicitedCallbackList +ixNpeMhSolicitedCbMgrCallbackLists[IX_NPEMH_NUM_NPES]; + +PRIVATE IxNpeMhSolicitedCbMgrStats +ixNpeMhSolicitedCbMgrStats[IX_NPEMH_NUM_NPES]; + +/* + * Extern function prototypes. + */ + +/* + * Static function prototypes. + */ + +/* + * Function definition: ixNpeMhSolicitedCbMgrInitialize + */ + +void ixNpeMhSolicitedCbMgrInitialize (void) +{ + IxNpeMhNpeId npeId; + UINT32 localIndex; + IxNpeMhSolicitedCallbackList *list = NULL; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhSolicitedCbMgrInitialize\n"); + + /* for each NPE ... */ + for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) + { + /* initialise a pointer to the list for convenience */ + list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId]; + + /* for each entry in the list, after the dummy entry ... */ + for (localIndex = 1; localIndex <= IX_NPEMH_MAX_CALLBACKS; localIndex++) + { + /* initialise the entry */ + list->entries[localIndex].messageId = 0x00; + list->entries[localIndex].callback = NULL; + + /* if this entry is before the last entry */ + if (localIndex < IX_NPEMH_MAX_CALLBACKS) + { + /* chain this entry to the following entry */ + list->entries[localIndex].next = &(list->entries[localIndex + 1]); + } + else /* this entry is the last entry */ + { + /* the last entry isn't chained to anything */ + list->entries[localIndex].next = NULL; + } + } + + /* set the free list pointer to point to the first real entry */ + /* (all real entries begin chained together on the free list) */ + list->freeHead = &(list->entries[1]); + + /* set the callback list pointers to point to the dummy entry */ + /* (the callback list is initially empty) */ + list->callbackHead = &(list->entries[0]); + list->callbackTail = &(list->entries[0]); + } + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhSolicitedCbMgrInitialize\n"); +} + +/* + * Function definition: ixNpeMhSolicitedCbMgrCallbackSave + */ + +IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave ( + IxNpeMhNpeId npeId, + IxNpeMhMessageId solicitedMessageId, + IxNpeMhCallback solicitedCallback) +{ + IxNpeMhSolicitedCallbackList *list = NULL; + IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhSolicitedCbMgrCallbackSave\n"); + + /* initialise a pointer to the list for convenience */ + list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId]; + + /* check to see if there are any entries in the free list */ + if (list->freeHead == NULL) + { + IX_NPEMH_ERROR_REPORT ("Solicited callback list is full\n"); + return IX_FAIL; + } + + /* there is an entry in the free list we can use */ + + /* update statistical info */ + ixNpeMhSolicitedCbMgrStats[npeId].saves++; + + /* remove a callback entry from the start of the free list */ + callbackEntry = list->freeHead; + list->freeHead = callbackEntry->next; + + /* fill in the callback entry with the new data */ + callbackEntry->messageId = solicitedMessageId; + callbackEntry->callback = solicitedCallback; + + /* the new callback entry will be added to the tail of the callback */ + /* list, so it isn't chained to anything */ + callbackEntry->next = NULL; + + /* chain new callback entry to the last entry of the callback list */ + list->callbackTail->next = callbackEntry; + list->callbackTail = callbackEntry; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhSolicitedCbMgrCallbackSave\n"); + + return IX_SUCCESS; +} + +/* + * Function definition: ixNpeMhSolicitedCbMgrCallbackRetrieve + */ + +void ixNpeMhSolicitedCbMgrCallbackRetrieve ( + IxNpeMhNpeId npeId, + IxNpeMhMessageId solicitedMessageId, + IxNpeMhCallback *solicitedCallback) +{ + IxNpeMhSolicitedCallbackList *list = NULL; + IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL; + IxNpeMhSolicitedCallbackListEntry *previousEntry = NULL; + + /* initialise a pointer to the list for convenience */ + list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId]; + + /* initialise the callback entry to the first entry of the callback */ + /* list - we must skip over the dummy entry, which is the previous */ + callbackEntry = list->callbackHead->next; + previousEntry = list->callbackHead; + + /* traverse the callback list looking for an entry with a matching */ + /* message ID. note we also save the previous entry's pointer to */ + /* allow us to unchain the matching entry from the callback list */ + while ((callbackEntry != NULL) && + (callbackEntry->messageId != solicitedMessageId)) + { + previousEntry = callbackEntry; + callbackEntry = callbackEntry->next; + } + + /* if we didn't find a matching callback entry */ + if (callbackEntry == NULL) + { + /* return a NULL callback in the outgoing parameter */ + *solicitedCallback = NULL; + } + else /* we found a matching callback entry */ + { + /* update statistical info */ + ixNpeMhSolicitedCbMgrStats[npeId].retrieves++; + + /* return the callback in the outgoing parameter */ + *solicitedCallback = callbackEntry->callback; + + /* unchain callback entry by chaining previous entry to next */ + previousEntry->next = callbackEntry->next; + + /* if the callback entry is at the tail of the list */ + if (list->callbackTail == callbackEntry) + { + /* update the tail of the callback list */ + list->callbackTail = previousEntry; + } + + /* re-initialise the callback entry */ + callbackEntry->messageId = 0x00; + callbackEntry->callback = NULL; + + /* add the callback entry to the start of the free list */ + callbackEntry->next = list->freeHead; + list->freeHead = callbackEntry; + } +} + +/* + * Function definition: ixNpeMhSolicitedCbMgrShow + */ + +void ixNpeMhSolicitedCbMgrShow ( + IxNpeMhNpeId npeId) +{ + /* show the solicited callback list save counter */ + IX_NPEMH_SHOW ("Solicited callback list saves", + ixNpeMhSolicitedCbMgrStats[npeId].saves); + + /* show the solicited callback list retrieve counter */ + IX_NPEMH_SHOW ("Solicited callback list retrieves", + ixNpeMhSolicitedCbMgrStats[npeId].retrieves); +} + +/* + * Function definition: ixNpeMhSolicitedCbMgrShowReset + */ + +void ixNpeMhSolicitedCbMgrShowReset ( + IxNpeMhNpeId npeId) +{ + /* reset the solicited callback list save counter */ + ixNpeMhSolicitedCbMgrStats[npeId].saves = 0; + + /* reset the solicited callback list retrieve counter */ + ixNpeMhSolicitedCbMgrStats[npeId].retrieves = 0; +} diff --git a/drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c b/drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c new file mode 100644 index 0000000..d37f9f9 --- /dev/null +++ b/drivers/net/npe/IxNpeMhUnsolicitedCbMgr.c @@ -0,0 +1,246 @@ +/** + * @file IxNpeMhUnsolicitedCbMgr.c + * + * @author Intel Corporation + * @date 18 Jan 2002 + * + * @brief This file contains the implementation of the private API for + * the Unsolicited Callback Manager module. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * Put the system defined include files required. + */ + + +/* + * Put the user defined include files required. + */ +#include "IxOsal.h" + +#include "IxNpeMhMacros_p.h" + +#include "IxNpeMhUnsolicitedCbMgr_p.h" + + +/* + * #defines and macros used in this file. + */ + +/* + * Typedefs whose scope is limited to this file. + */ + +/** + * @struct IxNpeMhUnsolicitedCallbackTable + * + * @brief This structure is used to maintain the list of registered + * callbacks. One entry exists for each message ID, and a NULL entry will + * signify that no callback has been registered for that ID. + */ + +typedef struct +{ + /** array of entries */ + IxNpeMhCallback entries[IX_NPEMH_MAX_MESSAGE_ID + 1]; +} IxNpeMhUnsolicitedCallbackTable; + +/** + * @struct IxNpeMhUnsolicitedCbMgrStats + * + * @brief This structure is used to maintain statistics for the Unsolicited + * Callback Manager module. + */ + +typedef struct +{ + UINT32 saves; /**< callback table saves */ + UINT32 overwrites; /**< callback table overwrites */ +} IxNpeMhUnsolicitedCbMgrStats; + +/* + * Variable declarations global to this file only. Externs are followed by + * static variables. + */ + +PRIVATE IxNpeMhUnsolicitedCallbackTable +ixNpeMhUnsolicitedCallbackTables[IX_NPEMH_NUM_NPES]; + +PRIVATE IxNpeMhUnsolicitedCbMgrStats +ixNpeMhUnsolicitedCbMgrStats[IX_NPEMH_NUM_NPES]; + +/* + * Extern function prototypes. + */ + +/* + * Static function prototypes. + */ + +/* + * Function definition: ixNpeMhUnsolicitedCbMgrInitialize + */ + +void ixNpeMhUnsolicitedCbMgrInitialize (void) +{ + IxNpeMhNpeId npeId = 0; + IxNpeMhUnsolicitedCallbackTable *table = NULL; + IxNpeMhMessageId messageId = 0; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhUnsolicitedCbMgrInitialize\n"); + + /* for each NPE ... */ + for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) + { + /* initialise a pointer to the table for convenience */ + table = &ixNpeMhUnsolicitedCallbackTables[npeId]; + + /* for each message ID ... */ + for (messageId = IX_NPEMH_MIN_MESSAGE_ID; + messageId <= IX_NPEMH_MAX_MESSAGE_ID; messageId++) + { + /* initialise the callback for this message ID to NULL */ + table->entries[messageId] = NULL; + } + } + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhUnsolicitedCbMgrInitialize\n"); +} + +/* + * Function definition: ixNpeMhUnsolicitedCbMgrCallbackSave + */ + +void ixNpeMhUnsolicitedCbMgrCallbackSave ( + IxNpeMhNpeId npeId, + IxNpeMhMessageId unsolicitedMessageId, + IxNpeMhCallback unsolicitedCallback) +{ + IxNpeMhUnsolicitedCallbackTable *table = NULL; + + /* initialise a pointer to the table for convenience */ + table = &ixNpeMhUnsolicitedCallbackTables[npeId]; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " + "ixNpeMhUnsolicitedCbMgrCallbackSave\n"); + + /* update statistical info */ + ixNpeMhUnsolicitedCbMgrStats[npeId].saves++; + + /* check if there is a callback already registered for this NPE and */ + /* message ID */ + if (table->entries[unsolicitedMessageId] != NULL) + { + /* if we are overwriting an existing callback */ + if (unsolicitedCallback != NULL) + { + IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "Unsolicited callback " + "overwriting existing callback for NPE ID %d " + "message ID 0x%02X\n", npeId, unsolicitedMessageId); + } + else /* if we are clearing an existing callback */ + { + IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NULL unsolicited callback " + "clearing existing callback for NPE ID %d " + "message ID 0x%02X\n", npeId, unsolicitedMessageId); + } + + /* update statistical info */ + ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites++; + } + + /* save the callback into the table */ + table->entries[unsolicitedMessageId] = unsolicitedCallback; + + IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " + "ixNpeMhUnsolicitedCbMgrCallbackSave\n"); +} + +/* + * Function definition: ixNpeMhUnsolicitedCbMgrCallbackRetrieve + */ + +void ixNpeMhUnsolicitedCbMgrCallbackRetrieve ( + IxNpeMhNpeId npeId, + IxNpeMhMessageId unsolicitedMessageId, + IxNpeMhCallback *unsolicitedCallback) +{ + IxNpeMhUnsolicitedCallbackTable *table = NULL; + + /* initialise a pointer to the table for convenience */ + table = &ixNpeMhUnsolicitedCallbackTables[npeId]; + + /* retrieve the callback from the table */ + *unsolicitedCallback = table->entries[unsolicitedMessageId]; +} + +/* + * Function definition: ixNpeMhUnsolicitedCbMgrShow + */ + +void ixNpeMhUnsolicitedCbMgrShow ( + IxNpeMhNpeId npeId) +{ + /* show the unsolicited callback table save counter */ + IX_NPEMH_SHOW ("Unsolicited callback table saves", + ixNpeMhUnsolicitedCbMgrStats[npeId].saves); + + /* show the unsolicited callback table overwrite counter */ + IX_NPEMH_SHOW ("Unsolicited callback table overwrites", + ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites); +} + +/* + * Function definition: ixNpeMhUnsolicitedCbMgrShowReset + */ + +void ixNpeMhUnsolicitedCbMgrShowReset ( + IxNpeMhNpeId npeId) +{ + /* reset the unsolicited callback table save counter */ + ixNpeMhUnsolicitedCbMgrStats[npeId].saves = 0; + + /* reset the unsolicited callback table overwrite counter */ + ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites = 0; +} diff --git a/drivers/net/npe/IxOsalBufferMgt.c b/drivers/net/npe/IxOsalBufferMgt.c new file mode 100644 index 0000000..fa8db47 --- /dev/null +++ b/drivers/net/npe/IxOsalBufferMgt.c @@ -0,0 +1,800 @@ +/** + * @file IxOsalBufferMgt.c + * + * @brief Default buffer pool management and buffer management + * Implementation. + * + * Design Notes: + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/* + * OS may choose to use default bufferMgt by defining + * IX_OSAL_USE_DEFAULT_BUFFER_MGT in IxOsalOsBufferMgt.h + */ + +#include "IxOsal.h" + +#define IX_OSAL_BUFFER_FREE_PROTECTION /* Define this to enable Illegal MBuf Freed Protection*/ + +/* + * The implementation is only used when the following + * is defined. + */ +#ifdef IX_OSAL_USE_DEFAULT_BUFFER_MGT + + +#define IX_OSAL_MBUF_SYS_SIGNATURE (0x8BADF00D) +#define IX_OSAL_MBUF_SYS_SIGNATURE_MASK (0xEFFFFFFF) +#define IX_OSAL_MBUF_USED_FLAG (0x10000000) +#define IX_OSAL_MBUF_SYS_SIGNATURE_INIT(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) = (UINT32)IX_OSAL_MBUF_SYS_SIGNATURE + +/* +* This implementation is protect, the buffer pool management's ixOsalMBufFree +* against an invalid MBUF pointer argument that already has been freed earlier +* or in other words resides in the free pool of MBUFs. This added feature, +* checks the MBUF "USED" FLAG. The Flag tells if the MBUF is still not freed +* back to the Buffer Pool. +* Disable this feature for performance reasons by undef +* IX_OSAL_BUFFER_FREE_PROTECTION macro. +*/ +#ifdef IX_OSAL_BUFFER_FREE_PROTECTION /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/ + +#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&(IX_OSAL_MBUF_SYS_SIGNATURE_MASK) ) +#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr) do { \ + IX_OSAL_MBUF_SIGNATURE (bufPtr)&(~IX_OSAL_MBUF_SYS_SIGNATURE_MASK);\ + IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_SYS_SIGNATURE; \ + }while(0) + +#define IX_OSAL_MBUF_SET_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)|=IX_OSAL_MBUF_USED_FLAG +#define IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr)&=~IX_OSAL_MBUF_USED_FLAG +#define IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr) (IX_OSAL_MBUF_SIGNATURE (bufPtr)&IX_OSAL_MBUF_USED_FLAG) + +#else + +#define IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) +#define IX_OSAL_MBUF_SET_SYS_SIGNATURE(bufPtr) IX_OSAL_MBUF_SIGNATURE (bufPtr) = IX_OSAL_MBUF_SYS_SIGNATURE + +#endif /*IX_OSAL_BUFFER_FREE_PROTECTION With Buffer Free protection*/ +/* + * Variable declarations global to this file only. Externs are followed by + * static variables. + */ + +/* + * A unit of 32, used to provide bit-shift for pool + * management. Needs some work if users want more than 32 pools. + */ +#define IX_OSAL_BUFF_FREE_BITS 32 + +PRIVATE UINT32 ixOsalBuffFreePools[IX_OSAL_MBUF_MAX_POOLS / + IX_OSAL_BUFF_FREE_BITS]; + +PUBLIC IX_OSAL_MBUF_POOL ixOsalBuffPools[IX_OSAL_MBUF_MAX_POOLS]; + +static int ixOsalBuffPoolsInUse = 0; + +#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY +PRIVATE IX_OSAL_MBUF * +ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned, + UINT32 dataSizeAligned, + IX_OSAL_MBUF_POOL *poolPtr); +#endif + +PRIVATE IX_OSAL_MBUF_POOL * ixOsalPoolAlloc (void); + +/* + * Function definition: ixOsalPoolAlloc + */ + +/****************************/ + +PRIVATE IX_OSAL_MBUF_POOL * +ixOsalPoolAlloc (void) +{ + register unsigned int i = 0; + + /* + * Scan for the first free buffer. Free buffers are indicated by 0 + * on the corrsponding bit in ixOsalBuffFreePools. + */ + if (ixOsalBuffPoolsInUse >= IX_OSAL_MBUF_MAX_POOLS) + { + /* + * Fail to grab a ptr this time + */ + return NULL; + } + + while (ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] & + (1 << (i % IX_OSAL_BUFF_FREE_BITS))) + i++; + /* + * Free buffer found. Mark it as busy and initialize. + */ + ixOsalBuffFreePools[i / IX_OSAL_BUFF_FREE_BITS] |= + (1 << (i % IX_OSAL_BUFF_FREE_BITS)); + + memset (&ixOsalBuffPools[i], 0, sizeof (IX_OSAL_MBUF_POOL)); + + ixOsalBuffPools[i].poolIdx = i; + ixOsalBuffPoolsInUse++; + + return &ixOsalBuffPools[i]; +} + + +#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY +PRIVATE IX_OSAL_MBUF * +ixOsalBuffPoolMbufInit (UINT32 mbufSizeAligned, + UINT32 dataSizeAligned, + IX_OSAL_MBUF_POOL *poolPtr) +{ + UINT8 *dataPtr; + IX_OSAL_MBUF *realMbufPtr; + /* Allocate cache-aligned memory for mbuf header */ + realMbufPtr = (IX_OSAL_MBUF *) IX_OSAL_CACHE_DMA_MALLOC (mbufSizeAligned); + IX_OSAL_ASSERT (realMbufPtr != NULL); + memset (realMbufPtr, 0, mbufSizeAligned); + + /* Allocate cache-aligned memory for mbuf data */ + dataPtr = (UINT8 *) IX_OSAL_CACHE_DMA_MALLOC (dataSizeAligned); + IX_OSAL_ASSERT (dataPtr != NULL); + memset (dataPtr, 0, dataSizeAligned); + + /* Fill in mbuf header fields */ + IX_OSAL_MBUF_MDATA (realMbufPtr) = dataPtr; + IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (realMbufPtr) = (UINT32)dataPtr; + + IX_OSAL_MBUF_MLEN (realMbufPtr) = dataSizeAligned; + IX_OSAL_MBUF_ALLOCATED_BUFF_LEN (realMbufPtr) = dataSizeAligned; + + IX_OSAL_MBUF_NET_POOL (realMbufPtr) = (IX_OSAL_MBUF_POOL *) poolPtr; + + IX_OSAL_MBUF_SYS_SIGNATURE_INIT(realMbufPtr); + + /* update some statistical information */ + poolPtr->mbufMemSize += mbufSizeAligned; + poolPtr->dataMemSize += dataSizeAligned; + + return realMbufPtr; +} +#endif /* #ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY */ + +/* + * Function definition: ixOsalBuffPoolInit + */ + +PUBLIC IX_OSAL_MBUF_POOL * +ixOsalPoolInit (UINT32 count, UINT32 size, const char *name) +{ + + /* These variables are only used if UX_OSAL_BUFFER_ALLOC_SEPERATELY + * is defined . + */ +#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY + UINT32 i, mbufSizeAligned, dataSizeAligned; + IX_OSAL_MBUF *currentMbufPtr = NULL; +#else + void *poolBufPtr; + void *poolDataPtr; + int mbufMemSize; + int dataMemSize; +#endif + + IX_OSAL_MBUF_POOL *poolPtr = NULL; + + if (count <= 0) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalPoolInit(): " "count = 0 \n", 0, 0, 0, 0, 0, 0); + return NULL; + } + + if (name == NULL) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalPoolInit(): " "NULL name \n", 0, 0, 0, 0, 0, 0); + return NULL; + } + + if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalPoolInit(): " + "ERROR - name length should be no greater than %d \n", + IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0); + return NULL; + } + +/* OS can choose whether to allocate all buffers all together (if it + * can handle a huge single alloc request), or to allocate buffers + * separately by the defining IX_OSAL_BUFFER_ALLOC_SEPARATELY. + */ +#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY + /* Get a pool Ptr */ + poolPtr = ixOsalPoolAlloc (); + + if (poolPtr == NULL) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalPoolInit(): " "Fail to Get PoolPtr \n", 0, 0, 0, 0, 0, 0); + return NULL; + } + + mbufSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF)); + dataSizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN(size); + + poolPtr->nextFreeBuf = NULL; + poolPtr->mbufMemPtr = NULL; + poolPtr->dataMemPtr = NULL; + poolPtr->bufDataSize = dataSizeAligned; + poolPtr->totalBufsInPool = count; + poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC; + strcpy (poolPtr->name, name); + + + for (i = 0; i < count; i++) + { + /* create an mbuf */ + currentMbufPtr = ixOsalBuffPoolMbufInit (mbufSizeAligned, + dataSizeAligned, + poolPtr); + +#ifdef IX_OSAL_BUFFER_FREE_PROTECTION +/* Set the Buffer USED Flag. If not, ixOsalMBufFree will fail. + ixOsalMbufFree used here is in a special case whereby, it's + used to add MBUF to the Pool. By specification, ixOsalMbufFree + deallocates an allocated MBUF from Pool. +*/ + IX_OSAL_MBUF_SET_USED_FLAG(currentMbufPtr); +#endif + /* Add it to the pool */ + ixOsalMbufFree (currentMbufPtr); + + /* flush the pool information to RAM */ + IX_OSAL_CACHE_FLUSH (currentMbufPtr, mbufSizeAligned); + } + + /* + * update the number of free buffers in the pool + */ + poolPtr->freeBufsInPool = count; + +#else +/* Otherwise allocate buffers in a continuous block fashion */ + poolBufPtr = IX_OSAL_MBUF_POOL_MBUF_AREA_ALLOC (count, mbufMemSize); + IX_OSAL_ASSERT (poolBufPtr != NULL); + poolDataPtr = + IX_OSAL_MBUF_POOL_DATA_AREA_ALLOC (count, size, dataMemSize); + IX_OSAL_ASSERT (poolDataPtr != NULL); + + poolPtr = ixOsalNoAllocPoolInit (poolBufPtr, poolDataPtr, + count, size, name); + if (poolPtr == NULL) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalPoolInit(): " "Fail to get pool ptr \n", 0, 0, 0, 0, 0, 0); + return NULL; + } + + poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC; + +#endif /* IX_OSAL_BUFFER_ALLOC_SEPARATELY */ + return poolPtr; +} + +PUBLIC IX_OSAL_MBUF_POOL * +ixOsalNoAllocPoolInit (void *poolBufPtr, + void *poolDataPtr, UINT32 count, UINT32 size, const char *name) +{ + UINT32 i, mbufSizeAligned, sizeAligned; + IX_OSAL_MBUF *currentMbufPtr = NULL; + IX_OSAL_MBUF *nextMbufPtr = NULL; + IX_OSAL_MBUF_POOL *poolPtr = NULL; + + /* + * check parameters + */ + if (poolBufPtr == NULL) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalNoAllocPoolInit(): " + "ERROR - NULL poolBufPtr \n", 0, 0, 0, 0, 0, 0); + return NULL; + } + + if (count <= 0) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalNoAllocPoolInit(): " + "ERROR - count must > 0 \n", 0, 0, 0, 0, 0, 0); + return NULL; + } + + if (name == NULL) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalNoAllocPoolInit(): " + "ERROR - NULL name ptr \n", 0, 0, 0, 0, 0, 0); + return NULL; + } + + if (strlen (name) > IX_OSAL_MBUF_POOL_NAME_LEN) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalNoAllocPoolInit(): " + "ERROR - name length should be no greater than %d \n", + IX_OSAL_MBUF_POOL_NAME_LEN, 0, 0, 0, 0, 0); + return NULL; + } + + poolPtr = ixOsalPoolAlloc (); + + if (poolPtr == NULL) + { + return NULL; + } + + /* + * Adjust sizes to ensure alignment on cache line boundaries + */ + mbufSizeAligned = + IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF)); + /* + * clear the mbuf memory area + */ + memset (poolBufPtr, 0, mbufSizeAligned * count); + + if (poolDataPtr != NULL) + { + /* + * Adjust sizes to ensure alignment on cache line boundaries + */ + sizeAligned = IX_OSAL_MBUF_POOL_SIZE_ALIGN (size); + /* + * clear the data memory area + */ + memset (poolDataPtr, 0, sizeAligned * count); + } + else + { + sizeAligned = 0; + } + + /* + * initialise pool fields + */ + strcpy ((poolPtr)->name, name); + + poolPtr->dataMemPtr = poolDataPtr; + poolPtr->mbufMemPtr = poolBufPtr; + poolPtr->bufDataSize = sizeAligned; + poolPtr->totalBufsInPool = count; + poolPtr->mbufMemSize = mbufSizeAligned * count; + poolPtr->dataMemSize = sizeAligned * count; + + currentMbufPtr = (IX_OSAL_MBUF *) poolBufPtr; + + poolPtr->nextFreeBuf = currentMbufPtr; + + for (i = 0; i < count; i++) + { + if (i < (count - 1)) + { + nextMbufPtr = + (IX_OSAL_MBUF *) ((unsigned) currentMbufPtr + + mbufSizeAligned); + } + else + { /* last mbuf in chain */ + nextMbufPtr = NULL; + } + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (currentMbufPtr) = nextMbufPtr; + IX_OSAL_MBUF_NET_POOL (currentMbufPtr) = poolPtr; + + IX_OSAL_MBUF_SYS_SIGNATURE_INIT(currentMbufPtr); + + if (poolDataPtr != NULL) + { + IX_OSAL_MBUF_MDATA (currentMbufPtr) = poolDataPtr; + IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(currentMbufPtr) = (UINT32) poolDataPtr; + + IX_OSAL_MBUF_MLEN (currentMbufPtr) = sizeAligned; + IX_OSAL_MBUF_ALLOCATED_BUFF_LEN(currentMbufPtr) = sizeAligned; + + poolDataPtr = (void *) ((unsigned) poolDataPtr + sizeAligned); + } + + currentMbufPtr = nextMbufPtr; + } + + /* + * update the number of free buffers in the pool + */ + poolPtr->freeBufsInPool = count; + + poolPtr->poolAllocType = IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC; + + return poolPtr; +} + +/* + * Get a mbuf ptr from the pool + */ +PUBLIC IX_OSAL_MBUF * +ixOsalMbufAlloc (IX_OSAL_MBUF_POOL * poolPtr) +{ + int lock; + IX_OSAL_MBUF *newBufPtr = NULL; + + /* + * check parameters + */ + if (poolPtr == NULL) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalMbufAlloc(): " + "ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0); + return NULL; + } + + lock = ixOsalIrqLock (); + + newBufPtr = poolPtr->nextFreeBuf; + if (newBufPtr) + { + poolPtr->nextFreeBuf = + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr); + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (newBufPtr) = NULL; + + /* + * update the number of free buffers in the pool + */ + poolPtr->freeBufsInPool--; + } + else + { + /* Return NULL to indicate to caller that request is denied. */ + ixOsalIrqUnlock (lock); + + return NULL; + } + +#ifdef IX_OSAL_BUFFER_FREE_PROTECTION + /* Set Buffer Used Flag to indicate state.*/ + IX_OSAL_MBUF_SET_USED_FLAG(newBufPtr); +#endif + + ixOsalIrqUnlock (lock); + + return newBufPtr; +} + +PUBLIC IX_OSAL_MBUF * +ixOsalMbufFree (IX_OSAL_MBUF * bufPtr) +{ + int lock; + IX_OSAL_MBUF_POOL *poolPtr; + + IX_OSAL_MBUF *nextBufPtr = NULL; + + /* + * check parameters + */ + if (bufPtr == NULL) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalMbufFree(): " + "ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0); + return NULL; + } + + + + lock = ixOsalIrqLock (); + +#ifdef IX_OSAL_BUFFER_FREE_PROTECTION + + /* Prevention for Buffer freed more than once*/ + if(!IX_OSAL_MBUF_ISSET_USED_FLAG(bufPtr)) + { + return NULL; + } + IX_OSAL_MBUF_CLEAR_USED_FLAG(bufPtr); +#endif + + poolPtr = IX_OSAL_MBUF_NET_POOL (bufPtr); + + /* + * check the mbuf wrapper signature (if mbuf wrapper was used) + */ + if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC) + { + IX_OSAL_ENSURE ( (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) == IX_OSAL_MBUF_SYS_SIGNATURE), + "ixOsalBuffPoolBufFree: ERROR - Invalid mbuf signature."); + } + + nextBufPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr); + + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR (bufPtr) = poolPtr->nextFreeBuf; + poolPtr->nextFreeBuf = bufPtr; + + /* + * update the number of free buffers in the pool + */ + poolPtr->freeBufsInPool++; + + ixOsalIrqUnlock (lock); + + return nextBufPtr; +} + +PUBLIC void +ixOsalMbufChainFree (IX_OSAL_MBUF * bufPtr) +{ + while ((bufPtr = ixOsalMbufFree (bufPtr))); +} + +/* + * Function definition: ixOsalBuffPoolShow + */ +PUBLIC void +ixOsalMbufPoolShow (IX_OSAL_MBUF_POOL * poolPtr) +{ + IX_OSAL_MBUF *nextBufPtr; + int count = 0; + int lock; + + /* + * check parameters + */ + if (poolPtr == NULL) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalBuffPoolShow(): " + "ERROR - Invalid Parameter", 0, 0, 0, 0, 0, 0); + /* + * return IX_FAIL; + */ + return; + } + + lock = ixOsalIrqLock (); + count = poolPtr->freeBufsInPool; + nextBufPtr = poolPtr->nextFreeBuf; + ixOsalIrqUnlock (lock); + + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, + IX_OSAL_LOG_DEV_STDOUT, "=== POOL INFORMATION ===\n", 0, 0, 0, + 0, 0, 0); + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, + "Pool Name: %s\n", + (unsigned int) poolPtr->name, 0, 0, 0, 0, 0); + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, + "Pool Allocation Type: %d\n", + (unsigned int) poolPtr->poolAllocType, 0, 0, 0, 0, 0); + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, + "Pool Mbuf Mem Usage (bytes): %d\n", + (unsigned int) poolPtr->mbufMemSize, 0, 0, 0, 0, 0); + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, + "Pool Data Mem Usage (bytes): %d\n", + (unsigned int) poolPtr->dataMemSize, 0, 0, 0, 0, 0); + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, + "Mbuf Data Capacity (bytes): %d\n", + (unsigned int) poolPtr->bufDataSize, 0, 0, 0, 0, 0); + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, + "Total Mbufs in Pool: %d\n", + (unsigned int) poolPtr->totalBufsInPool, 0, 0, 0, 0, 0); + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, + "Available Mbufs: %d\n", (unsigned int) count, 0, + 0, 0, 0, 0); + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, + "Next Available Mbuf: %p\n", (unsigned int) nextBufPtr, + 0, 0, 0, 0, 0); + + if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_USER_ALLOC) + { + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, + IX_OSAL_LOG_DEV_STDOUT, + "Mbuf Mem Area Start address: %p\n", + (unsigned int) poolPtr->mbufMemPtr, 0, 0, 0, 0, 0); + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, + "Data Mem Area Start address: %p\n", + (unsigned int) poolPtr->dataMemPtr, 0, 0, 0, 0, 0); + } +} + +PUBLIC void +ixOsalMbufDataPtrReset (IX_OSAL_MBUF * bufPtr) +{ + IX_OSAL_MBUF_POOL *poolPtr; + UINT8 *poolDataPtr; + + if (bufPtr == NULL) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, + "ixOsalBuffPoolBufDataPtrReset" + ": ERROR - Invalid Parameter\n", 0, 0, 0, 0, 0, 0); + return; + } + + poolPtr = (IX_OSAL_MBUF_POOL *) IX_OSAL_MBUF_NET_POOL (bufPtr); + poolDataPtr = poolPtr->dataMemPtr; + + if (poolPtr->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC) + { + if (IX_OSAL_MBUF_GET_SYS_SIGNATURE(bufPtr) != IX_OSAL_MBUF_SYS_SIGNATURE) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, + "ixOsalBuffPoolBufDataPtrReset" + ": invalid mbuf, cannot reset mData pointer\n", 0, 0, + 0, 0, 0, 0); + return; + } + IX_OSAL_MBUF_MDATA (bufPtr) = (UINT8*)IX_OSAL_MBUF_ALLOCATED_BUFF_DATA (bufPtr); + } + else + { + if (poolDataPtr) + { + unsigned int bufSize = poolPtr->bufDataSize; + unsigned int bufDataAddr = + (unsigned int) IX_OSAL_MBUF_MDATA (bufPtr); + unsigned int poolDataAddr = (unsigned int) poolDataPtr; + + /* + * the pointer is still pointing somewhere in the mbuf payload. + * This operation moves the pointer to the beginning of the + * mbuf payload + */ + bufDataAddr = ((bufDataAddr - poolDataAddr) / bufSize) * bufSize; + IX_OSAL_MBUF_MDATA (bufPtr) = &poolDataPtr[bufDataAddr]; + } + else + { + ixOsalLog (IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDOUT, + "ixOsalBuffPoolBufDataPtrReset" + ": cannot be used if user supplied NULL pointer for pool data area " + "when pool was created\n", 0, 0, 0, 0, 0, 0); + return; + } + } + +} + +/* + * Function definition: ixOsalBuffPoolUninit + */ +PUBLIC IX_STATUS +ixOsalBuffPoolUninit (IX_OSAL_MBUF_POOL * pool) +{ + if (!pool) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, + "ixOsalBuffPoolUninit: NULL ptr \n", 0, 0, 0, 0, 0, 0); + return IX_FAIL; + } + + if (pool->freeBufsInPool != pool->totalBufsInPool) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, + "ixOsalBuffPoolUninit: need to return all ptrs to the pool first! \n", + 0, 0, 0, 0, 0, 0); + return IX_FAIL; + } + + if (pool->poolAllocType == IX_OSAL_MBUF_POOL_TYPE_SYS_ALLOC) + { +#ifdef IX_OSAL_BUFFER_ALLOC_SEPARATELY + UINT32 i; + IX_OSAL_MBUF* pBuf; + + pBuf = pool->nextFreeBuf; + /* Freed the Buffer one by one till all the Memory is freed*/ + for (i= pool->freeBufsInPool; i >0 && pBuf!=NULL ;i--){ + IX_OSAL_MBUF* pBufTemp; + pBufTemp = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(pBuf); + /* Freed MBUF Data Memory area*/ + IX_OSAL_CACHE_DMA_FREE( (void *) (IX_OSAL_MBUF_ALLOCATED_BUFF_DATA(pBuf)) ); + /* Freed MBUF Struct Memory area*/ + IX_OSAL_CACHE_DMA_FREE(pBuf); + pBuf = pBufTemp; + } + +#else + IX_OSAL_CACHE_DMA_FREE (pool->mbufMemPtr); + IX_OSAL_CACHE_DMA_FREE (pool->dataMemPtr); +#endif + } + + ixOsalBuffFreePools[pool->poolIdx / IX_OSAL_BUFF_FREE_BITS] &= + ~(1 << (pool->poolIdx % IX_OSAL_BUFF_FREE_BITS)); + ixOsalBuffPoolsInUse--; + return IX_SUCCESS; +} + +/* + * Function definition: ixOsalBuffPoolDataAreaSizeGet + */ +PUBLIC UINT32 +ixOsalBuffPoolDataAreaSizeGet (int count, int size) +{ + UINT32 memorySize; + memorySize = count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (size); + return memorySize; +} + +/* + * Function definition: ixOsalBuffPoolMbufAreaSizeGet + */ +PUBLIC UINT32 +ixOsalBuffPoolMbufAreaSizeGet (int count) +{ + UINT32 memorySize; + memorySize = + count * IX_OSAL_MBUF_POOL_SIZE_ALIGN (sizeof (IX_OSAL_MBUF)); + return memorySize; +} + +/* + * Function definition: ixOsalBuffPoolFreeCountGet + */ +PUBLIC UINT32 ixOsalBuffPoolFreeCountGet(IX_OSAL_MBUF_POOL * poolPtr) + +{ + + return poolPtr->freeBufsInPool; + +} + +#endif /* IX_OSAL_USE_DEFAULT_BUFFER_MGT */ diff --git a/drivers/net/npe/IxOsalIoMem.c b/drivers/net/npe/IxOsalIoMem.c new file mode 100644 index 0000000..34df92b --- /dev/null +++ b/drivers/net/npe/IxOsalIoMem.c @@ -0,0 +1,332 @@ +/** + * @file IxOsalIoMem.c + * + * @brief OS-independent IO/Mem implementation + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/* Access to the global mem map is only allowed in this file */ +#define IxOsalIoMem_C + +#include "IxOsal.h" + +#define SEARCH_PHYSICAL_ADDRESS (1) +#define SEARCH_VIRTUAL_ADDRESS (2) + +/* + * Searches for map using one of the following criteria: + * + * - enough room to include a zone starting with the physical "requestedAddress" of size "size" (for mapping) + * - includes the virtual "requestedAddress" in its virtual address space (already mapped, for unmapping) + * - correct coherency + * + * Returns a pointer to the map or NULL if a suitable map is not found. + */ +PRIVATE IxOsalMemoryMap * +ixOsalMemMapFind (UINT32 requestedAddress, + UINT32 size, UINT32 searchCriteria, UINT32 requestedEndianType) +{ + UINT32 mapIndex; + + UINT32 numMapElements = + sizeof (ixOsalGlobalMemoryMap) / sizeof (IxOsalMemoryMap); + + for (mapIndex = 0; mapIndex < numMapElements; mapIndex++) + { + IxOsalMemoryMap *map = &ixOsalGlobalMemoryMap[mapIndex]; + + if (searchCriteria == SEARCH_PHYSICAL_ADDRESS + && requestedAddress >= map->physicalAddress + && (requestedAddress + size) <= (map->physicalAddress + map->size) + && (map->mapEndianType & requestedEndianType) != 0) + { + return map; + } + else if (searchCriteria == SEARCH_VIRTUAL_ADDRESS + && requestedAddress >= map->virtualAddress + && requestedAddress <= (map->virtualAddress + map->size) + && (map->mapEndianType & requestedEndianType) != 0) + { + return map; + } + else if (searchCriteria == SEARCH_PHYSICAL_ADDRESS) + { + ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, + IX_OSAL_LOG_DEV_STDOUT, + "Osal: Checking [phys addr 0x%x:size 0x%x:endianType %d]\n", + map->physicalAddress, map->size, map->mapEndianType, 0, 0, 0); + } + } + + /* + * not found + */ + return NULL; +} + +/* + * This function maps an I/O mapped physical memory zone of the given size + * into a virtual memory zone accessible by the caller and returns a cookie - + * the start address of the virtual memory zone. + * IX_OSAL_MMAP_PHYS_TO_VIRT should NOT therefore be used on the returned + * virtual address. + * The memory zone is to be unmapped using ixOsalMemUnmap once the caller has + * finished using this zone (e.g. on driver unload) using the cookie as + * parameter. + * The IX_OSAL_READ/WRITE_LONG/SHORT macros should be used to read and write + * the mapped memory, adding the necessary offsets to the address cookie. + * + * Note: this function is not to be used directly. Use IX_OSAL_MEM_MAP + * instead. + */ +PUBLIC void * +ixOsalIoMemMap (UINT32 requestedAddress, + UINT32 size, IxOsalMapEndianessType requestedEndianType) +{ + IxOsalMemoryMap *map; + + ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, + IX_OSAL_LOG_DEV_STDOUT, + "OSAL: Mapping [addr 0x%x:size 0x%x:endianType %d]\n", + requestedAddress, size, requestedEndianType, 0, 0, 0); + + if (requestedEndianType == IX_OSAL_LE) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalIoMemMap: Please specify component coherency mode to use MEM functions \n", + 0, 0, 0, 0, 0, 0); + return (NULL); + } + map = ixOsalMemMapFind (requestedAddress, + size, SEARCH_PHYSICAL_ADDRESS, requestedEndianType); + if (map != NULL) + { + UINT32 offset = requestedAddress - map->physicalAddress; + + ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, + IX_OSAL_LOG_DEV_STDOUT, "OSAL: Found map [", 0, 0, 0, 0, 0, 0); + ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, + IX_OSAL_LOG_DEV_STDOUT, map->name, 0, 0, 0, 0, 0, 0); + ixOsalLog (IX_OSAL_LOG_LVL_DEBUG3, + IX_OSAL_LOG_DEV_STDOUT, + ":addr 0x%x: virt 0x%x:size 0x%x:ref %d:endianType %d]\n", + map->physicalAddress, map->virtualAddress, + map->size, map->refCount, map->mapEndianType, 0); + + if (map->type == IX_OSAL_DYNAMIC_MAP && map->virtualAddress == 0) + { + if (map->mapFunction != NULL) + { + map->mapFunction (map); + + if (map->virtualAddress == 0) + { + /* + * failed + */ + ixOsalLog (IX_OSAL_LOG_LVL_FATAL, + IX_OSAL_LOG_DEV_STDERR, + "OSAL: Remap failed - [addr 0x%x:size 0x%x:endianType %d]\n", + requestedAddress, size, requestedEndianType, 0, 0, 0); + return NULL; + } + } + else + { + /* + * error, no map function for a dynamic map + */ + ixOsalLog (IX_OSAL_LOG_LVL_FATAL, + IX_OSAL_LOG_DEV_STDERR, + "OSAL: No map function for a dynamic map - " + "[addr 0x%x:size 0x%x:endianType %d]\n", + requestedAddress, size, requestedEndianType, 0, 0, 0); + + return NULL; + } + } + + /* + * increment reference count + */ + map->refCount++; + + return (void *) (map->virtualAddress + offset); + } + + /* + * requested address is not described in the global memory map + */ + ixOsalLog (IX_OSAL_LOG_LVL_FATAL, + IX_OSAL_LOG_DEV_STDERR, + "OSAL: No mapping found - [addr 0x%x:size 0x%x:endianType %d]\n", + requestedAddress, size, requestedEndianType, 0, 0, 0); + return NULL; +} + +/* + * This function unmaps a previously mapped I/O memory zone using + * the cookie obtained in the mapping operation. The memory zone in question + * becomes unavailable to the caller once unmapped and the cookie should be + * discarded. + * + * This function cannot fail if the given parameter is correct and does not + * return a value. + * + * Note: this function is not to be used directly. Use IX_OSAL_MEM_UNMAP + * instead. + */ +PUBLIC void +ixOsalIoMemUnmap (UINT32 requestedAddress, UINT32 endianType) +{ + IxOsalMemoryMap *map; + + if (endianType == IX_OSAL_LE) + { + ixOsalLog (IX_OSAL_LOG_LVL_ERROR, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalIoMemUnmap: Please specify component coherency mode to use MEM functions \n", + 0, 0, 0, 0, 0, 0); + return; + } + + if (requestedAddress == 0) + { + /* + * invalid virtual address + */ + return; + } + + map = + ixOsalMemMapFind (requestedAddress, 0, SEARCH_VIRTUAL_ADDRESS, + endianType); + + if (map != NULL) + { + if (map->refCount > 0) + { + /* + * decrement reference count + */ + map->refCount--; + + if (map->refCount == 0) + { + /* + * no longer used, deallocate + */ + if (map->type == IX_OSAL_DYNAMIC_MAP + && map->unmapFunction != NULL) + { + map->unmapFunction (map); + } + } + } + } + else + { + ixOsalLog (IX_OSAL_LOG_LVL_WARNING, + IX_OSAL_LOG_DEV_STDERR, + "OSAL: ixOsServMemUnmap didn't find the requested map " + "[virt addr 0x%x: endianType %d], ignoring call\n", + requestedAddress, endianType, 0, 0, 0, 0); + } +} + +/* + * This function Converts a virtual address into a physical + * address, including the dynamically mapped memory. + * + * Parameters virtAddr - virtual address to convert + * Return value: corresponding physical address, or NULL + * if there is no physical address addressable + * by the given virtual address + * OS: VxWorks, Linux, WinCE, QNX, eCos + * Reentrant: Yes + * IRQ safe: Yes + */ +PUBLIC UINT32 +ixOsalIoMemVirtToPhys (UINT32 virtualAddress, UINT32 requestedCoherency) +{ + IxOsalMemoryMap *map = + ixOsalMemMapFind (virtualAddress, 0, SEARCH_VIRTUAL_ADDRESS, + requestedCoherency); + + if (map != NULL) + { + return map->physicalAddress + virtualAddress - map->virtualAddress; + } + else + { + return (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS (virtualAddress); + } +} + +/* + * This function Converts a virtual address into a physical + * address, including the dynamically mapped memory. + * + * Parameters virtAddr - virtual address to convert + * Return value: corresponding physical address, or NULL + * if there is no physical address addressable + * by the given virtual address + * OS: VxWorks, Linux, WinCE, QNX, eCos + * Reentrant: Yes + * IRQ safe: Yes + */ +PUBLIC UINT32 +ixOsalIoMemPhysToVirt (UINT32 physicalAddress, UINT32 requestedCoherency) +{ + IxOsalMemoryMap *map = + ixOsalMemMapFind (physicalAddress, 0, SEARCH_PHYSICAL_ADDRESS, + requestedCoherency); + + if (map != NULL) + { + return map->virtualAddress + physicalAddress - map->physicalAddress; + } + else + { + return (UINT32) IX_OSAL_MMU_PHYS_TO_VIRT (physicalAddress); + } +} diff --git a/drivers/net/npe/IxOsalOsCacheMMU.c b/drivers/net/npe/IxOsalOsCacheMMU.c new file mode 100644 index 0000000..3db1a70 --- /dev/null +++ b/drivers/net/npe/IxOsalOsCacheMMU.c @@ -0,0 +1,67 @@ +/** + * @file IxOsalOsCacheMMU.c (linux) + * + * @brief Cache MemAlloc and MemFree. + * + * + * @par + * IXP400 SW Release version 1.5 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxOsal.h" + +#include + +/* + * Allocate on a cache line boundary (null pointers are + * not affected by this operation). This operation is NOT cache safe. + */ +void * +ixOsalCacheDmaMalloc (UINT32 n) +{ + return malloc(n); +} + +/* + * + */ +void +ixOsalCacheDmaFree (void *ptr) +{ + free(ptr); +} diff --git a/drivers/net/npe/IxOsalOsMsgQ.c b/drivers/net/npe/IxOsalOsMsgQ.c new file mode 100644 index 0000000..45a5c68 --- /dev/null +++ b/drivers/net/npe/IxOsalOsMsgQ.c @@ -0,0 +1,79 @@ +/** + * @file IxOsalOsMsgQ.c (eCos) + * + * @brief OS-specific Message Queue implementation. + * + * + * @par + * IXP400 SW Release version 1.5 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxOsal.h" + +/******************************* + * Public functions + *******************************/ +PUBLIC IX_STATUS +ixOsalMessageQueueCreate (IxOsalMessageQueue * queue, + UINT32 msgCount, UINT32 msgLen) +{ + diag_printf("%s called\n", __FUNCTION__); + return IX_FAIL; +} + +PUBLIC IX_STATUS +ixOsalMessageQueueDelete (IxOsalMessageQueue * queue) +{ + diag_printf("%s called\n", __FUNCTION__); + return IX_FAIL; +} + +PUBLIC IX_STATUS +ixOsalMessageQueueSend (IxOsalMessageQueue * queue, UINT8 * message) +{ + diag_printf("%s called\n", __FUNCTION__); + return IX_FAIL; +} + +PUBLIC IX_STATUS +ixOsalMessageQueueReceive (IxOsalMessageQueue * queue, UINT8 * message) +{ + diag_printf("%s called\n", __FUNCTION__); + return IX_FAIL; +} + diff --git a/drivers/net/npe/IxOsalOsSemaphore.c b/drivers/net/npe/IxOsalOsSemaphore.c new file mode 100644 index 0000000..443aefd --- /dev/null +++ b/drivers/net/npe/IxOsalOsSemaphore.c @@ -0,0 +1,233 @@ +/** + * @file IxOsalOsSemaphore.c (eCos) + * + * @brief Implementation for semaphore and mutex. + * + * + * @par + * IXP400 SW Release version 1.5 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxOsal.h" +#include "IxNpeMhReceive_p.h" + +/* Define a large number */ +#define IX_OSAL_MAX_LONG (0x7FFFFFFF) + +/* Max timeout in MS, used to guard against possible overflow */ +#define IX_OSAL_MAX_TIMEOUT_MS (IX_OSAL_MAX_LONG/HZ) + + +PUBLIC IX_STATUS +ixOsalSemaphoreInit (IxOsalSemaphore * sid, UINT32 start_value) +{ + diag_printf("%s called\n", __FUNCTION__); + return IX_SUCCESS; +} + +/** + * DESCRIPTION: If the semaphore is 'empty', the calling thread is blocked. + * If the semaphore is 'full', it is taken and control is returned + * to the caller. If the time indicated in 'timeout' is reached, + * the thread will unblock and return an error indication. If the + * timeout is set to 'IX_OSAL_WAIT_NONE', the thread will never block; + * if it is set to 'IX_OSAL_WAIT_FOREVER', the thread will block until + * the semaphore is available. + * + * + */ + + +PUBLIC IX_STATUS +ixOsalSemaphoreWait (IxOsalOsSemaphore * sid, INT32 timeout) +{ + diag_printf("%s called\n", __FUNCTION__); + return IX_SUCCESS; +} + +/* + * Attempt to get semaphore, return immediately, + * no error info because users expect some failures + * when using this API. + */ +PUBLIC IX_STATUS +ixOsalSemaphoreTryWait (IxOsalSemaphore * sid) +{ + diag_printf("%s called\n", __FUNCTION__); + return IX_FAIL; +} + +/** + * + * DESCRIPTION: This function causes the next available thread in the pend queue + * to be unblocked. If no thread is pending on this semaphore, the + * semaphore becomes 'full'. + */ +PUBLIC IX_STATUS +ixOsalSemaphorePost (IxOsalSemaphore * sid) +{ + diag_printf("%s called\n", __FUNCTION__); + return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixOsalSemaphoreGetValue (IxOsalSemaphore * sid, UINT32 * value) +{ + diag_printf("%s called\n", __FUNCTION__); + return IX_FAIL; +} + +PUBLIC IX_STATUS +ixOsalSemaphoreDestroy (IxOsalSemaphore * sid) +{ + diag_printf("%s called\n", __FUNCTION__); + return IX_FAIL; +} + +/**************************** + * Mutex + ****************************/ + +static void drv_mutex_init(IxOsalMutex *mutex) +{ + *mutex = 0; +} + +static void drv_mutex_destroy(IxOsalMutex *mutex) +{ + *mutex = -1; +} + +static int drv_mutex_trylock(IxOsalMutex *mutex) +{ + int result = TRUE; + + if (*mutex == 1) + result = FALSE; + + return result; +} + +static void drv_mutex_unlock(IxOsalMutex *mutex) +{ + if (*mutex == 1) + printf("Trying to unlock unlocked mutex!"); + + *mutex = 0; +} + +PUBLIC IX_STATUS +ixOsalMutexInit (IxOsalMutex * mutex) +{ + drv_mutex_init(mutex); + return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixOsalMutexLock (IxOsalMutex * mutex, INT32 timeout) +{ + int tries; + + if (timeout == IX_OSAL_WAIT_NONE) { + if (drv_mutex_trylock(mutex)) + return IX_SUCCESS; + else + return IX_FAIL; + } + + tries = (timeout * 1000) / 50; + while (1) { + if (drv_mutex_trylock(mutex)) + return IX_SUCCESS; + if (timeout != IX_OSAL_WAIT_FOREVER && tries-- <= 0) + break; + udelay(50); + } + return IX_FAIL; +} + +PUBLIC IX_STATUS +ixOsalMutexUnlock (IxOsalMutex * mutex) +{ + drv_mutex_unlock(mutex); + return IX_SUCCESS; +} + +/* + * Attempt to get mutex, return immediately, + * no error info because users expect some failures + * when using this API. + */ +PUBLIC IX_STATUS +ixOsalMutexTryLock (IxOsalMutex * mutex) +{ + if (drv_mutex_trylock(mutex)) + return IX_SUCCESS; + return IX_FAIL; +} + +PUBLIC IX_STATUS +ixOsalMutexDestroy (IxOsalMutex * mutex) +{ + drv_mutex_destroy(mutex); + return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixOsalFastMutexInit (IxOsalFastMutex * mutex) +{ + return ixOsalMutexInit(mutex); +} + +PUBLIC IX_STATUS ixOsalFastMutexTryLock(IxOsalFastMutex *mutex) +{ + return ixOsalMutexTryLock(mutex); +} + + +PUBLIC IX_STATUS +ixOsalFastMutexUnlock (IxOsalFastMutex * mutex) +{ + return ixOsalMutexUnlock(mutex); +} + +PUBLIC IX_STATUS +ixOsalFastMutexDestroy (IxOsalFastMutex * mutex) +{ + return ixOsalMutexDestroy(mutex); +} diff --git a/drivers/net/npe/IxOsalOsServices.c b/drivers/net/npe/IxOsalOsServices.c new file mode 100644 index 0000000..e18c6c4 --- /dev/null +++ b/drivers/net/npe/IxOsalOsServices.c @@ -0,0 +1,251 @@ +/** + * @file IxOsalOsServices.c (linux) + * + * @brief Implementation for Irq, Mem, sleep. + * + * + * @par + * IXP400 SW Release version 1.5 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include +#include +#include "IxOsal.h" +#include +#include +#include +#include +#include + +static char *traceHeaders[] = { + "", + "[fatal] ", + "[error] ", + "[warning] ", + "[message] ", + "[debug1] ", + "[debug2] ", + "[debug3] ", + "[all]" +}; + +/* by default trace all but debug message */ +PRIVATE int ixOsalCurrLogLevel = IX_OSAL_LOG_LVL_MESSAGE; + +/************************************** + * Irq services + *************************************/ + +PUBLIC IX_STATUS +ixOsalIrqBind (UINT32 vector, IxOsalVoidFnVoidPtr routine, void *parameter) +{ + return IX_FAIL; +} + +PUBLIC IX_STATUS +ixOsalIrqUnbind (UINT32 vector) +{ + return IX_FAIL; +} + +PUBLIC UINT32 +ixOsalIrqLock () +{ + return 0; +} + +/* Enable interrupts and task scheduling, + * input parameter: irqEnable status returned + * by ixOsalIrqLock(). + */ +PUBLIC void +ixOsalIrqUnlock (UINT32 lockKey) +{ +} + +PUBLIC UINT32 +ixOsalIrqLevelSet (UINT32 level) +{ + return IX_FAIL; +} + +PUBLIC void +ixOsalIrqEnable (UINT32 irqLevel) +{ +} + +PUBLIC void +ixOsalIrqDisable (UINT32 irqLevel) +{ +} + +/********************* + * Log function + *********************/ + +INT32 +ixOsalLog (IxOsalLogLevel level, + IxOsalLogDevice device, + char *format, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6) +{ + /* + * Return -1 for custom display devices + */ + if ((device != IX_OSAL_LOG_DEV_STDOUT) + && (device != IX_OSAL_LOG_DEV_STDERR)) + { + debug("ixOsalLog: only IX_OSAL_LOG_DEV_STDOUT and IX_OSAL_LOG_DEV_STDERR are supported \n"); + return (IX_OSAL_LOG_ERROR); + } + + if (level <= ixOsalCurrLogLevel && level != IX_OSAL_LOG_LVL_NONE) + { +#if 0 /* sr: U-Boots printf or debug doesn't return a length */ + int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : diag_printf(traceHeaders[level - 1]); + + return headerByteCount + diag_printf (format, arg1, arg2, arg3, arg4, arg5, arg6); +#else + int headerByteCount = (level == IX_OSAL_LOG_LVL_USER) ? 0 : strlen(traceHeaders[level - 1]); + + return headerByteCount + strlen(format); +#endif + } + else + { + /* + * Return error + */ + return (IX_OSAL_LOG_ERROR); + } +} + +PUBLIC UINT32 +ixOsalLogLevelSet (UINT32 level) +{ + UINT32 oldLevel; + + /* + * Check value first + */ + if ((level < IX_OSAL_LOG_LVL_NONE) || (level > IX_OSAL_LOG_LVL_ALL)) + { + ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE, + IX_OSAL_LOG_DEV_STDOUT, + "ixOsalLogLevelSet: Log Level is between %d and%d \n", + IX_OSAL_LOG_LVL_NONE, IX_OSAL_LOG_LVL_ALL, 0, 0, 0, 0); + return IX_OSAL_LOG_LVL_NONE; + } + oldLevel = ixOsalCurrLogLevel; + + ixOsalCurrLogLevel = level; + + return oldLevel; +} + +/************************************** + * Task services + *************************************/ + +PUBLIC void +ixOsalBusySleep (UINT32 microseconds) +{ + udelay(microseconds); +} + +PUBLIC void +ixOsalSleep (UINT32 milliseconds) +{ + if (milliseconds != 0) { +#if 1 + /* + * sr: We poll while we wait because interrupts are off in U-Boot + * and CSR expects messages, etc to be dispatched while sleeping. + */ + int i; + IxQMgrDispatcherFuncPtr qDispatcherFunc; + + ixQMgrDispatcherLoopGet(&qDispatcherFunc); + + while (milliseconds--) { + for (i = 1; i <= 2; i++) + ixNpeMhMessagesReceive(i); + (*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP); + + udelay(1000); + } +#endif + } +} + +/************************************** + * Memory functions + *************************************/ + +void * +ixOsalMemAlloc (UINT32 size) +{ + return (void *)0; +} + +void +ixOsalMemFree (void *ptr) +{ +} + +/* + * Copy count bytes from src to dest , + * returns pointer to the dest mem zone. + */ +void * +ixOsalMemCopy (void *dest, void *src, UINT32 count) +{ + IX_OSAL_ASSERT (dest != NULL); + IX_OSAL_ASSERT (src != NULL); + return (memcpy (dest, src, count)); +} + +/* + * Fills a memory zone with a given constant byte, + * returns pointer to the memory zone. + */ +void * +ixOsalMemSet (void *ptr, UINT8 filler, UINT32 count) +{ + IX_OSAL_ASSERT (ptr != NULL); + return (memset (ptr, filler, count)); +} diff --git a/drivers/net/npe/IxOsalOsThread.c b/drivers/net/npe/IxOsalOsThread.c new file mode 100644 index 0000000..e6a4967 --- /dev/null +++ b/drivers/net/npe/IxOsalOsThread.c @@ -0,0 +1,98 @@ +/** + * @file IxOsalOsThread.c (eCos) + * + * @brief OS-specific thread implementation. + * + * + * @par + * IXP400 SW Release version 1.5 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include "IxOsal.h" + +/* Thread attribute is ignored */ +PUBLIC IX_STATUS +ixOsalThreadCreate (IxOsalThread * ptrTid, + IxOsalThreadAttr * threadAttr, IxOsalVoidFnVoidPtr entryPoint, void *arg) +{ + return IX_SUCCESS; +} + +/* + * Start thread after given its thread handle + */ +PUBLIC IX_STATUS +ixOsalThreadStart (IxOsalThread * tId) +{ + /* Thread already started upon creation */ + return IX_SUCCESS; +} + +/* + * In Linux threadKill does not actually destroy the thread, + * it will stop the signal handling. + */ +PUBLIC IX_STATUS +ixOsalThreadKill (IxOsalThread * tid) +{ + return IX_SUCCESS; +} + +PUBLIC void +ixOsalThreadExit (void) +{ +} + +PUBLIC IX_STATUS +ixOsalThreadPrioritySet (IxOsalOsThread * tid, UINT32 priority) +{ + return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixOsalThreadSuspend (IxOsalThread * tId) +{ + return IX_SUCCESS; + +} + +PUBLIC IX_STATUS +ixOsalThreadResume (IxOsalThread * tId) +{ + return IX_SUCCESS; +} diff --git a/drivers/net/npe/IxQMgrAqmIf.c b/drivers/net/npe/IxQMgrAqmIf.c new file mode 100644 index 0000000..7386513 --- /dev/null +++ b/drivers/net/npe/IxQMgrAqmIf.c @@ -0,0 +1,963 @@ +/* + * @file: IxQMgrAqmIf.c + * + * @author Intel Corporation + * @date 30-Oct-2001 + * + * @brief This component provides a set of functions for + * perfoming I/O on the AQM hardware. + * + * Design Notes: + * These functions are intended to be as fast as possible + * and as a result perform NO PARAMETER CHECKING. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * Inlines are compiled as function when this is defined. + * N.B. Must be placed before #include of "IxQMgrAqmIf_p.h + */ +#ifndef IXQMGRAQMIF_P_H +# define IXQMGRAQMIF_C +#else +# error +#endif + +/* + * User defined include files. + */ +#include "IxOsal.h" +#include "IxQMgr.h" +#include "IxQMgrAqmIf_p.h" +#include "IxQMgrLog_p.h" + + +/* + * #defines and macros used in this file. + */ + +/* These defines are the bit offsets of the various fields of + * the queue configuration register + */ +#define IX_QMGR_Q_CONFIG_WRPTR_OFFSET 0x00 +#define IX_QMGR_Q_CONFIG_RDPTR_OFFSET 0x07 +#define IX_QMGR_Q_CONFIG_BADDR_OFFSET 0x0E +#define IX_QMGR_Q_CONFIG_ESIZE_OFFSET 0x16 +#define IX_QMGR_Q_CONFIG_BSIZE_OFFSET 0x18 +#define IX_QMGR_Q_CONFIG_NE_OFFSET 0x1A +#define IX_QMGR_Q_CONFIG_NF_OFFSET 0x1D + +#define IX_QMGR_BASE_ADDR_16_WORD_ALIGN 0x40 +#define IX_QMGR_BASE_ADDR_16_WORD_SHIFT 0x6 + +#define IX_QMGR_NE_NF_CLEAR_MASK 0x03FFFFFF +#define IX_QMGR_NE_MASK 0x7 +#define IX_QMGR_NF_MASK 0x7 +#define IX_QMGR_SIZE_MASK 0x3 +#define IX_QMGR_ENTRY_SIZE_MASK 0x3 +#define IX_QMGR_BADDR_MASK 0x003FC000 +#define IX_QMGR_RDPTR_MASK 0x7F +#define IX_QMGR_WRPTR_MASK 0x7F +#define IX_QMGR_RDWRPTR_MASK 0x00003FFF + +#define IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS 0x1000 + +/* Base address of AQM SRAM */ +#define IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET \ +((IX_QMGR_QUECONFIG_BASE_OFFSET) + (IX_QMGR_QUECONFIG_SIZE)) + +/* Min buffer size used for generating buffer size in QUECONFIG */ +#define IX_QMGR_MIN_BUFFER_SIZE 16 + +/* Reset values of QMgr hardware registers */ +#define IX_QMGR_QUELOWSTAT_RESET_VALUE 0x33333333 +#define IX_QMGR_QUEUOSTAT_RESET_VALUE 0x00000000 +#define IX_QMGR_QUEUPPSTAT0_RESET_VALUE 0xFFFFFFFF +#define IX_QMGR_QUEUPPSTAT1_RESET_VALUE 0x00000000 +#define IX_QMGR_INT0SRCSELREG_RESET_VALUE 0x00000000 +#define IX_QMGR_QUEIEREG_RESET_VALUE 0x00000000 +#define IX_QMGR_QINTREG_RESET_VALUE 0xFFFFFFFF +#define IX_QMGR_QUECONFIG_RESET_VALUE 0x00000000 + +#define IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS IX_OSAL_IXP400_QMGR_PHYS_BASE + +#define IX_QMGR_QUELOWSTAT_BITS_PER_Q (BITS_PER_WORD/IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) + +#define IX_QMGR_QUELOWSTAT_QID_MASK 0x7 +#define IX_QMGR_Q_CONFIG_ADDR_GET(qId)\ + (((qId) * IX_QMGR_NUM_BYTES_PER_WORD) +\ + IX_QMGR_QUECONFIG_BASE_OFFSET) + +#define IX_QMGR_ENTRY1_OFFSET 0 +#define IX_QMGR_ENTRY2_OFFSET 1 +#define IX_QMGR_ENTRY4_OFFSET 3 + +/* + * Variable declarations global to this file. Externs are followed by + * statics. + */ +UINT32 aqmBaseAddress = 0; +/* Store addresses and bit-masks for certain queue access and status registers. + * This is to facilitate inlining of QRead, QWrite and QStatusGet functions + * in IxQMgr,h + */ +extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; +UINT32 * ixQMgrAqmIfQueAccRegAddr[IX_QMGR_MAX_NUM_QUEUES]; +UINT32 ixQMgrAqmIfQueLowStatRegAddr[IX_QMGR_MIN_QUEUPP_QID]; +UINT32 ixQMgrAqmIfQueLowStatBitsOffset[IX_QMGR_MIN_QUEUPP_QID]; +UINT32 ixQMgrAqmIfQueLowStatBitsMask; +UINT32 ixQMgrAqmIfQueUppStat0RegAddr; +UINT32 ixQMgrAqmIfQueUppStat1RegAddr; +UINT32 ixQMgrAqmIfQueUppStat0BitMask[IX_QMGR_MIN_QUEUPP_QID]; +UINT32 ixQMgrAqmIfQueUppStat1BitMask[IX_QMGR_MIN_QUEUPP_QID]; + +/* + * Fast mutexes, one for each queue, used to protect peek & poke functions + */ +IxOsalFastMutex ixQMgrAqmIfPeekPokeFastMutex[IX_QMGR_MAX_NUM_QUEUES]; + +/* + * Function prototypes + */ +PRIVATE unsigned +watermarkToAqmWatermark (IxQMgrWMLevel watermark ); + +PRIVATE unsigned +entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize); + +PRIVATE unsigned +bufferSizeToAqmBufferSize (unsigned bufferSizeInWords); + +PRIVATE void +ixQMgrAqmIfRegistersReset (void); + +PRIVATE void +ixQMgrAqmIfEntryAddressGet (unsigned int entryIndex, + UINT32 configRegWord, + unsigned int qEntrySizeInwords, + unsigned int qSizeInWords, + UINT32 **address); +/* + * Function definitions + */ +void +ixQMgrAqmIfInit (void) +{ + UINT32 aqmVirtualAddr; + int i; + + /* The value of aqmBaseAddress depends on the logical address + * assigned by the MMU. + */ + aqmVirtualAddr = + (UINT32) IX_OSAL_MEM_MAP(IX_QMGR_PHYSICAL_AQM_BASE_ADDRESS, + IX_OSAL_IXP400_QMGR_MAP_SIZE); + IX_OSAL_ASSERT (aqmVirtualAddr); + + ixQMgrAqmIfBaseAddressSet (aqmVirtualAddr); + + ixQMgrAqmIfRegistersReset (); + + for (i = 0; i< IX_QMGR_MAX_NUM_QUEUES; i++) + { + ixOsalFastMutexInit(&ixQMgrAqmIfPeekPokeFastMutex[i]); + + /******************************************************************** + * Register addresses and bit masks are calculated and stored here to + * facilitate inlining of QRead, QWrite and QStatusGet functions in + * IxQMgr.h. + * These calculations are normally performed dynamically in inlined + * functions in IxQMgrAqmIf_p.h, and their semantics are reused here. + */ + + /* AQM Queue access reg addresses, per queue */ + ixQMgrAqmIfQueAccRegAddr[i] = + (UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i)); + ixQMgrQInlinedReadWriteInfo[i].qAccRegAddr = + (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_ACCESS_ADDR_GET(i)); + + + ixQMgrQInlinedReadWriteInfo[i].qConfigRegAddr = + (volatile UINT32 *)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(i)); + + /* AQM Queue lower-group (0-31), only */ + if (i < IX_QMGR_MIN_QUEUPP_QID) + { + /* AQM Q underflow/overflow status register addresses, per queue */ + ixQMgrQInlinedReadWriteInfo[i].qUOStatRegAddr = + (volatile UINT32 *)(aqmBaseAddress + + IX_QMGR_QUEUOSTAT0_OFFSET + + ((i / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD) * + IX_QMGR_NUM_BYTES_PER_WORD)); + + /* AQM Q underflow status bit masks for status register per queue */ + ixQMgrQInlinedReadWriteInfo[i].qUflowStatBitMask = + (IX_QMGR_UNDERFLOW_BIT_OFFSET + 1) << + ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) * + (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD)); + + /* AQM Q overflow status bit masks for status register, per queue */ + ixQMgrQInlinedReadWriteInfo[i].qOflowStatBitMask = + (IX_QMGR_OVERFLOW_BIT_OFFSET + 1) << + ((i & (IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD - 1)) * + (BITS_PER_WORD / IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD)); + + /* AQM Q lower-group (0-31) status register addresses, per queue */ + ixQMgrAqmIfQueLowStatRegAddr[i] = aqmBaseAddress + + IX_QMGR_QUELOWSTAT0_OFFSET + + ((i / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) * + IX_QMGR_NUM_BYTES_PER_WORD); + + /* AQM Q lower-group (0-31) status register bit offset */ + ixQMgrAqmIfQueLowStatBitsOffset[i] = + (i & (IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD - 1)) * + (BITS_PER_WORD / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD); + } + else /* AQM Q upper-group (32-63), only */ + { + /* AQM Q upper-group (32-63) Nearly Empty status reg bit masks */ + ixQMgrAqmIfQueUppStat0BitMask[i - IX_QMGR_MIN_QUEUPP_QID] = + (1 << (i - IX_QMGR_MIN_QUEUPP_QID)); + + /* AQM Q upper-group (32-63) Full status register bit masks */ + ixQMgrAqmIfQueUppStat1BitMask[i - IX_QMGR_MIN_QUEUPP_QID] = + (1 << (i - IX_QMGR_MIN_QUEUPP_QID)); + } + } + + /* AQM Q lower-group (0-31) status register bit mask */ + ixQMgrAqmIfQueLowStatBitsMask = (1 << + (BITS_PER_WORD / + IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)) - 1; + + /* AQM Q upper-group (32-63) Nearly Empty status register address */ + ixQMgrAqmIfQueUppStat0RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET; + + /* AQM Q upper-group (32-63) Full status register address */ + ixQMgrAqmIfQueUppStat1RegAddr = aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET; +} + +/* + * Uninitialise the AqmIf module by unmapping memory, etc + */ +void +ixQMgrAqmIfUninit (void) +{ + UINT32 virtAddr; + + ixQMgrAqmIfBaseAddressGet (&virtAddr); + IX_OSAL_MEM_UNMAP (virtAddr); + ixQMgrAqmIfBaseAddressSet (0); +} + +/* + * Set the the logical base address of AQM + */ +void +ixQMgrAqmIfBaseAddressSet (UINT32 address) +{ + aqmBaseAddress = address; +} + +/* + * Get the logical base address of AQM + */ +void +ixQMgrAqmIfBaseAddressGet (UINT32 *address) +{ + *address = aqmBaseAddress; +} + +/* + * Get the logical base address of AQM SRAM + */ +void +ixQMgrAqmIfSramBaseAddressGet (UINT32 *address) +{ + *address = aqmBaseAddress + + IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET; +} + +/* + * This function will write the status bits of a queue + * specified by qId. + */ +void +ixQMgrAqmIfQRegisterBitsWrite (IxQMgrQId qId, + UINT32 registerBaseAddrOffset, + unsigned queuesPerRegWord, + UINT32 value) +{ + volatile UINT32 *registerAddress; + UINT32 registerWord; + UINT32 statusBitsMask; + UINT32 bitsPerQueue; + + bitsPerQueue = BITS_PER_WORD / queuesPerRegWord; + + /* + * Calculate the registerAddress + * multiple queues split accross registers + */ + registerAddress = (UINT32*)(aqmBaseAddress + + registerBaseAddrOffset + + ((qId / queuesPerRegWord) * + IX_QMGR_NUM_BYTES_PER_WORD)); + + /* Read the current data */ + ixQMgrAqmIfWordRead (registerAddress, ®isterWord); + + + if( (registerBaseAddrOffset == IX_QMGR_INT0SRCSELREG0_OFFSET) && + (qId == IX_QMGR_QUEUE_0) ) + { + statusBitsMask = 0x7 ; + + /* Queue 0 at INT0SRCSELREG should not corrupt the value bit-3 */ + value &= 0x7 ; + } + else + { + /* Calculate the mask for the status bits for this queue. */ + statusBitsMask = ((1 << bitsPerQueue) - 1); + statusBitsMask <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue); + + /* Mask out bits in value that would overwrite other q data */ + value <<= ((qId & (queuesPerRegWord - 1)) * bitsPerQueue); + value &= statusBitsMask; + } + + /* Mask out bits to write to */ + registerWord &= ~statusBitsMask; + + + /* Set the write bits */ + registerWord |= value; + + /* + * Write the data + */ + ixQMgrAqmIfWordWrite (registerAddress, registerWord); +} + +/* + * This function generates the parameters that can be used to + * check if a Qs status matches the specified source select. + * It calculates which status word to check (statusWordOffset), + * the value to check the status against (checkValue) and the + * mask (mask) to mask out all but the bits to check in the status word. + */ +void +ixQMgrAqmIfQStatusCheckValsCalc (IxQMgrQId qId, + IxQMgrSourceId srcSel, + unsigned int *statusWordOffset, + UINT32 *checkValue, + UINT32 *mask) +{ + UINT32 shiftVal; + + if (qId < IX_QMGR_MIN_QUEUPP_QID) + { + switch (srcSel) + { + case IX_QMGR_Q_SOURCE_ID_E: + *checkValue = IX_QMGR_Q_STATUS_E_BIT_MASK; + *mask = IX_QMGR_Q_STATUS_E_BIT_MASK; + break; + case IX_QMGR_Q_SOURCE_ID_NE: + *checkValue = IX_QMGR_Q_STATUS_NE_BIT_MASK; + *mask = IX_QMGR_Q_STATUS_NE_BIT_MASK; + break; + case IX_QMGR_Q_SOURCE_ID_NF: + *checkValue = IX_QMGR_Q_STATUS_NF_BIT_MASK; + *mask = IX_QMGR_Q_STATUS_NF_BIT_MASK; + break; + case IX_QMGR_Q_SOURCE_ID_F: + *checkValue = IX_QMGR_Q_STATUS_F_BIT_MASK; + *mask = IX_QMGR_Q_STATUS_F_BIT_MASK; + break; + case IX_QMGR_Q_SOURCE_ID_NOT_E: + *checkValue = 0; + *mask = IX_QMGR_Q_STATUS_E_BIT_MASK; + break; + case IX_QMGR_Q_SOURCE_ID_NOT_NE: + *checkValue = 0; + *mask = IX_QMGR_Q_STATUS_NE_BIT_MASK; + break; + case IX_QMGR_Q_SOURCE_ID_NOT_NF: + *checkValue = 0; + *mask = IX_QMGR_Q_STATUS_NF_BIT_MASK; + break; + case IX_QMGR_Q_SOURCE_ID_NOT_F: + *checkValue = 0; + *mask = IX_QMGR_Q_STATUS_F_BIT_MASK; + break; + default: + /* Should never hit */ + IX_OSAL_ASSERT(0); + break; + } + + /* One nibble of status per queue so need to shift the + * check value and mask out to the correct position. + */ + shiftVal = (qId % IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD) * + IX_QMGR_QUELOWSTAT_BITS_PER_Q; + + /* Calculate the which status word to check from the qId, + * 8 Qs status per word + */ + *statusWordOffset = qId / IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD; + + *checkValue <<= shiftVal; + *mask <<= shiftVal; + } + else + { + /* One status word */ + *statusWordOffset = 0; + /* Single bits per queue and int source bit hardwired NE, + * Qs start at 32. + */ + *mask = 1 << (qId - IX_QMGR_MIN_QUEUPP_QID); + *checkValue = *mask; + } +} + +void +ixQMgrAqmIfQInterruptEnable (IxQMgrQId qId) +{ + volatile UINT32 *registerAddress; + UINT32 registerWord; + UINT32 actualBitOffset; + + if (qId < IX_QMGR_MIN_QUEUPP_QID) + { + registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET); + } + else + { + registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET); + } + + actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID); + + ixQMgrAqmIfWordRead (registerAddress, ®isterWord); + ixQMgrAqmIfWordWrite (registerAddress, (registerWord | actualBitOffset)); +} + +void +ixQMgrAqmIfQInterruptDisable (IxQMgrQId qId) +{ + volatile UINT32 *registerAddress; + UINT32 registerWord; + UINT32 actualBitOffset; + + if (qId < IX_QMGR_MIN_QUEUPP_QID) + { + registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET); + } + else + { + registerAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET); + } + + actualBitOffset = 1 << (qId % IX_QMGR_MIN_QUEUPP_QID); + + ixQMgrAqmIfWordRead (registerAddress, ®isterWord); + ixQMgrAqmIfWordWrite (registerAddress, registerWord & (~actualBitOffset)); +} + +void +ixQMgrAqmIfQueCfgWrite (IxQMgrQId qId, + IxQMgrQSizeInWords qSizeInWords, + IxQMgrQEntrySizeInWords entrySizeInWords, + UINT32 freeSRAMAddress) +{ + volatile UINT32 *cfgAddress = NULL; + UINT32 qCfg = 0; + UINT32 baseAddress = 0; + unsigned aqmEntrySize = 0; + unsigned aqmBufferSize = 0; + + /* Build config register */ + aqmEntrySize = entrySizeToAqmEntrySize (entrySizeInWords); + qCfg |= (aqmEntrySize&IX_QMGR_ENTRY_SIZE_MASK) << + IX_QMGR_Q_CONFIG_ESIZE_OFFSET; + + aqmBufferSize = bufferSizeToAqmBufferSize (qSizeInWords); + qCfg |= (aqmBufferSize&IX_QMGR_SIZE_MASK) << IX_QMGR_Q_CONFIG_BSIZE_OFFSET; + + /* baseAddress, calculated relative to aqmBaseAddress and start address */ + baseAddress = freeSRAMAddress - + (aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET); + + /* Verify base address aligned to a 16 word boundary */ + if ((baseAddress % IX_QMGR_BASE_ADDR_16_WORD_ALIGN) != 0) + { + IX_QMGR_LOG_ERROR0("ixQMgrAqmIfQueCfgWrite () address is not on 16 word boundary\n"); + } + /* Now convert it to a 16 word pointer as required by QUECONFIG register */ + baseAddress >>= IX_QMGR_BASE_ADDR_16_WORD_SHIFT; + + + qCfg |= (baseAddress << IX_QMGR_Q_CONFIG_BADDR_OFFSET); + + + cfgAddress = (UINT32*)(aqmBaseAddress + + IX_QMGR_Q_CONFIG_ADDR_GET(qId)); + + + /* NOTE: High and Low watermarks are set to zero */ + ixQMgrAqmIfWordWrite (cfgAddress, qCfg); +} + +void +ixQMgrAqmIfQueCfgRead (IxQMgrQId qId, + unsigned int numEntries, + UINT32 *baseAddress, + unsigned int *ne, + unsigned int *nf, + UINT32 *readPtr, + UINT32 *writePtr) +{ + UINT32 qcfg; + UINT32 *cfgAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId)); + unsigned int qEntrySizeInwords; + unsigned int qSizeInWords; + UINT32 *readPtr_ = NULL; + + /* Read the queue configuration register */ + ixQMgrAqmIfWordRead (cfgAddress, &qcfg); + + /* Extract the base address */ + *baseAddress = (UINT32)((qcfg & IX_QMGR_BADDR_MASK) >> + (IX_QMGR_Q_CONFIG_BADDR_OFFSET)); + + /* Base address is a 16 word pointer from the start of AQM SRAM. + * Convert to absolute word address. + */ + *baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT; + *baseAddress += (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET; + + /* + * Extract the watermarks. 0->0 entries, 1->1 entries, 2->2 entries, 3->4 entries...... + * If ne > 0 ==> neInEntries = 2^(ne - 1) + * If ne == 0 ==> neInEntries = 0 + * The same applies. + */ + *ne = ((qcfg) >> (IX_QMGR_Q_CONFIG_NE_OFFSET)) & IX_QMGR_NE_MASK; + *nf = ((qcfg) >> (IX_QMGR_Q_CONFIG_NF_OFFSET)) & IX_QMGR_NF_MASK; + + if (0 != *ne) + { + *ne = 1 << (*ne - 1); + } + if (0 != *nf) + { + *nf = 1 << (*nf - 1); + } + + /* Get the queue entry size in words */ + qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId); + + /* Get the queue size in words */ + qSizeInWords = ixQMgrQSizeInWordsGet (qId); + + ixQMgrAqmIfEntryAddressGet (0/* Entry 0. i.e the readPtr*/, + qcfg, + qEntrySizeInwords, + qSizeInWords, + &readPtr_); + *readPtr = (UINT32)readPtr_; + *readPtr -= (UINT32)aqmBaseAddress;/* Offset, not absolute address */ + + *writePtr = (qcfg >> IX_QMGR_Q_CONFIG_WRPTR_OFFSET) & IX_QMGR_WRPTR_MASK; + *writePtr = *baseAddress + (*writePtr * (IX_QMGR_NUM_BYTES_PER_WORD)); + return; +} + +unsigned +ixQMgrAqmIfLog2 (unsigned number) +{ + unsigned count = 0; + + /* + * N.B. this function will return 0 + * for ixQMgrAqmIfLog2 (0) + */ + while (number/2) + { + number /=2; + count++; + } + + return count; +} + +void ixQMgrAqmIfIntSrcSelReg0Bit3Set (void) +{ + + volatile UINT32 *registerAddress; + UINT32 registerWord; + + /* + * Calculate the registerAddress + * multiple queues split accross registers + */ + registerAddress = (UINT32*)(aqmBaseAddress + + IX_QMGR_INT0SRCSELREG0_OFFSET); + + /* Read the current data */ + ixQMgrAqmIfWordRead (registerAddress, ®isterWord); + + /* Set the write bits */ + registerWord |= (1<> + (IX_QMGR_Q_CONFIG_BADDR_OFFSET)); + + /* Base address is a 16 word pointer from the start of AQM SRAM. + * Convert to absolute word address. + */ + baseAddress <<= IX_QMGR_BASE_ADDR_16_WORD_SHIFT; + baseAddress += ((UINT32)aqmBaseAddress + (UINT32)IX_QMGR_QUECONFIG_BASE_OFFSET); + + /* Extract the read pointer. Read pointer is a word pointer */ + readPtr = (UINT32)((configRegWord >> + IX_QMGR_Q_CONFIG_RDPTR_OFFSET)&IX_QMGR_RDPTR_MASK); + + /* Read/Write pointers(word pointers) are offsets from the queue buffer space base address. + * Calculate the absolute read pointer address. NOTE: Queues are circular buffers. + */ + readPtr = (readPtr + (entryIndex * qEntrySizeInwords)) & (qSizeInWords - 1); /* Mask by queue size */ + *address = (UINT32 *)(baseAddress + (readPtr * (IX_QMGR_NUM_BYTES_PER_WORD))); + + switch (qEntrySizeInwords) + { + case IX_QMGR_Q_ENTRY_SIZE1: + IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY1_OFFSET) < topOfAqmSram); + break; + case IX_QMGR_Q_ENTRY_SIZE2: + IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY2_OFFSET) < topOfAqmSram); + break; + case IX_QMGR_Q_ENTRY_SIZE4: + IX_OSAL_ASSERT((*address + IX_QMGR_ENTRY4_OFFSET) < topOfAqmSram); + break; + default: + IX_QMGR_LOG_ERROR0("Invalid Q Entry size passed to ixQMgrAqmIfEntryAddressGet"); + break; + } + +} + +IX_STATUS +ixQMgrAqmIfQPeek (IxQMgrQId qId, + unsigned int entryIndex, + unsigned int *entry) +{ + UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId)); + UINT32 *entryAddress = NULL; + UINT32 configRegWordOnEntry; + UINT32 configRegWordOnExit; + unsigned int qEntrySizeInwords; + unsigned int qSizeInWords; + + /* Get the queue entry size in words */ + qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId); + + /* Get the queue size in words */ + qSizeInWords = ixQMgrQSizeInWordsGet (qId); + + /* Read the config register */ + ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry); + + /* Get the entry address */ + ixQMgrAqmIfEntryAddressGet (entryIndex, + configRegWordOnEntry, + qEntrySizeInwords, + qSizeInWords, + &entryAddress); + + /* Get the lock or return busy */ + if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId])) + { + return IX_FAIL; + } + + while(qEntrySizeInwords--) + { + ixQMgrAqmIfWordRead (entryAddress++, entry++); + } + + /* Release the lock */ + ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]); + + /* Read the config register */ + ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit); + + /* Check that the read and write pointers have not changed */ + if (configRegWordOnEntry != configRegWordOnExit) + { + return IX_FAIL; + } + + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrAqmIfQPoke (IxQMgrQId qId, + unsigned entryIndex, + unsigned int *entry) +{ + UINT32 *cfgRegAddress = (UINT32*)(aqmBaseAddress + IX_QMGR_Q_CONFIG_ADDR_GET(qId)); + UINT32 *entryAddress = NULL; + UINT32 configRegWordOnEntry; + UINT32 configRegWordOnExit; + unsigned int qEntrySizeInwords; + unsigned int qSizeInWords; + + /* Get the queue entry size in words */ + qEntrySizeInwords = ixQMgrQEntrySizeInWordsGet (qId); + + /* Get the queue size in words */ + qSizeInWords = ixQMgrQSizeInWordsGet (qId); + + /* Read the config register */ + ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnEntry); + + /* Get the entry address */ + ixQMgrAqmIfEntryAddressGet (entryIndex, + configRegWordOnEntry, + qEntrySizeInwords, + qSizeInWords, + &entryAddress); + + /* Get the lock or return busy */ + if (IX_SUCCESS != ixOsalFastMutexTryLock(&ixQMgrAqmIfPeekPokeFastMutex[qId])) + { + return IX_FAIL; + } + + /* Else read the entry directly from SRAM. This will not move the read pointer */ + while(qEntrySizeInwords--) + { + ixQMgrAqmIfWordWrite (entryAddress++, *entry++); + } + + /* Release the lock */ + ixOsalFastMutexUnlock(&ixQMgrAqmIfPeekPokeFastMutex[qId]); + + /* Read the config register */ + ixQMgrAqmIfWordRead (cfgRegAddress, &configRegWordOnExit); + + /* Check that the read and write pointers have not changed */ + if (configRegWordOnEntry != configRegWordOnExit) + { + return IX_FAIL; + } + + return IX_SUCCESS; +} + +PRIVATE unsigned +watermarkToAqmWatermark (IxQMgrWMLevel watermark ) +{ + unsigned aqmWatermark = 0; + + /* + * Watermarks 0("000"),1("001"),2("010"),4("011"), + * 8("100"),16("101"),32("110"),64("111") + */ + aqmWatermark = ixQMgrAqmIfLog2 (watermark * 2); + + return aqmWatermark; +} + +PRIVATE unsigned +entrySizeToAqmEntrySize (IxQMgrQEntrySizeInWords entrySize) +{ + /* entrySize 1("00"),2("01"),4("10") */ + return (ixQMgrAqmIfLog2 (entrySize)); +} + +PRIVATE unsigned +bufferSizeToAqmBufferSize (unsigned bufferSizeInWords) +{ + /* bufferSize 16("00"),32("01),64("10"),128("11") */ + return (ixQMgrAqmIfLog2 (bufferSizeInWords / IX_QMGR_MIN_BUFFER_SIZE)); +} + +/* + * Reset AQM registers to default values. + */ +PRIVATE void +ixQMgrAqmIfRegistersReset (void) +{ + volatile UINT32 *qConfigWordAddress = NULL; + unsigned int i; + + /* + * Need to initialize AQM hardware registers to an initial + * value as init may have been called as a result of a soft + * reset. i.e. soft reset does not reset hardware registers. + */ + + /* Reset queues 0..31 status registers 0..3 */ + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT0_OFFSET), + IX_QMGR_QUELOWSTAT_RESET_VALUE); + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT1_OFFSET), + IX_QMGR_QUELOWSTAT_RESET_VALUE); + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT2_OFFSET), + IX_QMGR_QUELOWSTAT_RESET_VALUE); + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUELOWSTAT3_OFFSET), + IX_QMGR_QUELOWSTAT_RESET_VALUE); + + /* Reset underflow/overflow status registers 0..1 */ + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT0_OFFSET), + IX_QMGR_QUEUOSTAT_RESET_VALUE); + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUOSTAT1_OFFSET), + IX_QMGR_QUEUOSTAT_RESET_VALUE); + + /* Reset queues 32..63 nearly empty status registers */ + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT0_OFFSET), + IX_QMGR_QUEUPPSTAT0_RESET_VALUE); + + /* Reset queues 32..63 full status registers */ + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEUPPSTAT1_OFFSET), + IX_QMGR_QUEUPPSTAT1_RESET_VALUE); + + /* Reset int0 status flag source select registers 0..3 */ + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG0_OFFSET), + IX_QMGR_INT0SRCSELREG_RESET_VALUE); + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG1_OFFSET), + IX_QMGR_INT0SRCSELREG_RESET_VALUE); + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG2_OFFSET), + IX_QMGR_INT0SRCSELREG_RESET_VALUE); + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_INT0SRCSELREG3_OFFSET), + IX_QMGR_INT0SRCSELREG_RESET_VALUE); + + /* Reset queue interrupt enable register 0..1 */ + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG0_OFFSET), + IX_QMGR_QUEIEREG_RESET_VALUE); + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QUEIEREG1_OFFSET), + IX_QMGR_QUEIEREG_RESET_VALUE); + + /* Reset queue interrupt register 0..1 */ + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG0_OFFSET), + IX_QMGR_QINTREG_RESET_VALUE); + ixQMgrAqmIfWordWrite((UINT32 *)(aqmBaseAddress + IX_QMGR_QINTREG1_OFFSET), + IX_QMGR_QINTREG_RESET_VALUE); + + /* Reset queue configuration words 0..63 */ + qConfigWordAddress = (UINT32 *)(aqmBaseAddress + IX_QMGR_QUECONFIG_BASE_OFFSET); + for (i = 0; i < (IX_QMGR_QUECONFIG_SIZE / sizeof(UINT32)); i++) + { + ixQMgrAqmIfWordWrite(qConfigWordAddress, + IX_QMGR_QUECONFIG_RESET_VALUE); + /* Next word */ + qConfigWordAddress++; + } +} + diff --git a/drivers/net/npe/IxQMgrDispatcher.c b/drivers/net/npe/IxQMgrDispatcher.c new file mode 100644 index 0000000..9cb1439 --- /dev/null +++ b/drivers/net/npe/IxQMgrDispatcher.c @@ -0,0 +1,1344 @@ +/** + * @file IxQMgrDispatcher.c + * + * @author Intel Corporation + * @date 20-Dec-2001 + * + * @brief This file contains the implementation of the Dispatcher sub component + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * User defined include files. + */ +#include "IxQMgr.h" +#include "IxQMgrAqmIf_p.h" +#include "IxQMgrQCfg_p.h" +#include "IxQMgrDispatcher_p.h" +#include "IxQMgrLog_p.h" +#include "IxQMgrDefines_p.h" +#include "IxFeatureCtrl.h" +#include "IxOsal.h" + + + +/* + * #defines and macros used in this file. + */ + + +/* + * This constant is used to indicate the number of priority levels supported + */ +#define IX_QMGR_NUM_PRIORITY_LEVELS 3 + +/* + * This constant is used to set the size of the array of status words + */ +#define MAX_Q_STATUS_WORDS 4 + +/* + * This macro is used to check if a given priority is valid + */ +#define IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority) \ +(((priority) >= IX_QMGR_Q_PRIORITY_0) && ((priority) <= IX_QMGR_Q_PRIORITY_2)) + +/* + * This macto is used to check that a given interrupt source is valid + */ +#define IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel) \ +(((srcSel) >= IX_QMGR_Q_SOURCE_ID_E) && ((srcSel) <= IX_QMGR_Q_SOURCE_ID_NOT_F)) + +/* + * Number of times a dummy callback is called before logging a trace + * message + */ +#define LOG_THROTTLE_COUNT 1000000 + +/* Priority tables limits */ +#define IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX (0) +#define IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX (16) +#define IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX (31) +#define IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX (32) +#define IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX (48) +#define IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX (63) + +/* + * This macro is used to check if a given callback type is valid + */ +#define IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type) \ + (((type) >= IX_QMGR_TYPE_REALTIME_OTHER) && \ + ((type) <= IX_QMGR_TYPE_REALTIME_SPORADIC)) + +/* + * define max index in lower queue to use in loops + */ +#define IX_QMGR_MAX_LOW_QUE_TABLE_INDEX (31) + +/* + * Typedefs whose scope is limited to this file. + */ + +/* + * Information on a queue needed by the Dispatcher + */ +typedef struct +{ + IxQMgrCallback callback; /* Notification callback */ + IxQMgrCallbackId callbackId; /* Notification callback identifier */ + unsigned dummyCallbackCount; /* Number of times runs of dummy callback */ + IxQMgrPriority priority; /* Dispatch priority */ + unsigned int statusWordOffset; /* Offset to the status word to check */ + UINT32 statusMask; /* Status mask */ + UINT32 statusCheckValue; /* Status check value */ + UINT32 intRegCheckMask; /* Interrupt register check mask */ +} IxQMgrQInfo; + +/* + * Variable declarations global to this file. Externs are followed by + * statics. + */ + +/* + * Flag to keep record of what dispatcher set in featureCtrl when ixQMgrInit() + * is called. This is needed because it is possible that a client might + * change whether the live lock prevention dispatcher is used between + * calls to ixQMgrInit() and ixQMgrDispatcherLoopGet(). + */ +PRIVATE IX_STATUS ixQMgrOrigB0Dispatcher = IX_FEATURE_CTRL_COMPONENT_ENABLED; + +/* + * keep record of Q types - not in IxQMgrQInfo for performance as + * it is only used with ixQMgrDispatcherLoopRunB0LLP() + */ +PRIVATE IxQMgrType ixQMgrQTypes[IX_QMGR_MAX_NUM_QUEUES]; + +/* + * This array contains a list of queue identifiers ordered by priority. The table + * is split logically between queue identifiers 0-31 and 32-63. + */ +static IxQMgrQId priorityTable[IX_QMGR_MAX_NUM_QUEUES]; + +/* + * This flag indicates to the dispatcher that the priority table needs to be rebuilt. + */ +static BOOL rebuildTable = FALSE; + +/* Dispatcher statistics */ +static IxQMgrDispatcherStats dispatcherStats; + +/* Table of queue information */ +static IxQMgrQInfo dispatchQInfo[IX_QMGR_MAX_NUM_QUEUES]; + +/* Masks use to identify the first queues in the priority tables +* when comparing with the interrupt register +*/ +static unsigned int lowPriorityTableFirstHalfMask; +static unsigned int uppPriorityTableFirstHalfMask; + +/* + * Static function prototypes + */ + +/* + * This function is the default callback for all queues + */ +PRIVATE void +dummyCallback (IxQMgrQId qId, + IxQMgrCallbackId cbId); + +PRIVATE void +ixQMgrDispatcherReBuildPriorityTable (void); + +/* + * Function definitions. + */ +void +ixQMgrDispatcherInit (void) +{ + int i; + IxFeatureCtrlProductId productId = 0; + IxFeatureCtrlDeviceId deviceId = 0; + BOOL stickyIntSilicon = TRUE; + + /* Set default priorities */ + for (i=0; i< IX_QMGR_MAX_NUM_QUEUES; i++) + { + dispatchQInfo[i].callback = dummyCallback; + dispatchQInfo[i].callbackId = 0; + dispatchQInfo[i].dummyCallbackCount = 0; + dispatchQInfo[i].priority = IX_QMGR_Q_PRIORITY_2; + dispatchQInfo[i].statusWordOffset = 0; + dispatchQInfo[i].statusCheckValue = 0; + dispatchQInfo[i].statusMask = 0; + /* + * There are two interrupt registers, 32 bits each. One for the lower + * queues(0-31) and one for the upper queues(32-63). Therefore need to + * mod by 32 i.e the min upper queue identifier. + */ + dispatchQInfo[i].intRegCheckMask = (1<<(i%(IX_QMGR_MIN_QUEUPP_QID))); + + /* + * Set the Q types - will only be used with livelock + */ + ixQMgrQTypes[i] = IX_QMGR_TYPE_REALTIME_OTHER; + + /* Reset queue statistics */ + dispatcherStats.queueStats[i].callbackCnt = 0; + dispatcherStats.queueStats[i].priorityChangeCnt = 0; + dispatcherStats.queueStats[i].intNoCallbackCnt = 0; + dispatcherStats.queueStats[i].intLostCallbackCnt = 0; + dispatcherStats.queueStats[i].notificationEnabled = FALSE; + dispatcherStats.queueStats[i].srcSel = 0; + + } + + /* Priority table. Order the table from queue 0 to 63 */ + ixQMgrDispatcherReBuildPriorityTable(); + + /* Reset statistics */ + dispatcherStats.loopRunCnt = 0; + + /* Get the device ID for the underlying silicon */ + deviceId = ixFeatureCtrlDeviceRead(); + + /* Get the product ID for the underlying silicon */ + productId = ixFeatureCtrlProductIdRead(); + + /* + * Check featureCtrl to see if Livelock prevention is required + */ + ixQMgrOrigB0Dispatcher = ixFeatureCtrlSwConfigurationCheck( + IX_FEATURECTRL_ORIGB0_DISPATCHER); + + /* + * Check if the silicon supports the sticky interrupt feature. + * IF (IXP42X AND A0) -> No sticky interrupt feature supported + */ + if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X == + (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) && + (IX_FEATURE_CTRL_SILICON_TYPE_A0 == + (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId))) + { + stickyIntSilicon = FALSE; + } + + /* + * IF user wants livelock prev option AND silicon supports sticky interrupt + * feature -> enable the sticky interrupt bit + */ + if ((IX_FEATURE_CTRL_SWCONFIG_DISABLED == ixQMgrOrigB0Dispatcher) && + stickyIntSilicon) + { + ixQMgrStickyInterruptRegEnable(); + } +} + +IX_STATUS +ixQMgrDispatcherPrioritySet (IxQMgrQId qId, + IxQMgrPriority priority) +{ + int ixQMgrLockKey; + + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + + if (!IX_QMGR_DISPATCHER_PRIORITY_CHECK(priority)) + { + return IX_QMGR_Q_INVALID_PRIORITY; + } + + ixQMgrLockKey = ixOsalIrqLock(); + + /* Change priority */ + dispatchQInfo[qId].priority = priority; + /* Set flag */ + rebuildTable = TRUE; + + ixOsalIrqUnlock(ixQMgrLockKey); + +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qId].priorityChangeCnt++; +#endif + + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrNotificationCallbackSet (IxQMgrQId qId, + IxQMgrCallback callback, + IxQMgrCallbackId callbackId) +{ + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + + if (NULL == callback) + { + /* Reset to dummy callback */ + dispatchQInfo[qId].callback = dummyCallback; + dispatchQInfo[qId].dummyCallbackCount = 0; + dispatchQInfo[qId].callbackId = 0; + } + else + { + dispatchQInfo[qId].callback = callback; + dispatchQInfo[qId].callbackId = callbackId; + } + + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrNotificationEnable (IxQMgrQId qId, + IxQMgrSourceId srcSel) +{ + IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */ + IxQMgrQStatus qStatusOnExit; /* to this function */ + int ixQMgrLockKey; + +#ifndef NDEBUG + if (!ixQMgrQIsConfigured (qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + + if ((qId < IX_QMGR_MIN_QUEUPP_QID) && + !IX_QMGR_DISPATCHER_SOURCE_ID_CHECK(srcSel)) + { + /* QId 0-31 source id invalid */ + return IX_QMGR_INVALID_INT_SOURCE_ID; + } + + if ((IX_QMGR_Q_SOURCE_ID_NE != srcSel) && + (qId >= IX_QMGR_MIN_QUEUPP_QID)) + { + /* + * For queues 32-63 the interrupt source is fixed to the Nearly + * Empty status flag and therefore should have a srcSel of NE. + */ + return IX_QMGR_INVALID_INT_SOURCE_ID; + } +#endif + +#ifndef NDEBUG + dispatcherStats.queueStats[qId].notificationEnabled = TRUE; + dispatcherStats.queueStats[qId].srcSel = srcSel; +#endif + + /* Get the current queue status */ + ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry); + + /* + * Enabling interrupts results in Read-Modify-Write + * so need critical section + */ + + ixQMgrLockKey = ixOsalIrqLock(); + + /* Calculate the checkMask and checkValue for this q */ + ixQMgrAqmIfQStatusCheckValsCalc (qId, + srcSel, + &dispatchQInfo[qId].statusWordOffset, + &dispatchQInfo[qId].statusCheckValue, + &dispatchQInfo[qId].statusMask); + + + /* Set the interrupt source is this queue is in the range 0-31 */ + if (qId < IX_QMGR_MIN_QUEUPP_QID) + { + ixQMgrAqmIfIntSrcSelWrite (qId, srcSel); + } + + /* Enable the interrupt */ + ixQMgrAqmIfQInterruptEnable (qId); + + ixOsalIrqUnlock(ixQMgrLockKey); + + /* Get the current queue status */ + ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit); + + /* If the status has changed return a warning */ + if (qStatusOnEntry != qStatusOnExit) + { + return IX_QMGR_WARNING; + } + + return IX_SUCCESS; +} + + +IX_STATUS +ixQMgrNotificationDisable (IxQMgrQId qId) +{ + int ixQMgrLockKey; + +#ifndef NDEBUG + /* Validate parameters */ + if (!ixQMgrQIsConfigured (qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } +#endif + + /* + * Enabling interrupts results in Read-Modify-Write + * so need critical section + */ +#ifndef NDEBUG + dispatcherStats.queueStats[qId].notificationEnabled = FALSE; +#endif + + ixQMgrLockKey = ixOsalIrqLock(); + + ixQMgrAqmIfQInterruptDisable (qId); + + ixOsalIrqUnlock(ixQMgrLockKey); + + return IX_SUCCESS; +} + +void +ixQMgrStickyInterruptRegEnable(void) +{ + /* Use Aqm If function to set Interrupt Register0 Bit-3 */ + ixQMgrAqmIfIntSrcSelReg0Bit3Set (); +} + +#if !defined __XSCALE__ || defined __linux + +/* Count the number of leading zero bits in a word, + * and return the same value than the CLZ instruction. + * + * word (in) return value (out) + * 0x80000000 0 + * 0x40000000 1 + * ,,, ,,, + * 0x00000002 30 + * 0x00000001 31 + * 0x00000000 32 + * + * The C version of this function is used as a replacement + * for system not providing the equivalent of the CLZ + * assembly language instruction. + * + * Note that this version is big-endian + */ +unsigned int +ixQMgrCountLeadingZeros(UINT32 word) +{ + unsigned int leadingZerosCount = 0; + + if (word == 0) + { + return 32; + } + /* search the first bit set by testing the MSB and shifting the input word */ + while ((word & 0x80000000) == 0) + { + word <<= 1; + leadingZerosCount++; + } + return leadingZerosCount; +} +#endif /* not __XSCALE__ or __linux */ + +void +ixQMgrDispatcherLoopGet (IxQMgrDispatcherFuncPtr *qDispatcherFuncPtr) +{ + IxFeatureCtrlProductId productId = 0; + IxFeatureCtrlDeviceId deviceId = 0; + + /* Get the device ID for the underlying silicon */ + deviceId = ixFeatureCtrlDeviceRead(); + + /* Get the product ID for the underlying silicon */ + productId = ixFeatureCtrlProductIdRead (); + + /* IF (IXP42X AND A0 silicon) -> use ixQMgrDispatcherLoopRunA0 */ + if ((IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X == + (IX_FEATURE_CTRL_DEVICE_TYPE_MASK & deviceId)) && + (IX_FEATURE_CTRL_SILICON_TYPE_A0 == + (IX_FEATURE_CTRL_SILICON_STEPPING_MASK & productId))) + { + /*For IXP42X A0 silicon */ + *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunA0 ; + } + else /*For IXP42X B0 or IXP46X silicon*/ + { + if (IX_FEATURE_CTRL_SWCONFIG_ENABLED == ixQMgrOrigB0Dispatcher) + { + /* Default for IXP42X B0 and IXP46X silicon */ + *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0; + } + else + { + /* FeatureCtrl indicated that livelock dispatcher be used */ + *qDispatcherFuncPtr = &ixQMgrDispatcherLoopRunB0LLP; + } + } +} + +void +ixQMgrDispatcherLoopRunA0 (IxQMgrDispatchGroup group) +{ + UINT32 intRegVal; /* Interrupt reg val */ + UINT32 intRegValAfterWrite; /* Interrupt reg val after writing back */ + UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ + UINT32 qStatusWordsB4Write[MAX_Q_STATUS_WORDS]; /* Status b4 interrupt write */ + UINT32 qStatusWordsAfterWrite[MAX_Q_STATUS_WORDS]; /* Status after interrupt write */ + IxQMgrQInfo *currDispatchQInfo; + BOOL statusChangeFlag; + + int priorityTableIndex;/* Priority table index */ + int qIndex; /* Current queue being processed */ + int endIndex; /* Index of last queue to process */ + +#ifndef NDEBUG + IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || + (group == IX_QMGR_QUELOW_GROUP)); +#endif + + /* Read Q status registers before interrupt status read/write */ + ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsB4Write); + + /* Read the interrupt register */ + ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); + + /* No bit set : nothing to process (the reaminder of the algorithm is + * based on the fact that the interrupt register value contains at + * least one bit set + */ + if (intRegVal == 0) + { +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.loopRunCnt++; +#endif + + /* Rebuild the priority table if needed */ + if (rebuildTable) + { + ixQMgrDispatcherReBuildPriorityTable (); + } + + return; + } + + /* Write it back to clear the interrupt */ + ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); + + /* Read Q status registers after interrupt status read/write */ + ixQMgrAqmIfQStatusRegsRead (group, qStatusWordsAfterWrite); + + /* get the first queue Id from the interrupt register value */ + qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); + + /* check if any change occured during hw register modifications */ + if (IX_QMGR_QUELOW_GROUP == group) + { + statusChangeFlag = + (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]) || + (qStatusWordsB4Write[1] != qStatusWordsAfterWrite[1]) || + (qStatusWordsB4Write[2] != qStatusWordsAfterWrite[2]) || + (qStatusWordsB4Write[3] != qStatusWordsAfterWrite[3]); + } + else + { + statusChangeFlag = + (qStatusWordsB4Write[0] != qStatusWordsAfterWrite[0]); + /* Set the queue range based on the queue group to proccess */ + qIndex += IX_QMGR_MIN_QUEUPP_QID; + } + + if (statusChangeFlag == FALSE) + { + /* check if the interrupt register contains + * only 1 bit set (happy day scenario) + */ + currDispatchQInfo = &dispatchQInfo[qIndex]; + if (intRegVal == currDispatchQInfo->intRegCheckMask) + { + /* only 1 queue event triggered a notification * + * Call the callback function for this queue + */ + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + } + else + { + /* the event is triggered by more than 1 queue, + * the queue search will be starting from the beginning + * or the middle of the priority table + * + * the serach will end when all the bits of the interrupt + * register are cleared. There is no need to maintain + * a seperate value and test it at each iteration. + */ + if (IX_QMGR_QUELOW_GROUP == group) + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & lowPriorityTableFirstHalfMask) + { + priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; + } + } + else + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & uppPriorityTableFirstHalfMask) + { + priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; + } + } + + /* iterate following the priority table until all the bits + * of the interrupt register are cleared. + */ + do + { + qIndex = priorityTable[priorityTableIndex++]; + currDispatchQInfo = &dispatchQInfo[qIndex]; + intRegCheckMask = currDispatchQInfo->intRegCheckMask; + + /* If this queue caused this interrupt to be raised */ + if (intRegVal & intRegCheckMask) + { + /* Call the callback function for this queue */ + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + + /* Clear the interrupt register bit */ + intRegVal &= ~intRegCheckMask; + } + } + while(intRegVal); + } + } + else + { + /* A change in queue status occured during the hw interrupt + * register update. To maintain the interrupt consistency, it + * is necessary to iterate through all queues of the queue group. + */ + + /* Read interrupt status again */ + ixQMgrAqmIfQInterruptRegRead (group, &intRegValAfterWrite); + + if (IX_QMGR_QUELOW_GROUP == group) + { + priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; + endIndex = IX_QMGR_MAX_LOW_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; + endIndex = IX_QMGR_MAX_UPP_QUE_PRIORITY_TABLE_INDEX; + } + + for ( ; priorityTableIndex<=endIndex; priorityTableIndex++) + { + qIndex = priorityTable[priorityTableIndex]; + currDispatchQInfo = &dispatchQInfo[qIndex]; + intRegCheckMask = currDispatchQInfo->intRegCheckMask; + + /* If this queue caused this interrupt to be raised */ + if (intRegVal & intRegCheckMask) + { + /* Call the callback function for this queue */ + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + + } /* if (intRegVal .. */ + + /* + * If interrupt bit is set in intRegValAfterWrite don't + * proceed as this will be caught in next interrupt + */ + else if ((intRegValAfterWrite & intRegCheckMask) == 0) + { + /* Check if an interrupt was lost for this Q */ + if (ixQMgrAqmIfQStatusCheck(qStatusWordsB4Write, + qStatusWordsAfterWrite, + currDispatchQInfo->statusWordOffset, + currDispatchQInfo->statusCheckValue, + currDispatchQInfo->statusMask)) + { + /* Call the callback function for this queue */ + currDispatchQInfo->callback (qIndex, + dispatchQInfo[qIndex].callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; + dispatcherStats.queueStats[qIndex].intLostCallbackCnt++; +#endif + } /* if ixQMgrAqmIfQStatusCheck(.. */ + } /* else if ((intRegValAfterWrite ... */ + } /* for (priorityTableIndex=0 ... */ + } + + /* Rebuild the priority table if needed */ + if (rebuildTable) + { + ixQMgrDispatcherReBuildPriorityTable (); + } + +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.loopRunCnt++; +#endif +} + + + +void +ixQMgrDispatcherLoopRunB0 (IxQMgrDispatchGroup group) +{ + UINT32 intRegVal; /* Interrupt reg val */ + UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ + IxQMgrQInfo *currDispatchQInfo; + + + int priorityTableIndex; /* Priority table index */ + int qIndex; /* Current queue being processed */ + +#ifndef NDEBUG + IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || + (group == IX_QMGR_QUELOW_GROUP)); + IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || + (group == IX_QMGR_QUELOW_GROUP)); +#endif + + /* Read the interrupt register */ + ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); + + + /* No queue has interrupt register set */ + if (intRegVal != 0) + { + + /* Write it back to clear the interrupt */ + ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); + + /* get the first queue Id from the interrupt register value */ + qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); + + if (IX_QMGR_QUEUPP_GROUP == group) + { + /* Set the queue range based on the queue group to proccess */ + qIndex += IX_QMGR_MIN_QUEUPP_QID; + } + + /* check if the interrupt register contains + * only 1 bit set + * For example: + * intRegVal = 0x0010 + * currDispatchQInfo->intRegCheckMask = 0x0010 + * intRegVal == currDispatchQInfo->intRegCheckMask is TRUE. + */ + currDispatchQInfo = &dispatchQInfo[qIndex]; + if (intRegVal == currDispatchQInfo->intRegCheckMask) + { + /* only 1 queue event triggered a notification * + * Call the callback function for this queue + */ + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + } + else + { + /* the event is triggered by more than 1 queue, + * the queue search will be starting from the beginning + * or the middle of the priority table + * + * the serach will end when all the bits of the interrupt + * register are cleared. There is no need to maintain + * a seperate value and test it at each iteration. + */ + if (IX_QMGR_QUELOW_GROUP == group) + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & lowPriorityTableFirstHalfMask) + { + priorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; + } + } + else + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & uppPriorityTableFirstHalfMask) + { + priorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; + } + } + + /* iterate following the priority table until all the bits + * of the interrupt register are cleared. + */ + do + { + qIndex = priorityTable[priorityTableIndex++]; + currDispatchQInfo = &dispatchQInfo[qIndex]; + intRegCheckMask = currDispatchQInfo->intRegCheckMask; + + /* If this queue caused this interrupt to be raised */ + if (intRegVal & intRegCheckMask) + { + /* Call the callback function for this queue */ + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + + /* Clear the interrupt register bit */ + intRegVal &= ~intRegCheckMask; + } + } + while(intRegVal); + } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */ + } /* End of intRegVal != 0 */ + +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.loopRunCnt++; +#endif + + /* Rebuild the priority table if needed */ + if (rebuildTable) + { + ixQMgrDispatcherReBuildPriorityTable (); + } +} + +void +ixQMgrDispatcherLoopRunB0LLP (IxQMgrDispatchGroup group) +{ + UINT32 intRegVal =0; /* Interrupt reg val */ + UINT32 intRegCheckMask; /* Mask for checking interrupt bits */ + IxQMgrQInfo *currDispatchQInfo; + + int priorityTableIndex; /* Priority table index */ + int qIndex; /* Current queue being processed */ + + UINT32 intRegValCopy = 0; + UINT32 intEnableRegVal = 0; + UINT8 i = 0; + +#ifndef NDEBUG + IX_OSAL_ASSERT((group == IX_QMGR_QUEUPP_GROUP) || + (group == IX_QMGR_QUELOW_GROUP)); +#endif + + /* Read the interrupt register */ + ixQMgrAqmIfQInterruptRegRead (group, &intRegVal); + + /* + * mask any interrupts that are not enabled + */ + ixQMgrAqmIfQInterruptEnableRegRead (group, &intEnableRegVal); + intRegVal &= intEnableRegVal; + + /* No queue has interrupt register set */ + if (intRegVal != 0) + { + if (IX_QMGR_QUELOW_GROUP == group) + { + /* + * As the sticky bit is set, the interrupt register will + * not clear if write back at this point because the condition + * has not been cleared. Take a copy and write back later after + * the condition has been cleared + */ + intRegValCopy = intRegVal; + } + else + { + /* no sticky for upper Q's, so write back now */ + ixQMgrAqmIfQInterruptRegWrite (group, intRegVal); + } + + /* get the first queue Id from the interrupt register value */ + qIndex = (BITS_PER_WORD - 1) - ixQMgrCountLeadingZeros(intRegVal); + + if (IX_QMGR_QUEUPP_GROUP == group) + { + /* Set the queue range based on the queue group to proccess */ + qIndex += IX_QMGR_MIN_QUEUPP_QID; + } + + /* check if the interrupt register contains + * only 1 bit set + * For example: + * intRegVal = 0x0010 + * currDispatchQInfo->intRegCheckMask = 0x0010 + * intRegVal == currDispatchQInfo->intRegCheckMask is TRUE. + */ + currDispatchQInfo = &dispatchQInfo[qIndex]; + if (intRegVal == currDispatchQInfo->intRegCheckMask) + { + + /* + * check if Q type periodic - only lower queues can + * have there type set to periodic + */ + if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex]) + { + /* + * Disable the notifications on any sporadics + */ + for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) + { + if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i]) + { + ixQMgrNotificationDisable(i); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[i].disableCount++; +#endif + } + } + } + + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + } + else + { + /* the event is triggered by more than 1 queue, + * the queue search will be starting from the beginning + * or the middle of the priority table + * + * the serach will end when all the bits of the interrupt + * register are cleared. There is no need to maintain + * a seperate value and test it at each iteration. + */ + if (IX_QMGR_QUELOW_GROUP == group) + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & lowPriorityTableFirstHalfMask) + { + priorityTableIndex = + IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = + IX_QMGR_MID_LOW_QUE_PRIORITY_TABLE_INDEX; + } + } + else + { + /* check if any bit related to queues in the first + * half of the priority table is set + */ + if (intRegVal & uppPriorityTableFirstHalfMask) + { + priorityTableIndex = + IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; + } + else + { + priorityTableIndex = + IX_QMGR_MID_UPP_QUE_PRIORITY_TABLE_INDEX; + } + } + + /* iterate following the priority table until all the bits + * of the interrupt register are cleared. + */ + do + { + qIndex = priorityTable[priorityTableIndex++]; + currDispatchQInfo = &dispatchQInfo[qIndex]; + intRegCheckMask = currDispatchQInfo->intRegCheckMask; + + /* If this queue caused this interrupt to be raised */ + if (intRegVal & intRegCheckMask) + { + /* + * check if Q type periodic - only lower queues can + * have there type set to periodic. There can only be one + * periodic queue, so the sporadics are only disabled once. + */ + if (IX_QMGR_TYPE_REALTIME_PERIODIC == ixQMgrQTypes[qIndex]) + { + /* + * Disable the notifications on any sporadics + */ + for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) + { + if (IX_QMGR_TYPE_REALTIME_SPORADIC == + ixQMgrQTypes[i]) + { + ixQMgrNotificationDisable(i); + /* + * remove from intRegVal as we don't want + * to service any sporadics now + */ + intRegVal &= ~dispatchQInfo[i].intRegCheckMask; +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[i].disableCount++; +#endif + } + } + } + + currDispatchQInfo->callback (qIndex, + currDispatchQInfo->callbackId); +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.queueStats[qIndex].callbackCnt++; +#endif + /* Clear the interrupt register bit */ + intRegVal &= ~intRegCheckMask; + } + } + while(intRegVal); + } /*End of intRegVal == currDispatchQInfo->intRegCheckMask */ + } /* End of intRegVal != 0 */ + +#ifndef NDEBUG + /* Update statistics */ + dispatcherStats.loopRunCnt++; +#endif + + if ((intRegValCopy != 0) && (IX_QMGR_QUELOW_GROUP == group)) + { + /* + * lower groups (therefore sticky) AND at least one enabled interrupt + * Write back to clear the interrupt + */ + ixQMgrAqmIfQInterruptRegWrite (IX_QMGR_QUELOW_GROUP, intRegValCopy); + } + + /* Rebuild the priority table if needed */ + if (rebuildTable) + { + ixQMgrDispatcherReBuildPriorityTable (); + } +} + +PRIVATE void +ixQMgrDispatcherReBuildPriorityTable (void) +{ + UINT32 qIndex; + UINT32 priority; + int lowQuePriorityTableIndex = IX_QMGR_MIN_LOW_QUE_PRIORITY_TABLE_INDEX; + int uppQuePriorityTableIndex = IX_QMGR_MIN_UPP_QUE_PRIORITY_TABLE_INDEX; + + /* Reset the rebuild flag */ + rebuildTable = FALSE; + + /* initialize the mak used to identify the queues in the first half + * of the priority table + */ + lowPriorityTableFirstHalfMask = 0; + uppPriorityTableFirstHalfMask = 0; + + /* For each priority level */ + for(priority=0; priority dummyCallback: qId (%d), callbackId (%d)\n",qId,cbId); + } + dispatchQInfo[qId].dummyCallbackCount++; + +#ifndef NDEBUG + /* Update statistcs */ + dispatcherStats.queueStats[qId].intNoCallbackCnt++; +#endif +} +void +ixQMgrLLPShow (int resetStats) +{ +#ifndef NDEBUG + UINT8 i = 0; + UINT32 intEnableRegVal = 0; + + printf ("Livelock statistics are printed on the fly.\n"); + printf ("qId Type EnableCnt DisableCnt IntEnableState Callbacks\n"); + printf ("=== ======== ========= ========== ============== =========\n"); + + for (i=0; i<= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) + { + if (ixQMgrQTypes[i] != IX_QMGR_TYPE_REALTIME_OTHER) + { + printf (" %2d ", i); + + if (ixQMgrQTypes[i] == IX_QMGR_TYPE_REALTIME_SPORADIC) + { + printf ("Sporadic"); + } + else + { + printf ("Periodic"); + } + + + ixQMgrAqmIfQInterruptEnableRegRead (IX_QMGR_QUELOW_GROUP, + &intEnableRegVal); + + + intEnableRegVal &= dispatchQInfo[i].intRegCheckMask; + intEnableRegVal = intEnableRegVal >> i; + + printf (" %10d %10d %10d %10d\n", + dispatcherStats.queueStats[i].enableCount, + dispatcherStats.queueStats[i].disableCount, + intEnableRegVal, + dispatcherStats.queueStats[i].callbackCnt); + + if (resetStats) + { + dispatcherStats.queueStats[i].enableCount = + dispatcherStats.queueStats[i].disableCount = + dispatcherStats.queueStats[i].callbackCnt = 0; + } + } + } +#else + IX_QMGR_LOG0("Livelock Prevention statistics are only collected in debug mode\n"); +#endif +} + +void +ixQMgrPeriodicDone (void) +{ + UINT32 i = 0; + UINT32 ixQMgrLockKey = 0; + + /* + * for the lower queues + */ + for (i=0; i <= IX_QMGR_MAX_LOW_QUE_TABLE_INDEX; i++) + { + /* + * check for sporadics + */ + if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrQTypes[i]) + { + /* + * enable any sporadics + */ + ixQMgrLockKey = ixOsalIrqLock(); + ixQMgrAqmIfQInterruptEnable(i); + ixOsalIrqUnlock(ixQMgrLockKey); +#ifndef NDEBUG + /* + * Update statistics + */ + dispatcherStats.queueStats[i].enableCount++; + dispatcherStats.queueStats[i].notificationEnabled = TRUE; +#endif + } + } +} +IX_STATUS +ixQMgrCallbackTypeSet (IxQMgrQId qId, + IxQMgrType type) +{ + UINT32 ixQMgrLockKey = 0; + IxQMgrType ixQMgrOldType =0; + +#ifndef NDEBUG + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + if (qId >= IX_QMGR_MIN_QUEUPP_QID) + { + return IX_QMGR_PARAMETER_ERROR; + } + if(!IX_QMGR_DISPATCHER_CALLBACK_TYPE_CHECK(type)) + { + return IX_QMGR_PARAMETER_ERROR; + } +#endif + + ixQMgrOldType = ixQMgrQTypes[qId]; + ixQMgrQTypes[qId] = type; + + /* + * check if Q has been changed from type SPORADIC + */ + if (IX_QMGR_TYPE_REALTIME_SPORADIC == ixQMgrOldType) + { + /* + * previously Q was a SPORADIC, this means that LLP + * might have had it disabled. enable it now. + */ + ixQMgrLockKey = ixOsalIrqLock(); + ixQMgrAqmIfQInterruptEnable(qId); + ixOsalIrqUnlock(ixQMgrLockKey); + +#ifndef NDEBUG + /* + * Update statistics + */ + dispatcherStats.queueStats[qId].enableCount++; +#endif + } + + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrCallbackTypeGet (IxQMgrQId qId, + IxQMgrType *type) +{ +#ifndef NDEBUG + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + if (qId >= IX_QMGR_MIN_QUEUPP_QID) + { + return IX_QMGR_PARAMETER_ERROR; + } + if(type == NULL) + { + return IX_QMGR_PARAMETER_ERROR; + } +#endif + + *type = ixQMgrQTypes[qId]; + return IX_SUCCESS; +} diff --git a/drivers/net/npe/IxQMgrInit.c b/drivers/net/npe/IxQMgrInit.c new file mode 100644 index 0000000..b00c22d --- /dev/null +++ b/drivers/net/npe/IxQMgrInit.c @@ -0,0 +1,233 @@ +/** + * @file IxQMgrInit.c + * + * @author Intel Corporation + * @date 30-Oct-2001 + * + * @brief: Provided initialization of the QMgr component and its subcomponents. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * System defined include files. + */ + +/* + * User defined include files. + */ +#include "IxOsal.h" +#include "IxQMgr.h" +#include "IxQMgrQCfg_p.h" +#include "IxQMgrDispatcher_p.h" +#include "IxQMgrLog_p.h" +#include "IxQMgrQAccess_p.h" +#include "IxQMgrDefines_p.h" +#include "IxQMgrAqmIf_p.h" + +/* + * Set to true if initialized + * N.B. global so integration/unit tests can reinitialize + */ +BOOL qMgrIsInitialized = FALSE; + +/* + * Function definitions. + */ +IX_STATUS +ixQMgrInit (void) +{ + if (qMgrIsInitialized) + { + IX_QMGR_LOG0("ixQMgrInit: IxQMgr already initialised\n"); + return IX_FAIL; + } + + /* Initialise the QCfg component */ + ixQMgrQCfgInit (); + + /* Initialise the Dispatcher component */ + ixQMgrDispatcherInit (); + + /* Initialise the Access component */ + ixQMgrQAccessInit (); + + /* Initialization complete */ + qMgrIsInitialized = TRUE; + + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrUnload (void) +{ + if (!qMgrIsInitialized) + { + return IX_FAIL; + } + + /* Uninitialise the QCfg component */ + ixQMgrQCfgUninit (); + + /* Uninitialization complete */ + qMgrIsInitialized = FALSE; + + return IX_SUCCESS; +} + +void +ixQMgrShow (void) +{ + IxQMgrQCfgStats *qCfgStats = NULL; + IxQMgrDispatcherStats *dispatcherStats = NULL; + int i; + UINT32 lowIntRegRead, upIntRegRead; + + qCfgStats = ixQMgrQCfgStatsGet (); + dispatcherStats = ixQMgrDispatcherStatsGet (); + ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUELOW_GROUP, &lowIntRegRead); + ixQMgrAqmIfQInterruptRegRead (IX_QMGR_QUEUPP_GROUP, &upIntRegRead); + printf("Generic Stats........\n"); + printf("=====================\n"); + printf("Loop Run Count..........%u\n",dispatcherStats->loopRunCnt); + printf("Watermark set count.....%d\n", qCfgStats->wmSetCnt); + printf("===========================================\n"); + printf("On the fly Interrupt Register Stats........\n"); + printf("===========================================\n"); + printf("Lower Interrupt Register............0x%08x\n",lowIntRegRead); + printf("Upper Interrupt Register............0x%08x\n",upIntRegRead); + printf("==============================================\n"); + printf("Queue Specific Stats........\n"); + printf("============================\n"); + + for (i=0; iqStats[qId].qName); + printf(" Size in words............ %u\n", qCfgStats->qStats[qId].qSizeInWords); + printf(" Entry size in words...... %u\n", qCfgStats->qStats[qId].qEntrySizeInWords); + printf(" Nearly empty watermark... %u\n", qCfgStats->qStats[qId].ne); + printf(" Nearly full watermark.... %u\n", qCfgStats->qStats[qId].nf); + printf(" Number of full entries... %u\n", qCfgStats->qStats[qId].numEntries); + printf(" Sram base address........ 0x%X\n", qCfgStats->qStats[qId].baseAddress); + printf(" Read pointer............. 0x%X\n", qCfgStats->qStats[qId].readPtr); + printf(" Write pointer............ 0x%X\n", qCfgStats->qStats[qId].writePtr); + +#ifndef NDEBUG + if (dispatcherStats->queueStats[qId].notificationEnabled) + { + char *localEvent = "none ????"; + switch (dispatcherStats->queueStats[qId].srcSel) + { + case IX_QMGR_Q_SOURCE_ID_E: + localEvent = "Empty"; + break; + case IX_QMGR_Q_SOURCE_ID_NE: + localEvent = "Nearly Empty"; + break; + case IX_QMGR_Q_SOURCE_ID_NF: + localEvent = "Nearly Full"; + break; + case IX_QMGR_Q_SOURCE_ID_F: + localEvent = "Full"; + break; + case IX_QMGR_Q_SOURCE_ID_NOT_E: + localEvent = "Not Empty"; + break; + case IX_QMGR_Q_SOURCE_ID_NOT_NE: + localEvent = "Not Nearly Empty"; + break; + case IX_QMGR_Q_SOURCE_ID_NOT_NF: + localEvent = "Not Nearly Full"; + break; + case IX_QMGR_Q_SOURCE_ID_NOT_F: + localEvent = "Not Full"; + break; + default : + break; + } + printf(" Notifications localEvent...... %s\n", localEvent); + } + else + { + printf(" Notifications............ not enabled\n"); + } + printf(" IxQMgrDispatcher Stats\n"); + printf(" Callback count................%d\n", + dispatcherStats->queueStats[qId].callbackCnt); + printf(" Priority change count.........%d\n", + dispatcherStats->queueStats[qId].priorityChangeCnt); + printf(" Interrupt no callback count...%d\n", + dispatcherStats->queueStats[qId].intNoCallbackCnt); + printf(" Interrupt lost callback count...%d\n", + dispatcherStats->queueStats[qId].intLostCallbackCnt); +#endif + + return IX_SUCCESS; +} + + + + diff --git a/drivers/net/npe/IxQMgrQAccess.c b/drivers/net/npe/IxQMgrQAccess.c new file mode 100644 index 0000000..8885736 --- /dev/null +++ b/drivers/net/npe/IxQMgrQAccess.c @@ -0,0 +1,796 @@ +/** + * @file IxQMgrQAccess.c + * + * @author Intel Corporation + * @date 30-Oct-2001 + * + * @brief This file contains functions for putting entries on a queue and + * removing entries from a queue. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * Inlines are compiled as function when this is defined. + * N.B. Must be placed before #include of "IxQMgr.h" + */ +#ifndef IXQMGR_H +# define IXQMGRQACCESS_C +#else +# error +#endif + +/* + * System defined include files. + */ + +/* + * User defined include files. + */ +#include "IxQMgr.h" +#include "IxQMgrAqmIf_p.h" +#include "IxQMgrQAccess_p.h" +#include "IxQMgrQCfg_p.h" +#include "IxQMgrDefines_p.h" + +/* + * Global variables and extern definitions + */ +extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; + +/* + * Function definitions. + */ +void +ixQMgrQAccessInit (void) +{ +} + +IX_STATUS +ixQMgrQReadWithChecks (IxQMgrQId qId, + UINT32 *entry) +{ + IxQMgrQEntrySizeInWords entrySizeInWords; + IxQMgrQInlinedReadWriteInfo *infoPtr; + + if (NULL == entry) + { + return IX_QMGR_PARAMETER_ERROR; + } + + /* Check QId */ + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + + /* Get the q entry size in words */ + entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId); + + ixQMgrAqmIfQPop (qId, entrySizeInWords, entry); + + /* reset the current read count if the counter wrapped around + * (unsigned arithmetic) + */ + infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; + if (infoPtr->qReadCount-- > infoPtr->qSizeInEntries) + { + infoPtr->qReadCount = 0; + } + + /* Check if underflow occurred on the read */ + if (ixQMgrAqmIfUnderflowCheck (qId)) + { + return IX_QMGR_Q_UNDERFLOW; + } + + return IX_SUCCESS; +} + +/* this function reads the remaining of the q entry + * for queues configured with many words. + * (the first word of the entry is already read + * in the inlined function and the entry pointer already + * incremented + */ +IX_STATUS +ixQMgrQReadMWordsMinus1 (IxQMgrQId qId, + UINT32 *entry) +{ + IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; + UINT32 entrySize = infoPtr->qEntrySizeInWords; + volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; + + while (--entrySize) + { + /* read the entry and accumulate the result */ + *(++entry) = IX_OSAL_READ_LONG(++qAccRegAddr); + } + /* underflow is available for lower queues only */ + if (qId < IX_QMGR_MIN_QUEUPP_QID) + { + /* get the queue status */ + UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); + + /* check the underflow status */ + if (status & infoPtr->qUflowStatBitMask) + { + /* the queue is empty + * clear the underflow status bit if it was set + */ + IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, + status & ~infoPtr->qUflowStatBitMask); + return IX_QMGR_Q_UNDERFLOW; + } + } + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrQWriteWithChecks (IxQMgrQId qId, + UINT32 *entry) +{ + IxQMgrQEntrySizeInWords entrySizeInWords; + IxQMgrQInlinedReadWriteInfo *infoPtr; + + if (NULL == entry) + { + return IX_QMGR_PARAMETER_ERROR; + } + + /* Check QId */ + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + + /* Get the q entry size in words */ + entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId); + + ixQMgrAqmIfQPush (qId, entrySizeInWords, entry); + + /* reset the current read count if the counter wrapped around + * (unsigned arithmetic) + */ + infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; + if (infoPtr->qWriteCount++ >= infoPtr->qSizeInEntries) + { + infoPtr->qWriteCount = infoPtr->qSizeInEntries; + } + + /* Check if overflow occurred on the write*/ + if (ixQMgrAqmIfOverflowCheck (qId)) + { + return IX_QMGR_Q_OVERFLOW; + } + + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrQPeek (IxQMgrQId qId, + unsigned int entryIndex, + UINT32 *entry) +{ + unsigned int numEntries; + +#ifndef NDEBUG + if ((NULL == entry) || (entryIndex >= IX_QMGR_Q_SIZE_INVALID)) + { + return IX_QMGR_PARAMETER_ERROR; + } + + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } +#endif + + if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries)) + { + return IX_FAIL; + } + + if (entryIndex >= numEntries) /* entryIndex starts at 0 */ + { + return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS; + } + + return ixQMgrAqmIfQPeek (qId, entryIndex, entry); +} + +IX_STATUS +ixQMgrQPoke (IxQMgrQId qId, + unsigned entryIndex, + UINT32 *entry) +{ + unsigned int numEntries; + +#ifndef NDEBUG + if ((NULL == entry) || (entryIndex > 128)) + { + return IX_QMGR_PARAMETER_ERROR; + } + + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } +#endif + + if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries)) + { + return IX_FAIL; + } + + if (numEntries < (entryIndex + 1)) /* entryIndex starts at 0 */ + { + return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS; + } + + return ixQMgrAqmIfQPoke (qId, entryIndex, entry); +} + +IX_STATUS +ixQMgrQStatusGetWithChecks (IxQMgrQId qId, + IxQMgrQStatus *qStatus) +{ + if (NULL == qStatus) + { + return IX_QMGR_PARAMETER_ERROR; + } + + if (!ixQMgrQIsConfigured (qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + + ixQMgrAqmIfQueStatRead (qId, qStatus); + + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrQNumEntriesGet (IxQMgrQId qId, + unsigned *numEntriesPtr) +{ + UINT32 qPtrs; + UINT32 qStatus; + unsigned numEntries; + IxQMgrQInlinedReadWriteInfo *infoPtr; + + +#ifndef NDEBUG + if (NULL == numEntriesPtr) + { + return IX_QMGR_PARAMETER_ERROR; + } + + /* Check QId */ + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } +#endif + + /* get fast access data */ + infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; + + /* get snapshot */ + qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr); + + /* Mod subtraction of pointers to get number of words in Q. */ + numEntries = (qPtrs - (qPtrs >> 7)) & 0x7f; + + if (numEntries == 0) + { + /* + * Could mean either full or empty queue + * so look at status + */ + ixQMgrAqmIfQueStatRead (qId, &qStatus); + + if (qId < IX_QMGR_MIN_QUEUPP_QID) + { + if (qStatus & IX_QMGR_Q_STATUS_E_BIT_MASK) + { + /* Empty */ + *numEntriesPtr = 0; + } + else if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK) + { + /* Full */ + *numEntriesPtr = infoPtr->qSizeInEntries; + } + else + { + /* + * Queue status and read/write pointers are volatile. + * The queue state has changed since we took the + * snapshot of the read and write pointers. + * Client can retry if they wish + */ + *numEntriesPtr = 0; + return IX_QMGR_WARNING; + } + } + else /* It is an upper queue which does not have an empty status bit maintained */ + { + if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK) + { + /* The queue is Full at the time of snapshot. */ + *numEntriesPtr = infoPtr->qSizeInEntries; + } + else + { + /* The queue is either empty, either moving, + * Client can retry if they wish + */ + *numEntriesPtr = 0; + return IX_QMGR_WARNING; + } + } + } + else + { + *numEntriesPtr = (numEntries / infoPtr->qEntrySizeInWords) & (infoPtr->qSizeInEntries - 1); + } + + return IX_SUCCESS; +} + +#if defined(__wince) && defined(NO_INLINE_APIS) + +PUBLIC IX_STATUS +ixQMgrQRead (IxQMgrQId qId, + UINT32 *entryPtr) +{ + extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; + IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; + UINT32 entry, entrySize; + + /* get a new entry */ + entrySize = infoPtr->qEntrySizeInWords; + entry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr); + + if (entrySize != IX_QMGR_Q_ENTRY_SIZE1) + { + *entryPtr = entry; + /* process the remaining part of the entry */ + return ixQMgrQReadMWordsMinus1(qId, entryPtr); + } + + /* underflow is available for lower queues only */ + if (qId < IX_QMGR_MIN_QUEUPP_QID) + { + /* the counter of queue entries is decremented. In happy + * day scenario there are many entries in the queue + * and the counter does not reach zero. + */ + if (infoPtr->qReadCount-- == 0) + { + /* There is maybe no entry in the queue + * qReadCount is now negative, but will be corrected before + * the function returns. + */ + UINT32 qPtrs; /* queue internal pointers */ + + /* when a queue is empty, the hw guarantees to return + * a null value. If the value is not null, the queue is + * not empty. + */ + if (entry == 0) + { + /* get the queue status */ + UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); + + /* check the underflow status */ + if (status & infoPtr->qUflowStatBitMask) + { + /* the queue is empty + * clear the underflow status bit if it was set + */ + IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, + status & ~infoPtr->qUflowStatBitMask); + *entryPtr = 0; + infoPtr->qReadCount = 0; + return IX_QMGR_Q_UNDERFLOW; + } + } + /* store the result */ + *entryPtr = entry; + + /* No underflow occured : someone is filling the queue + * or the queue contains null entries. + * The current counter needs to be + * updated from the current number of entries in the queue + */ + + /* get snapshot of queue pointers */ + qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr); + + /* Mod subtraction of pointers to get number of words in Q. */ + qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f; + + if (qPtrs == 0) + { + /* no entry in the queue */ + infoPtr->qReadCount = 0; + } + else + { + /* convert the number of words inside the queue + * to a number of entries + */ + infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1); + } + return IX_SUCCESS; + } + } + *entryPtr = entry; + return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixQMgrQBurstRead (IxQMgrQId qId, + UINT32 numEntries, + UINT32 *entries) +{ + extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; + IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; + UINT32 nullCheckEntry; + + if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1) + { + volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; + + /* the code is optimized to take care of data dependencies: + * Durig a read, there are a few cycles needed to get the + * read complete. During these cycles, it is poossible to + * do some CPU, e.g. increment pointers and decrement + * counters. + */ + + /* fetch a queue entry */ + nullCheckEntry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr); + + /* iterate the specified number of queue entries */ + while (--numEntries) + { + /* check the result of the previous read */ + if (nullCheckEntry == 0) + { + /* if we read a NULL entry, stop. We have underflowed */ + break; + } + else + { + /* write the entry */ + *entries = nullCheckEntry; + /* fetch next entry */ + nullCheckEntry = IX_OSAL_READ_LONG(qAccRegAddr); + /* increment the write address */ + entries++; + } + } + /* write the pre-fetched entry */ + *entries = nullCheckEntry; + } + else + { + IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords; + /* read the specified number of queue entries */ + nullCheckEntry = 0; + while (numEntries--) + { + int i; + + for (i = 0; i < entrySizeInWords; i++) + { + *entries = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr + i); + nullCheckEntry |= *entries++; + } + + /* if we read a NULL entry, stop. We have underflowed */ + if (nullCheckEntry == 0) + { + break; + } + nullCheckEntry = 0; + } + } + + /* reset the current read count : next access to the read function + * will force a underflow status check + */ + infoPtr->qWriteCount = 0; + + /* Check if underflow occurred on the read */ + if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID) + { + /* get the queue status */ + UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); + + if (status & infoPtr->qUflowStatBitMask) + { + /* clear the underflow status bit if it was set */ + IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, + status & ~infoPtr->qUflowStatBitMask); + return IX_QMGR_Q_UNDERFLOW; + } + } + + return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixQMgrQWrite (IxQMgrQId qId, + UINT32 *entry) +{ + extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; + IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; + UINT32 entrySize; + + /* write the entry */ + IX_OSAL_WRITE_LONG(infoPtr->qAccRegAddr, *entry); + entrySize = infoPtr->qEntrySizeInWords; + + if (entrySize != IX_QMGR_Q_ENTRY_SIZE1) + { + /* process the remaining part of the entry */ + volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; + while (--entrySize) + { + ++entry; + IX_OSAL_WRITE_LONG(++qAccRegAddr, *entry); + } + entrySize = infoPtr->qEntrySizeInWords; + } + + /* overflow is available for lower queues only */ + if (qId < IX_QMGR_MIN_QUEUPP_QID) + { + UINT32 qSize = infoPtr->qSizeInEntries; + /* increment the current number of entries in the queue + * and check for overflow + */ + if (infoPtr->qWriteCount++ == qSize) + { + /* the queue may have overflow */ + UINT32 qPtrs; /* queue internal pointers */ + + /* get the queue status */ + UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); + + /* read the status twice because the status may + * not be immediately ready after the write operation + */ + if ((status & infoPtr->qOflowStatBitMask) || + ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr)) + & infoPtr->qOflowStatBitMask)) + { + /* the queue is full, clear the overflow status + * bit if it was set + */ + IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, + status & ~infoPtr->qOflowStatBitMask); + infoPtr->qWriteCount = infoPtr->qSizeInEntries; + return IX_QMGR_Q_OVERFLOW; + } + /* No overflow occured : someone is draining the queue + * and the current counter needs to be + * updated from the current number of entries in the queue + */ + + /* get q pointer snapshot */ + qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr); + + /* Mod subtraction of pointers to get number of words in Q. */ + qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f; + + if (qPtrs == 0) + { + /* the queue may be full at the time of the + * snapshot. Next access will check + * the overflow status again. + */ + infoPtr->qWriteCount = qSize; + } + else + { + /* convert the number of words to a number of entries */ + if (entrySize == IX_QMGR_Q_ENTRY_SIZE1) + { + infoPtr->qWriteCount = qPtrs & (qSize - 1); + } + else + { + infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1); + } + } + } + } + return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixQMgrQBurstWrite (IxQMgrQId qId, + unsigned numEntries, + UINT32 *entries) +{ + extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; + IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; + UINT32 status; + + /* update the current write count */ + infoPtr->qWriteCount += numEntries; + + if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1) + { + volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr; + while (numEntries--) + { + IX_OSAL_WRITE_LONG(qAccRegAddr, *entries); + entries++; + } + } + else + { + IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords; + int i; + + /* write each queue entry */ + while (numEntries--) + { + /* write the queueEntrySize number of words for each entry */ + for (i = 0; i < entrySizeInWords; i++) + { + IX_OSAL_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries); + entries++; + } + } + } + + /* check if the write count overflows */ + if (infoPtr->qWriteCount > infoPtr->qSizeInEntries) + { + /* reset the current write count */ + infoPtr->qWriteCount = infoPtr->qSizeInEntries; + } + + /* Check if overflow occurred on the write operation */ + if (qId < IX_QMGR_MIN_QUEUPP_QID) + { + /* get the queue status */ + status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr); + + /* read the status twice because the status may + * not be ready at the time of the write + */ + if ((status & infoPtr->qOflowStatBitMask) || + ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr)) + & infoPtr->qOflowStatBitMask)) + { + /* clear the underflow status bit if it was set */ + IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr, + status & ~infoPtr->qOflowStatBitMask); + return IX_QMGR_Q_OVERFLOW; + } + } + + return IX_SUCCESS; +} + +PUBLIC IX_STATUS +ixQMgrQStatusGet (IxQMgrQId qId, + IxQMgrQStatus *qStatus) +{ + /* read the status of a queue in the range 0-31 */ + if (qId < IX_QMGR_MIN_QUEUPP_QID) + { + extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[]; + extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[]; + extern UINT32 ixQMgrAqmIfQueLowStatBitsMask; + extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[]; + IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId]; + volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId]; + volatile UINT32 *qUOStatRegAddr = infoPtr->qUOStatRegAddr; + + UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId]; + UINT32 lowStatBitsMask = ixQMgrAqmIfQueLowStatBitsMask; + UINT32 underflowBitMask = infoPtr->qUflowStatBitMask; + UINT32 overflowBitMask = infoPtr->qOflowStatBitMask; + + /* read the status register for this queue */ + *qStatus = IX_OSAL_READ_LONG(lowStatRegAddr); + /* mask out the status bits relevant only to this queue */ + *qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask; + + /* Check if the queue has overflowed */ + if (IX_OSAL_READ_LONG(qUOStatRegAddr) & overflowBitMask) + { + /* clear the overflow status bit if it was set */ + IX_OSAL_WRITE_LONG(qUOStatRegAddr, + (IX_OSAL_READ_LONG(qUOStatRegAddr) & + ~overflowBitMask)); + *qStatus |= IX_QMGR_Q_STATUS_OF_BIT_MASK; + } + + /* Check if the queue has underflowed */ + if (IX_OSAL_READ_LONG(qUOStatRegAddr) & underflowBitMask) + { + /* clear the underflow status bit if it was set */ + IX_OSAL_WRITE_LONG(qUOStatRegAddr, + (IX_OSAL_READ_LONG(qUOStatRegAddr) & + ~underflowBitMask)); + *qStatus |= IX_QMGR_Q_STATUS_UF_BIT_MASK; + } + } + else /* read status of a queue in the range 32-63 */ + { + extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr; + extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr; + extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[]; + extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[]; + + volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr; + volatile UINT32 *qFullStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr; + int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID; + UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex]; + UINT32 qFullStatBitMask = ixQMgrAqmIfQueUppStat1BitMask[maskIndex]; + + /* Reset the status bits */ + *qStatus = 0; + + /* Check if the queue is nearly empty */ + if (IX_OSAL_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask) + { + *qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK; + } + + /* Check if the queue is full */ + if (IX_OSAL_READ_LONG(qFullStatRegAddr) & qFullStatBitMask) + { + *qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK; + } + } + return IX_SUCCESS; +} +#endif /* def NO_INLINE_APIS */ diff --git a/drivers/net/npe/IxQMgrQCfg.c b/drivers/net/npe/IxQMgrQCfg.c new file mode 100644 index 0000000..ec7d837 --- /dev/null +++ b/drivers/net/npe/IxQMgrQCfg.c @@ -0,0 +1,543 @@ +/** + * @file QMgrQCfg.c + * + * @author Intel Corporation + * @date 30-Oct-2001 + * + * @brief This modules provides an interface for setting up the static + * configuration of AQM queues.This file contains the following + * functions: + * + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* + * System defined include files. + */ + +/* + * User defined include files. + */ +#include "IxOsal.h" +#include "IxQMgr.h" +#include "IxQMgrAqmIf_p.h" +#include "IxQMgrQCfg_p.h" +#include "IxQMgrDefines_p.h" + +/* + * #defines and macros used in this file. + */ + +#define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16 + +/* Total size of SRAM */ +#define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000 + +/* + * Check that qId is a valid queue identifier. This is provided to + * make the code easier to read. + */ +#define IX_QMGR_QID_IS_VALID(qId) \ +(((qId) >= (IX_QMGR_MIN_QID)) && ((qId) <= (IX_QMGR_MAX_QID))) + +/* + * Typedefs whose scope is limited to this file. + */ + +/* + * This struct describes an AQM queue. + * N.b. bufferSizeInWords and qEntrySizeInWords are stored in the queue + * as these are requested by Access in the data path. sizeInEntries is + * not required by the data path so it can be calculated dynamically. + * + */ +typedef struct +{ + char qName[IX_QMGR_MAX_QNAME_LEN+1]; /* Textual description of a queue*/ + IxQMgrQSizeInWords qSizeInWords; /* The number of words in the queue */ + IxQMgrQEntrySizeInWords qEntrySizeInWords; /* Number of words per queue entry*/ + BOOL isConfigured; /* This flag is TRUE if the queue has + * been configured + */ +} IxQMgrCfgQ; + +/* + * Variable declarations global to this file. Externs are followed by + * statics. + */ + +extern UINT32 * ixQMgrAqmIfQueAccRegAddr[]; + +/* Store data required to inline read and write access + */ +IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[IX_QMGR_MAX_NUM_QUEUES]; + +static IxQMgrCfgQ cfgQueueInfo[IX_QMGR_MAX_NUM_QUEUES]; + +/* This pointer holds the starting address of AQM SRAM not used by + * the AQM queues. + */ +static UINT32 freeSramAddress=0; + +/* 4 words of zeroed memory for inline access */ +static UINT32 zeroedPlaceHolder[4] = { 0, 0, 0, 0 }; + +static BOOL cfgInitialized = FALSE; + +static IxOsalMutex ixQMgrQCfgMutex; + +/* + * Statistics + */ +static IxQMgrQCfgStats stats; + +/* + * Function declarations + */ +PRIVATE BOOL +watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level); + +PRIVATE BOOL +qSizeInWordsIsOk (IxQMgrQSizeInWords qSize); + +PRIVATE BOOL +qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize); + +/* + * Function definitions. + */ +void +ixQMgrQCfgInit (void) +{ + int loopIndex; + + for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++) + { + /* info for code inlining */ + ixQMgrAqmIfQueAccRegAddr[loopIndex] = zeroedPlaceHolder; + + /* info for code inlining */ + ixQMgrQInlinedReadWriteInfo[loopIndex].qReadCount = 0; + ixQMgrQInlinedReadWriteInfo[loopIndex].qWriteCount = 0; + ixQMgrQInlinedReadWriteInfo[loopIndex].qAccRegAddr = zeroedPlaceHolder; + ixQMgrQInlinedReadWriteInfo[loopIndex].qUOStatRegAddr = zeroedPlaceHolder; + ixQMgrQInlinedReadWriteInfo[loopIndex].qUflowStatBitMask = 0; + ixQMgrQInlinedReadWriteInfo[loopIndex].qOflowStatBitMask = 0; + ixQMgrQInlinedReadWriteInfo[loopIndex].qEntrySizeInWords = 0; + ixQMgrQInlinedReadWriteInfo[loopIndex].qSizeInEntries = 0; + ixQMgrQInlinedReadWriteInfo[loopIndex].qConfigRegAddr = zeroedPlaceHolder; + } + + /* Initialise the AqmIf component */ + ixQMgrAqmIfInit (); + + /* Reset all queues to have queue name = NULL, entry size = 0 and + * isConfigured = false + */ + for (loopIndex=0; loopIndex < IX_QMGR_MAX_NUM_QUEUES;loopIndex++) + { + strcpy (cfgQueueInfo[loopIndex].qName, ""); + cfgQueueInfo[loopIndex].qSizeInWords = 0; + cfgQueueInfo[loopIndex].qEntrySizeInWords = 0; + cfgQueueInfo[loopIndex].isConfigured = FALSE; + + /* Statistics */ + stats.qStats[loopIndex].isConfigured = FALSE; + stats.qStats[loopIndex].qName = cfgQueueInfo[loopIndex].qName; + } + + /* Statistics */ + stats.wmSetCnt = 0; + + ixQMgrAqmIfSramBaseAddressGet (&freeSramAddress); + + ixOsalMutexInit(&ixQMgrQCfgMutex); + + cfgInitialized = TRUE; +} + +void +ixQMgrQCfgUninit (void) +{ + cfgInitialized = FALSE; + + /* Uninitialise the AqmIf component */ + ixQMgrAqmIfUninit (); +} + +IX_STATUS +ixQMgrQConfig (char *qName, + IxQMgrQId qId, + IxQMgrQSizeInWords qSizeInWords, + IxQMgrQEntrySizeInWords qEntrySizeInWords) +{ + UINT32 aqmLocalBaseAddress; + + if (!cfgInitialized) + { + return IX_FAIL; + } + + if (!IX_QMGR_QID_IS_VALID(qId)) + { + return IX_QMGR_INVALID_Q_ID; + } + + else if (NULL == qName) + { + return IX_QMGR_PARAMETER_ERROR; + } + + else if (strlen (qName) > IX_QMGR_MAX_QNAME_LEN) + { + return IX_QMGR_PARAMETER_ERROR; + } + + else if (!qSizeInWordsIsOk (qSizeInWords)) + { + return IX_QMGR_INVALID_QSIZE; + } + + else if (!qEntrySizeInWordsIsOk (qEntrySizeInWords)) + { + return IX_QMGR_INVALID_Q_ENTRY_SIZE; + } + + else if (cfgQueueInfo[qId].isConfigured) + { + return IX_QMGR_Q_ALREADY_CONFIGURED; + } + + ixOsalMutexLock(&ixQMgrQCfgMutex, IX_OSAL_WAIT_FOREVER); + + /* Write the config register */ + ixQMgrAqmIfQueCfgWrite (qId, + qSizeInWords, + qEntrySizeInWords, + freeSramAddress); + + + strcpy (cfgQueueInfo[qId].qName, qName); + cfgQueueInfo[qId].qSizeInWords = qSizeInWords; + cfgQueueInfo[qId].qEntrySizeInWords = qEntrySizeInWords; + + /* store pre-computed information in the same cache line + * to facilitate inlining of QRead and QWrite functions + * in IxQMgr.h + */ + ixQMgrQInlinedReadWriteInfo[qId].qReadCount = 0; + ixQMgrQInlinedReadWriteInfo[qId].qWriteCount = 0; + ixQMgrQInlinedReadWriteInfo[qId].qEntrySizeInWords = qEntrySizeInWords; + ixQMgrQInlinedReadWriteInfo[qId].qSizeInEntries = + (UINT32)qSizeInWords / (UINT32)qEntrySizeInWords; + + /* Calculate the new freeSramAddress from the size of the queue + * currently being configured. + */ + freeSramAddress += (qSizeInWords * IX_QMGR_NUM_BYTES_PER_WORD); + + /* Get the virtual SRAM address */ + ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress); + + IX_OSAL_ASSERT((freeSramAddress - (aqmLocalBaseAddress + (IX_QMGR_QUEBUFFER_SPACE_OFFSET))) <= + IX_QMGR_QUE_BUFFER_SPACE_SIZE); + + /* The queue is now configured */ + cfgQueueInfo[qId].isConfigured = TRUE; + + ixOsalMutexUnlock(&ixQMgrQCfgMutex); + +#ifndef NDEBUG + /* Update statistics */ + stats.qStats[qId].isConfigured = TRUE; + stats.qStats[qId].qName = cfgQueueInfo[qId].qName; +#endif + return IX_SUCCESS; +} + +IxQMgrQSizeInWords +ixQMgrQSizeInWordsGet (IxQMgrQId qId) +{ + /* No parameter checking as this is used on the data path */ + return (cfgQueueInfo[qId].qSizeInWords); +} + +IX_STATUS +ixQMgrQSizeInEntriesGet (IxQMgrQId qId, + unsigned *qSizeInEntries) +{ + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + + if(NULL == qSizeInEntries) + { + return IX_QMGR_PARAMETER_ERROR; + } + + *qSizeInEntries = (UINT32)(cfgQueueInfo[qId].qSizeInWords) / + (UINT32)cfgQueueInfo[qId].qEntrySizeInWords; + + return IX_SUCCESS; +} + +IxQMgrQEntrySizeInWords +ixQMgrQEntrySizeInWordsGet (IxQMgrQId qId) +{ + /* No parameter checking as this is used on the data path */ + return (cfgQueueInfo[qId].qEntrySizeInWords); +} + +IX_STATUS +ixQMgrWatermarkSet (IxQMgrQId qId, + IxQMgrWMLevel ne, + IxQMgrWMLevel nf) +{ + IxQMgrQStatus qStatusOnEntry;/* The queue status on entry/exit */ + IxQMgrQStatus qStatusOnExit; /* to this function */ + + if (!ixQMgrQIsConfigured(qId)) + { + return IX_QMGR_Q_NOT_CONFIGURED; + } + + if (!watermarkLevelIsOk (qId, ne)) + { + return IX_QMGR_INVALID_Q_WM; + } + + if (!watermarkLevelIsOk (qId, nf)) + { + return IX_QMGR_INVALID_Q_WM; + } + + /* Get the current queue status */ + ixQMgrAqmIfQueStatRead (qId, &qStatusOnEntry); + +#ifndef NDEBUG + /* Update statistics */ + stats.wmSetCnt++; +#endif + + ixQMgrAqmIfWatermarkSet (qId, + ne, + nf); + + /* Get the current queue status */ + ixQMgrAqmIfQueStatRead (qId, &qStatusOnExit); + + /* If the status has changed return a warning */ + if (qStatusOnEntry != qStatusOnExit) + { + return IX_QMGR_WARNING; + } + + return IX_SUCCESS; +} + +IX_STATUS +ixQMgrAvailableSramAddressGet (UINT32 *address, + unsigned *sizeOfFreeRam) +{ + UINT32 aqmLocalBaseAddress; + + if ((NULL == address)||(NULL == sizeOfFreeRam)) + { + return IX_QMGR_PARAMETER_ERROR; + } + if (!cfgInitialized) + { + return IX_FAIL; + } + + *address = freeSramAddress; + + /* Get the virtual SRAM address */ + ixQMgrAqmIfBaseAddressGet (&aqmLocalBaseAddress); + + /* + * Calculate the size in bytes of free sram + * i.e. current free SRAM virtual pointer from + * (base + total size) + */ + *sizeOfFreeRam = + (aqmLocalBaseAddress + + IX_QMGR_AQM_SRAM_SIZE_IN_BYTES) - + freeSramAddress; + + if (0 == *sizeOfFreeRam) + { + return IX_QMGR_NO_AVAILABLE_SRAM; + } + + return IX_SUCCESS; +} + +BOOL +ixQMgrQIsConfigured (IxQMgrQId qId) +{ + if (!IX_QMGR_QID_IS_VALID(qId)) + { + return FALSE; + } + + return cfgQueueInfo[qId].isConfigured; +} + +IxQMgrQCfgStats* +ixQMgrQCfgStatsGet (void) +{ + return &stats; +} + +IxQMgrQCfgStats* +ixQMgrQCfgQStatsGet (IxQMgrQId qId) +{ + unsigned int ne; + unsigned int nf; + UINT32 baseAddress; + UINT32 readPtr; + UINT32 writePtr; + + stats.qStats[qId].qSizeInWords = cfgQueueInfo[qId].qSizeInWords; + stats.qStats[qId].qEntrySizeInWords = cfgQueueInfo[qId].qEntrySizeInWords; + + if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries)) + { + if (IX_QMGR_WARNING != ixQMgrQNumEntriesGet (qId, &stats.qStats[qId].numEntries)) + { + IX_QMGR_LOG_WARNING1("Failed to get the number of entries in queue.... %d\n", qId); + } + } + + ixQMgrAqmIfQueCfgRead (qId, + stats.qStats[qId].numEntries, + &baseAddress, + &ne, + &nf, + &readPtr, + &writePtr); + + stats.qStats[qId].baseAddress = baseAddress; + stats.qStats[qId].ne = ne; + stats.qStats[qId].nf = nf; + stats.qStats[qId].readPtr = readPtr; + stats.qStats[qId].writePtr = writePtr; + + return &stats; +} + +/* + * Static function definitions + */ + +PRIVATE BOOL +watermarkLevelIsOk (IxQMgrQId qId, IxQMgrWMLevel level) +{ + unsigned qSizeInEntries; + + switch (level) + { + case IX_QMGR_Q_WM_LEVEL0: + case IX_QMGR_Q_WM_LEVEL1: + case IX_QMGR_Q_WM_LEVEL2: + case IX_QMGR_Q_WM_LEVEL4: + case IX_QMGR_Q_WM_LEVEL8: + case IX_QMGR_Q_WM_LEVEL16: + case IX_QMGR_Q_WM_LEVEL32: + case IX_QMGR_Q_WM_LEVEL64: + break; + default: + return FALSE; + } + + /* Check watermark is not bigger than the qSizeInEntries */ + ixQMgrQSizeInEntriesGet(qId, &qSizeInEntries); + + if ((unsigned)level > qSizeInEntries) + { + return FALSE; + } + + return TRUE; +} + +PRIVATE BOOL +qSizeInWordsIsOk (IxQMgrQSizeInWords qSize) +{ + BOOL status; + + switch (qSize) + { + case IX_QMGR_Q_SIZE16: + case IX_QMGR_Q_SIZE32: + case IX_QMGR_Q_SIZE64: + case IX_QMGR_Q_SIZE128: + status = TRUE; + break; + default: + status = FALSE; + break; + } + + return status; +} + +PRIVATE BOOL +qEntrySizeInWordsIsOk (IxQMgrQEntrySizeInWords entrySize) +{ + BOOL status; + + switch (entrySize) + { + case IX_QMGR_Q_ENTRY_SIZE1: + case IX_QMGR_Q_ENTRY_SIZE2: + case IX_QMGR_Q_ENTRY_SIZE4: + status = TRUE; + break; + default: + status = FALSE; + break; + } + + return status; +} diff --git a/drivers/net/npe/Makefile b/drivers/net/npe/Makefile new file mode 100644 index 0000000..d13391b --- /dev/null +++ b/drivers/net/npe/Makefile @@ -0,0 +1,99 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)libnpe.o + +LOCAL_CFLAGS += -I$(TOPDIR)/drivers/net/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux +CFLAGS += $(LOCAL_CFLAGS) +CPPFLAGS += $(LOCAL_CFLAGS) # needed for depend +HOSTCFLAGS += $(LOCAL_CFLAGS) + +COBJS-$(CONFIG_IXP4XX_NPE) := npe.o \ + miiphy.o \ + IxOsalBufferMgt.o \ + IxOsalIoMem.o \ + IxOsalOsCacheMMU.o \ + IxOsalOsMsgQ.o \ + IxOsalOsSemaphore.o \ + IxOsalOsServices.o \ + IxOsalOsThread.o \ + IxEthAcc.o \ + IxEthAccCommon.o \ + IxEthAccControlInterface.o \ + IxEthAccDataPlane.o \ + IxEthAccMac.o \ + IxEthAccMii.o \ + IxEthDBAPI.o \ + IxEthDBAPISupport.o \ + IxEthDBCore.o \ + IxEthDBEvents.o \ + IxEthDBFeatures.o \ + IxEthDBFirewall.o \ + IxEthDBHashtable.o \ + IxEthDBLearning.o \ + IxEthDBMem.o \ + IxEthDBNPEAdaptor.o \ + IxEthDBPortUpdate.o \ + IxEthDBReports.o \ + IxEthDBSearch.o \ + IxEthDBSpanningTree.o \ + IxEthDBUtil.o \ + IxEthDBVlan.o \ + IxEthDBWiFi.o \ + IxEthMii.o \ + IxQMgrAqmIf.o \ + IxQMgrDispatcher.o \ + IxQMgrInit.o \ + IxQMgrQAccess.o \ + IxQMgrQCfg.o \ + IxFeatureCtrl.o \ + IxNpeDl.o \ + IxNpeDlImageMgr.o \ + IxNpeDlNpeMgr.o \ + IxNpeDlNpeMgrUtils.o \ + IxNpeMh.o \ + IxNpeMhConfig.o \ + IxNpeMhReceive.o \ + IxNpeMhSend.o \ + IxNpeMhSolicitedCbMgr.o \ + IxNpeMhUnsolicitedCbMgr.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/drivers/net/npe/include/IxAssert.h b/drivers/net/npe/include/IxAssert.h new file mode 100644 index 0000000..eae8b3f --- /dev/null +++ b/drivers/net/npe/include/IxAssert.h @@ -0,0 +1,71 @@ +/** + * @file IxAssert.h + * + * @date 21-MAR-2002 (replaced by OSAL) + * + * @brief This file contains assert and ensure macros used by the IXP400 software + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @defgroup IxAssert IXP400 Assertion Macros (IxAssert) API + * + * @brief Assertion support + * + * @{ + */ + +#ifndef IXASSERT_H + +#ifndef __doxygen_HIDE +#define IXASSERT_H +#endif /* __doxygen_HIDE */ + +#include "IxOsalBackward.h" + +#endif /* IXASSERT_H */ + +/** + * @} addtogroup IxAssert + */ + + + diff --git a/drivers/net/npe/include/IxAtmSch.h b/drivers/net/npe/include/IxAtmSch.h new file mode 100644 index 0000000..73c3be2 --- /dev/null +++ b/drivers/net/npe/include/IxAtmSch.h @@ -0,0 +1,504 @@ +/** + * @file IxAtmSch.h + * + * @date 23-NOV-2001 + * + * @brief Header file for the IXP400 ATM Traffic Shaper + * + * This component demonstrates an ATM Traffic Shaper implementation. It + * will perform shaping on upto 12 ports and total of 44 VCs accross all ports, + * 32 are intended for AAL0/5 and 12 for OAM (1 per port). + * The supported traffic types are;1 rt-VBR VC where PCR = SCR. + * (Effectively CBR) and Up-to 44 VBR VCs. + * + * This component models the ATM ports and VCs and is capable of producing + * a schedule of ATM cells per port which can be supplied to IxAtmdAcc + * for execution on the data path. + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * + * @sa IxAtmm.h + * + */ + +/** + * @defgroup IxAtmSch IXP400 ATM Transmit Scheduler (IxAtmSch) API + * + * @brief IXP400 ATM scheduler component Public API + * + * @{ + */ + +#ifndef IXATMSCH_H +#define IXATMSCH_H + +#include "IxOsalTypes.h" +#include "IxAtmTypes.h" + +/* + * #defines and macros used in this file. + */ + +/* Return codes */ + +/** + * @ingroup IxAtmSch + * + * @def IX_ATMSCH_RET_NOT_ADMITTED + * @brief Indicates that CAC function has rejected VC registration due + * to insufficient line capacity. +*/ +#define IX_ATMSCH_RET_NOT_ADMITTED 2 + +/** + * @ingroup IxAtmSch + * + * @def IX_ATMSCH_RET_QUEUE_FULL + * @brief Indicates that the VC queue is full, no more demand can be + * queued at this time. + */ +#define IX_ATMSCH_RET_QUEUE_FULL 3 + +/** + * @ingroup IxAtmSch + * + * @def IX_ATMSCH_RET_QUEUE_EMPTY + * @brief Indicates that all VC queues on this port are empty and + * therefore there are no cells to be scheduled at this time. + */ +#define IX_ATMSCH_RET_QUEUE_EMPTY 4 + +/* + * Function declarations + */ + +/** + * @ingroup IxAtmSch + * + * @fn ixAtmSchInit(void) + * + * @brief This function is used to initialize the ixAtmSch component. It + * should be called before any other IxAtmSch API function. + * + * @param None + * + * @return + * - IX_SUCCESS : indicates that + * -# The ATM scheduler component has been successfully initialized. + * -# The scheduler is ready to accept Port modelling requests. + * - IX_FAIL : Some internal error has prevented the scheduler component + * from initialising. + */ +PUBLIC IX_STATUS +ixAtmSchInit(void); + +/** + * @ingroup IxAtmSch + * + * @fn ixAtmSchPortModelInitialize( IxAtmLogicalPort port, + unsigned int portRate, + unsigned int minCellsToSchedule) + * + * @brief This function shall be called first to initialize an ATM port before + * any other ixAtmSch API calls may be made for that port. + * + * @param port @ref IxAtmLogicalPort [in] - The specific port to initialize. Valid + * values range from 0 to IX_UTOPIA_MAX_PORTS - 1, representing a + * maximum of IX_UTOPIA_MAX_PORTS possible ports. + * + * @param portRate unsigned int [in] - Value indicating the upstream capacity + * of the indicated port. The value should be supplied in + * units of ATM (53 bytes) cells per second. + * A port rate of 800Kbits/s is the equivalent + * of 1886 cells per second + * + * @param minCellsToSchedule unsigned int [in] - This parameter specifies the minimum + * number of cells which the scheduler will put in a schedule + * table for this port. This value sets the worst case CDVT for VCs + * on this port i.e. CDVT = 1*minCellsToSchedule/portRate. + * @return + * - IX_SUCCESS : indicates that + * -# The ATM scheduler has been successfully initialized. + * -# The requested port model has been established. + * -# The scheduler is ready to accept VC modelling requests + * on the ATM port. + * - IX_FAIL : indicates the requested port could not be + * initialized. */ +PUBLIC IX_STATUS +ixAtmSchPortModelInitialize( IxAtmLogicalPort port, + unsigned int portRate, + unsigned int minCellsToSchedule); + +/** + * @ingroup IxAtmSch + * + * @fn ixAtmSchPortRateModify( IxAtmLogicalPort port, + unsigned int portRate) + * + * @brief This function is called to modify the portRate on a + * previously initialized port, typically in the event that + * the line condition of the port changes. + * + * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port which is to be + * modified. + * + * @param portRate unsigned int [in] - Value indicating the new upstream + * capacity for this port in cells/second. + * A port rate of 800Kbits/s is the equivalent + * of 1886 cells per second + * + * @return + * - IX_SUCCESS : The port rate has been successfully modified.
+ * - IX_FAIL : The port rate could not be modified, either + * because the input data was invalid, or the new port rate is + * insufficient to support established ATM VC contracts on this + * port. + * + * @warning The IxAtmSch component will validate the supplied port + * rate is sufficient to support all established VC + * contracts on the port. If the new port rate is + * insufficient to support all established contracts then + * the request to modify the port rate will be rejected. + * In this event, the user is expected to remove + * established contracts using the ixAtmSchVcModelRemove + * interface and then retry this interface. + * + * @sa ixAtmSchVcModelRemove() */ +PUBLIC IX_STATUS +ixAtmSchPortRateModify( IxAtmLogicalPort port, + unsigned int portRate); + + +/** + * @ingroup IxAtmSch + * + * @fn ixAtmSchVcModelSetup( IxAtmLogicalPort port, + IxAtmTrafficDescriptor *trafficDesc, + IxAtmSchedulerVcId *vcId) + * + * @brief A client calls this interface to set up an upstream + * (transmitting) virtual connection model (VC) on the + * specified ATM port. This function also provides the + * virtual * connection admission control (CAC) service to the + * client. + * + * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the upstream + * VC is to be established. + * + * @param *trafficDesc @ref IxAtmTrafficDescriptor [in] - Pointer to a structure + * describing the requested traffic contract of the VC to be + * established. This structure contains the typical ATM + * traffic descriptor values (e.g. PCR, SCR, MBS, CDVT, etc.) + * defined by the ATM standard. + * + * @param *vcId @ref IxAtmSchedulerVcId [out] - This value will be filled with the + * port-unique identifier for this virtual connection. A + * valid identification is a non-negative number. + * + * @return + * - IX_SUCCESS : The VC has been successfully established on + * this port. The client may begin to submit demand on this VC. + * - IX_ATMSCH_RET_NOT_ADMITTED : The VC cannot be established + * on this port because there is insufficient upstream capacity + * available to support the requested traffic contract descriptor + * - IX_FAIL :Input data are invalid. VC has not been + * established. + */ +PUBLIC IX_STATUS +ixAtmSchVcModelSetup( IxAtmLogicalPort port, + IxAtmTrafficDescriptor *trafficDesc, + IxAtmSchedulerVcId *vcId); + +/** + * @ingroup IxAtmSch + * + * @fn ixAtmSchVcConnIdSet( IxAtmLogicalPort port, + IxAtmSchedulerVcId vcId, + IxAtmConnId vcUserConnId) + * + * @brief A client calls this interface to set the vcUserConnId for a VC on + * the specified ATM port. This vcUserConnId will default to + * IX_ATM_IDLE_CELLS_CONNID if this function is not called for a VC. + * Hence if the client does not call this function for a VC then only idle + * cells will be scheduled for this VC. + * + * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the upstream + * VC is has been established. + * + * @param vcId @ref IxAtmSchedulerVcId [in] - This is the unique identifier for this virtual + * connection. A valid identification is a non-negative number and is + * all ports. + * + * @param vcUserConnId @ref IxAtmConnId [in] - The connId is used to refer to a VC in schedule + * table entries. It is treated as the Id by which the scheduler client + * knows the VC. It is used in any communicatations from the Scheduler + * to the scheduler user e.g. schedule table entries. + * + * @return + * - IX_SUCCESS : The id has successfully been set. + * - IX_FAIL :Input data are invalid. connId id is not established. + */ +PUBLIC IX_STATUS +ixAtmSchVcConnIdSet( IxAtmLogicalPort port, + IxAtmSchedulerVcId vcId, + IxAtmConnId vcUserConnId); + +/** + * @ingroup IxAtmSch + * + * @fn ixAtmSchVcModelRemove( IxAtmLogicalPort port, + IxAtmSchedulerVcId vcId) + * + * @brief Interface called by the client to remove a previously + * established VC on a particular port. + * + * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be + * removed is established. + * + * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be removed. This is the + * value returned by the @ref ixAtmSchVcModelSetup call which + * established the relevant VC. + * + * @return + * - IX_SUCCESS : The VC has been successfully removed from + * this port. It is no longer modelled on this port. + * - IX_FAIL :Input data are invalid. The VC is still being modeled + * by the traffic shaper. + * + * @sa ixAtmSchVcModelSetup() + */ +PUBLIC IX_STATUS +ixAtmSchVcModelRemove( IxAtmLogicalPort port, + IxAtmSchedulerVcId vcId); + +/** + * @ingroup IxAtmSch + * + * @fn ixAtmSchVcQueueUpdate( IxAtmLogicalPort port, + IxAtmSchedulerVcId vcId, + unsigned int numberOfCells) + * + * @brief The client calls this function to notify IxAtmSch that the + * user of a VC has submitted cells for transmission. + * + * This information is stored, aggregated from a number of calls to + * ixAtmSchVcQueueUpdate and eventually used in the call to + * ixAtmSchTableUpdate. + * + * Normally IxAtmSch will update the VC queue by adding the number of + * cells to the current queue length. However, if IxAtmSch + * determines that the user has over-submitted for the VC and + * exceeded its transmission quota the queue request can be rejected. + * The user should resubmit the request later when the queue has been + * depleted. + * + * This implementation of ixAtmSchVcQueueUpdate uses no operating + * system or external facilities, either directly or indirectly. + * This allows clients to call this function form within an interrupt handler. + * + * This interface is structurally compatible with the + * IxAtmdAccSchQueueUpdate callback type definition required for + * IXP400 ATM scheduler interoperability. + * + * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be + * updated is established. + * + * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be updated. This is the + * value returned by the @ref ixAtmSchVcModelSetup call which + * established the relevant VC. + * + * @param numberOfCells unsigned int [in] - Indicates how many ATM cells should + * be added to the queue for this VC. + * + * @return + * - IX_SUCCESS : The VC queue has been successfully updated. + * - IX_ATMSCH_RET_QUEUE_FULL : The VC queue has reached a + * preset limit. This indicates the client has over-submitted + * and exceeded its transmission quota. The request is + * rejected. The VC queue is not updated. The VC user is + * advised to resubmit the request later. + * - IX_FAIL : The input are invalid. No VC queue is updated. + * + * @warning IxAtmSch assumes that the calling software ensures that + * calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and + * ixAtmSchTableUpdate are both self and mutually exclusive + * for the same port. + * + * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */ +PUBLIC IX_STATUS +ixAtmSchVcQueueUpdate( IxAtmLogicalPort port, + IxAtmSchedulerVcId vcId, + unsigned int numberOfCells); + +/** + * @ingroup IxAtmSch + * + * @fn ixAtmSchVcQueueClear( IxAtmLogicalPort port, + IxAtmSchedulerVcId vcId) + * + * @brief The client calls this function to remove all currently + * queued cells from a registered VC. The pending cell count + * for the specified VC is reset to zero. + * + * This interface is structurally compatible with the + * IxAtmdAccSchQueueClear callback type definition required for + * IXP400 ATM scheduler interoperability. + * + * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be + * cleared is established. + * + * @param vcId @ref IxAtmSchedulerVcId [in] - Identifies the VC to be cleared. This is the + * value returned by the @ref ixAtmSchVcModelSetup call which + * established the relevant VC. + * + * @return + * - IX_SUCCESS : The VC queue has been successfully cleared. + * - IX_FAIL : The input are invalid. No VC queue is modified. + * + * @warning IxAtmSch assumes that the calling software ensures that + * calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and + * ixAtmSchTableUpdate are both self and mutually exclusive + * for the same port. + * + * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */ +PUBLIC IX_STATUS +ixAtmSchVcQueueClear( IxAtmLogicalPort port, + IxAtmSchedulerVcId vcId); + +/** + * @ingroup IxAtmSch + * + * @fn ixAtmSchTableUpdate( IxAtmLogicalPort port, + unsigned int maxCells, + IxAtmScheduleTable **rettable) + * + * @brief The client calls this function to request an update of the + * schedule table for a particular ATM port. + * + * This is called when the client decides it needs a new sequence of + * cells to send (probably because the transmit queue is near to + * empty for this ATM port). The scheduler will use its stored + * information on the cells submitted for transmit (i.e. data + * supplied via @ref ixAtmSchVcQueueUpdate function) with the traffic + * descriptor information of all established VCs on the ATM port to + * decide the sequence of cells to be sent and fill the schedule + * table for a period of time into the future. + * + * IxAtmSch will guarantee a minimum of minCellsToSchedule if there + * is at least one cell ready to send. If there are no cells then + * IX_ATMSCH_RET_QUEUE_EMPTY is returned. + * + * This implementation of ixAtmSchTableUpdate uses no operating + * system or external facilities, either directly or indirectly. + * This allows clients to call this function form within an FIQ + * interrupt handler. + * + * @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port for which requested + * schedule table is to be generated. + * + * @param maxCells unsigned [in] - Specifies the maximum number of cells + * that must be scheduled in the supplied table during any + * call to the interface. + * + * @param **table @ref IxAtmScheduleTable [out] - A pointer to an area of + * storage is returned which contains the generated + * schedule table. The client should not modify the + * contents of this table. + * + * @return + * - IX_SUCCESS : The schedule table has been published. + * Currently there is at least one VC queue that is nonempty. + * - IX_ATMSCH_RET_QUEUE_EMPTY : Currently all VC queues on + * this port are empty. The schedule table returned is set to + * NULL. The client is not expected to invoke this function + * again until more cells have been submitted on this port + * through the @ref ixAtmSchVcQueueUpdate function. + * - IX_FAIL : The input are invalid. No action is taken. + * + * @warning IxAtmSch assumes that the calling software ensures that + * calls to ixAtmSchVcQueueUpdate, ixAtmSchVcQueueClear and + * ixAtmSchTableUpdate are both self and mutually exclusive + * for the same port. + * + * @warning Subsequent calls to this function for the same port will + * overwrite the contents of previously supplied schedule + * tables. The client must be completely finished with the + * previously supplied schedule table before calling this + * function again for the same port. + * + * @sa ixAtmSchVcQueueUpdate(), ixAtmSchVcQueueClear(), ixAtmSchTableUpdate(). */ +PUBLIC IX_STATUS +ixAtmSchTableUpdate( IxAtmLogicalPort port, + unsigned int maxCells, + IxAtmScheduleTable **rettable); + +/** + * @ingroup IxAtmSch + * + * @fn ixAtmSchShow(void) + * + * @brief Utility function which will print statistics on the current + * and accumulated state of VCs and traffic in the ATM + * scheduler component. Output is sent to the default output + * device. + * + * @param none + * @return none + */ +PUBLIC void +ixAtmSchShow(void); + +/** + * @ingroup IxAtmSch + * + * @fn ixAtmSchStatsClear(void) + * + * @brief Utility function which will reset all counter statistics in + * the ATM scheduler to zero. + * + * @param none + * @return none + */ +PUBLIC void +ixAtmSchStatsClear(void); + +#endif +/* IXATMSCH_H */ + +/** @} */ diff --git a/drivers/net/npe/include/IxAtmTypes.h b/drivers/net/npe/include/IxAtmTypes.h new file mode 100644 index 0000000..8624c33 --- /dev/null +++ b/drivers/net/npe/include/IxAtmTypes.h @@ -0,0 +1,409 @@ +/** + * @file IxAtmTypes.h + * + * @date 24-MAR-2002 + * + * @brief This file contains Atm types common to a number of Atm components. + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/* ------------------------------------------------------ + Doxygen group definitions + ------------------------------------------------------ */ +/** + * @defgroup IxAtmTypes IXP400 ATM Types (IxAtmTypes) + * + * @brief The common set of types used in many Atm components + * + * @{ */ + +#ifndef IXATMTYPES_H +#define IXATMTYPES_H + +#include "IxNpeA.h" + +/** + * @enum IxAtmLogicalPort + * + * @brief Logical Port Definitions : + * + * Only 1 port is available in SPHY configuration + * 12 ports are enabled in MPHY configuration + * + */ +typedef enum +{ + IX_UTOPIA_PORT_0 = 0, /**< Port 0 */ +#ifdef IX_NPE_MPHYMULTIPORT + IX_UTOPIA_PORT_1, /**< Port 1 */ + IX_UTOPIA_PORT_2, /**< Port 2 */ + IX_UTOPIA_PORT_3, /**< Port 3 */ + IX_UTOPIA_PORT_4, /**< Port 4 */ + IX_UTOPIA_PORT_5, /**< Port 5 */ + IX_UTOPIA_PORT_6, /**< Port 6 */ + IX_UTOPIA_PORT_7, /**< Port 7 */ + IX_UTOPIA_PORT_8, /**< Port 8 */ + IX_UTOPIA_PORT_9, /**< Port 9 */ + IX_UTOPIA_PORT_10, /**< Port 10 */ + IX_UTOPIA_PORT_11, /**< Port 11 */ +#endif /* IX_NPE_MPHY */ + IX_UTOPIA_MAX_PORTS /**< Not a port - just a definition for the + * maximum possible ports + */ +} IxAtmLogicalPort; + +/** + * @def IX_ATM_CELL_PAYLOAD_SIZE + * @brief Size of a ATM cell payload + */ +#define IX_ATM_CELL_PAYLOAD_SIZE (48) + +/** + * @def IX_ATM_CELL_SIZE + * @brief Size of a ATM cell, including header + */ +#define IX_ATM_CELL_SIZE (53) + +/** + * @def IX_ATM_CELL_SIZE_NO_HEC + * @brief Size of a ATM cell, excluding HEC byte + */ +#define IX_ATM_CELL_SIZE_NO_HEC (IX_ATM_CELL_SIZE - 1) + +/** + * @def IX_ATM_OAM_CELL_SIZE_NO_HEC + * @brief Size of a OAM cell, excluding HEC byte + */ +#define IX_ATM_OAM_CELL_SIZE_NO_HEC IX_ATM_CELL_SIZE_NO_HEC + +/** + * @def IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE + * @brief Size of a AAL0 48 Cell payload + */ +#define IX_ATM_AAL0_48_CELL_PAYLOAD_SIZE IX_ATM_CELL_PAYLOAD_SIZE + +/** + * @def IX_ATM_AAL5_CELL_PAYLOAD_SIZE + * @brief Size of a AAL5 Cell payload + */ +#define IX_ATM_AAL5_CELL_PAYLOAD_SIZE IX_ATM_CELL_PAYLOAD_SIZE + +/** + * @def IX_ATM_AAL0_52_CELL_SIZE_NO_HEC + * @brief Size of a AAL0 52 Cell, excluding HEC byte + */ +#define IX_ATM_AAL0_52_CELL_SIZE_NO_HEC IX_ATM_CELL_SIZE_NO_HEC + + +/** + * @def IX_ATM_MAX_VPI + * @brief Maximum value of an ATM VPI + */ +#define IX_ATM_MAX_VPI 255 + +/** + * @def IX_ATM_MAX_VCI + * @brief Maximum value of an ATM VCI + */ +#define IX_ATM_MAX_VCI 65535 + + /** + * @def IX_ATM_MAX_NUM_AAL_VCS + * @brief Maximum number of active AAL5/AAL0 VCs in the system + */ +#define IX_ATM_MAX_NUM_AAL_VCS 32 + +/** + * @def IX_ATM_MAX_NUM_VC + * @brief Maximum number of active AAL5/AAL0 VCs in the system + * The use of this macro is depreciated, it is retained for + * backward compatiblity. For current software release + * and beyond the define IX_ATM_MAX_NUM_AAL_VC should be used. + */ +#define IX_ATM_MAX_NUM_VC IX_ATM_MAX_NUM_AAL_VCS + + + +/** + * @def IX_ATM_MAX_NUM_OAM_TX_VCS + * @brief Maximum number of active OAM Tx VCs in the system, + * 1 OAM VC per port + */ +#define IX_ATM_MAX_NUM_OAM_TX_VCS IX_UTOPIA_MAX_PORTS + +/** + * @def IX_ATM_MAX_NUM_OAM_RX_VCS + * @brief Maximum number of active OAM Rx VCs in the system, + * 1 OAM VC shared accross all ports + */ +#define IX_ATM_MAX_NUM_OAM_RX_VCS 1 + +/** + * @def IX_ATM_MAX_NUM_AAL_OAM_TX_VCS + * @brief Maximum number of active AAL5/AAL0/OAM Tx VCs in the system + */ +#define IX_ATM_MAX_NUM_AAL_OAM_TX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_TX_VCS) + +/** + * @def IX_ATM_MAX_NUM_AAL_OAM_RX_VCS + * @brief Maximum number of active AAL5/AAL0/OAM Rx VCs in the system + */ +#define IX_ATM_MAX_NUM_AAL_OAM_RX_VCS (IX_ATM_MAX_NUM_AAL_VCS + IX_ATM_MAX_NUM_OAM_RX_VCS) + +/** + * @def IX_ATM_IDLE_CELLS_CONNID + * @brief VC Id used to indicate idle cells in the returned schedule table. + */ +#define IX_ATM_IDLE_CELLS_CONNID 0 + + +/** + * @def IX_ATM_CELL_HEADER_VCI_GET + * @brief get the VCI field from a cell header + */ +#define IX_ATM_CELL_HEADER_VCI_GET(cellHeader) \ + (((cellHeader) >> 4) & IX_OAM_VCI_BITS_MASK); + +/** + * @def IX_ATM_CELL_HEADER_VPI_GET + * @brief get the VPI field from a cell header + */ +#define IX_ATM_CELL_HEADER_VPI_GET(cellHeader) \ + (((cellHeader) >> 20) & IX_OAM_VPI_BITS_MASK); + +/** + * @def IX_ATM_CELL_HEADER_PTI_GET + * @brief get the PTI field from a cell header + */ +#define IX_ATM_CELL_HEADER_PTI_GET(cellHeader) \ + ((cellHeader) >> 1) & IX_OAM_PTI_BITS_MASK; + +/** + * @typedef IxAtmCellHeader + * + * @brief ATM Cell Header, does not contain 4 byte HEC, added by NPE-A + */ +typedef unsigned int IxAtmCellHeader; + + +/** + * @enum IxAtmServiceCategory + * + * @brief Enumerated type representing available ATM service categories. + * For more informatoin on these categories, see "Traffic Management + * Specification" v4.1, published by the ATM Forum - + * http://www.atmforum.com + */ +typedef enum +{ + IX_ATM_CBR, /**< Constant Bit Rate */ + IX_ATM_RTVBR, /**< Real Time Variable Bit Rate */ + IX_ATM_VBR, /**< Variable Bit Rate */ + IX_ATM_UBR, /**< Unspecified Bit Rate */ + IX_ATM_ABR /**< Available Bit Rate (not supported) */ + +} IxAtmServiceCategory; + +/** + * + * @enum IxAtmRxQueueId + * + * @brief Rx Queue Type for RX traffic + * + * IxAtmRxQueueId defines the queues involved for receiving data. + * + * There are two queues to facilitate prioritisation handling + * and processing the 2 queues with different algorithms and + * constraints + * + * e.g. : one queue can carry voice (or time-critical traffic), the + * other queue can carry non-voice traffic + * + */ +typedef enum +{ + IX_ATM_RX_A = 0, /**< RX queue A */ + IX_ATM_RX_B, /**< RX queue B */ + IX_ATM_MAX_RX_STREAMS /**< Maximum number of RX streams */ +} IxAtmRxQueueId; + +/** + * @brief Structure describing an ATM traffic contract for a Virtual + * Connection (VC). + * + * Structure is used to specify the requested traffic contract for a + * VC to the IxAtmSch component using the @ref ixAtmSchVcModelSetup + * interface. + * + * These parameters are defined by the ATM forum working group + * (http://www.atmforum.com). + * + * @note Typical values for a voice channel 64 Kbit/s + * - atmService @a IX_ATM_RTVBR + * - pcr 400 (include IP overhead, and AAL5 trailer) + * - cdvt 5000000 (5 ms) + * - scr = pcr + * + * @note Typical values for a data channel 800 Kbit/s + * - atmService @a IX_ATM_UBR + * - pcr 1962 (include IP overhead, and AAL5 trailer) + * - cdvt 5000000 (5 ms) + * + */ +typedef struct +{ + IxAtmServiceCategory atmService; /**< ATM service category */ + unsigned pcr; /**< Peak Cell Rate - cells per second */ + unsigned cdvt; /**< Cell Delay Variation Tolerance - in nanoseconds */ + unsigned scr; /**< Sustained Cell Rate - cells per second */ + unsigned mbs; /**< Max Burst Size - cells */ + unsigned mcr; /**< Minimum Cell Rate - cells per second */ + unsigned mfs; /**< Max Frame Size - cells */ +} IxAtmTrafficDescriptor; + +/** + * @typedef IxAtmConnId + * + * @brief ATM VC data connection identifier. + * + * This is is generated by IxAtmdAcc when a successful connection is + * made on a VC. The is the ID by which IxAtmdAcc knows an active + * VC and should be used in IxAtmdAcc API calls to reference a + * specific VC. + */ +typedef unsigned int IxAtmConnId; + +/** + * @typedef IxAtmSchedulerVcId + * + * @brief ATM VC scheduling connection identifier. + * + * This id is generated and used by ATM Tx controller, generally + * the traffic shaper (e.g. IxAtmSch). The IxAtmdAcc component + * will request one of these Ids whenever a data connection on + * a Tx VC is requested. This ID will be used in callbacks to + * the ATM Transmission Ctrl s/w (e.g. IxAtmm) to reference a + * particular VC. + */ +typedef int IxAtmSchedulerVcId; + +/** + * @typedef IxAtmNpeRxVcId + * + * @brief ATM Rx VC identifier used by the ATM Npe. + * + * This Id is generated by IxAtmdAcc when a successful data connection + * is made on a rx VC. + */ +typedef unsigned int IxAtmNpeRxVcId; + +/** + * @brief ATM Schedule Table entry + * + * This IxAtmScheduleTableEntry is used by an ATM scheduler to inform + * IxAtmdAcc about the data to transmit (in term of cells per VC) + * + * This structure defines + * @li the number of cells to be transmitted (numberOfCells) + * @li the VC connection to be used for transmission (connId). + * + * @note - When the connection Id value is IX_ATM_IDLE_CELLS_CONNID, the + * corresponding number of idle cells will be transmitted to the hardware. + * + */ +typedef struct +{ + IxAtmConnId connId; /**< connection Id + * + * Identifier of VC from which cells are to be transmitted. + * When this valus is IX_ATM_IDLE_CELLS_CONNID, this indicates + * that the system should transmit the specified number + * of idle cells. Unknown connIds result in the transmission + * idle cells. + */ + unsigned int numberOfCells; /**< number of cells to transmit + * + * The number of contiguous cells to schedule from this VC + * at this point. The valid range is from 1 to + * @a IX_ATM_SCHEDULETABLE_MAXCELLS_PER_ENTRY. This + * number can swap over mbufs and pdus. OverSchduling results + * in the transmission of idle cells. + */ +} IxAtmScheduleTableEntry; + +/** + * @brief This structure defines a schedule table which gives details + * on which data (from which VCs) should be transmitted for a + * forthcoming period of time for a particular port and the + * order in which that data should be transmitted. + * + * The schedule table consists of a series of entries each of which + * will schedule one or more cells from a particular registered VC. + * The total number of cells scheduled and the total number of + * entries in the table are also indicated. + * + */ +typedef struct +{ + unsigned tableSize; /**< Number of entries + * + * Indicates the total number of + * entries in the table. + */ + unsigned totalCellSlots; /**< Number of cells + * + * Indicates the total number of ATM + * cells which are scheduled by all the + * entries in the table. + */ + IxAtmScheduleTableEntry *table; /**< Pointer to schedule entries + * + * Pointer to an array + * containing tableSize entries + */ +} IxAtmScheduleTable; + +#endif /* IXATMTYPES_H */ + +/** + * @} defgroup IxAtmTypes + */ + + diff --git a/drivers/net/npe/include/IxAtmdAcc.h b/drivers/net/npe/include/IxAtmdAcc.h new file mode 100644 index 0000000..ae7b243 --- /dev/null +++ b/drivers/net/npe/include/IxAtmdAcc.h @@ -0,0 +1,1194 @@ + +/** + * @file IxAtmdAcc.h + * + * @date 07-Nov-2001 + * + * @brief IxAtmdAcc Public API + * + * This file contains the public API of IxAtmdAcc, related to the + * data functions of the component + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/* ------------------------------------------------------ + Doxygen group definitions + ------------------------------------------------------ */ + +/** + * + * @defgroup IxAtmdAccAPI IXP400 ATM Driver Access (IxAtmdAcc) API + * + * @brief The public API for the IXP400 Atm Driver Data component + * + * IxAtmdAcc is the low level interface by which AAL0/AAL5 and + * OAM data gets transmitted to,and received from the Utopia bus. + * + * For AAL0/AAL5 services transmit and receive connections may + * be established independantly for unique combinations of + * port,VPI,and VCI. + * + * Two AAL0 services supporting 48 or 52 byte cell data are provided. + * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52). + * AAL0_52 is a raw cell service the client must format + * the PDU with an ATM cell header (excluding HEC) at the start of + * each cell, note that AtmdAcc does not validate the cell headers in + * a submitted PDU. + * + * OAM cells cannot be received over the AAL0 service but instead + * are received over a dedicated OAM service. + * + * For the OAM service an "OAM Tx channel" may be enabled for a port + * by establishing a single dedicated OAM Tx connection on that port. + * A single "OAM Rx channel" for all ports may be enabled by + * establishing a dedicated OAM Rx connection. + * + * The OAM service allows buffers containing 52 byte OAM F4/F5 cells + * to be transmitted and received over the dedicated OAM channels. + * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM + * service offered by AtmdAcc is a raw cell transport service. + * It is assumed that ITU I.610 procedures that make use of this + * service are implemented above AtmdAcc. + * + * Note that the dedicated OAM connections are established on + * reserved VPI,VCI, and (in the case of Rx) port values defined below. + * These values are used purely to descriminate the dedicated OAM channels + * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be + * realised for particluar VPI/VCIs by manipulating the VPI,VCI + * fields of the ATM cell headers of cells in the buffers passed + * to AtmdAcc. Note that AtmdAcc does not validate the cell headers + * in a submitted OAM PDU. + * + * + * + * This part is related to the User datapath processing + * + * @{ + */ + +#ifndef IXATMDACC_H +#define IXATMDACC_H + +#include "IxAtmTypes.h" + +/* ------------------------------------------------------ + AtmdAcc Data Types definition + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_WARNING + * + * @brief Warning return code + * + * This constant is used to tell IxAtmDAcc user about a special case. + * + */ +#define IX_ATMDACC_WARNING 2 + +/** + * + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_BUSY + * + * @brief Busy return code + * + * This constant is used to tell IxAtmDAcc user that the request + * is correct, but cannot be processed because the IxAtmAcc resources + * are already used. The user has to retry its request later + * + */ +#define IX_ATMDACC_BUSY 3 + +/** + * + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_RESOURCES_STILL_ALLOCATED + * + * @brief Disconnect return code + * + * This constant is used to tell IxAtmDAcc user that the disconnect + * functions are not complete because the resources used by the driver + * are not yet released. The user has to retry the disconnect call + * later. + * + */ +#define IX_ATMDACC_RESOURCES_STILL_ALLOCATED 4 + +/** + * + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_DEFAULT_REPLENISH_COUNT + * + * @brief Default resources usage for RxVcFree replenish mechanism + * + * This constant is used to tell IxAtmDAcc to allocate and use + * the minimum of resources for rx free replenish. + * + * @sa ixAtmdAccRxVcConnect + */ +#define IX_ATMDACC_DEFAULT_REPLENISH_COUNT 0 + + +/** + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_OAM_TX_VPI + * + * @brief The reserved value used for the dedicated OAM + * Tx connection. This "well known" value is used by atmdAcc and + * its clients to dsicriminate the OAM channel, and should be chosen so + * that it does not coencide with the VPI value used in an AAL0/AAL5 connection. + * Any attempt to connect a service type other than OAM on this VPI will fail. + * + * + */ +#define IX_ATMDACC_OAM_TX_VPI 0 + +/** + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_OAM_TX_VCI + * + * @brief The reserved value used for the dedicated OAM + * Tx connection. This "well known" value is used by atmdAcc and + * its clients to dsicriminate the OAM channel, and should be chosen so + * that it does not coencide with the VCI value used in an AAL0/AAL5 connection. + * Any attempt to connect a service type other than OAM on this VCI will fail. + */ +#define IX_ATMDACC_OAM_TX_VCI 0 + + + /** + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_OAM_RX_PORT + * + * @brief The reserved dummy PORT used for all dedicated OAM + * Rx connections. Note that this is not a real port but must + * have a value that lies within the valid range of port values. + */ +#define IX_ATMDACC_OAM_RX_PORT IX_UTOPIA_PORT_0 + + /** + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_OAM_RX_VPI + * + * @brief The reserved value value used for the dedicated OAM + * Rx connection. This value should be chosen so that it does not + * coencide with the VPI value used in an AAL0/AAL5 connection. + * Any attempt to connect a service type other than OAM on this VPI will fail. + */ +#define IX_ATMDACC_OAM_RX_VPI 0 + +/** + * @ingroup IxAtmdAccAPI + * + * @def IX_ATMDACC_OAM_RX_VCI + * + * @brief The reserved value value used for the dedicated OAM + * Rx connection. This value should be chosen so that it does not + * coencide with the VCI value used in an AAL0/AAL5 connection. + * Any attempt to connect a service type other than OAM on this VCI will fail. + */ +#define IX_ATMDACC_OAM_RX_VCI 0 + + +/** + * @enum IxAtmdAccPduStatus + * + * @ingroup IxAtmdAccAPI + * + * @brief IxAtmdAcc Pdu status : + * + * IxAtmdAccPduStatus is used during a RX operation to indicate + * the status of the received PDU + * + */ + +typedef enum +{ + IX_ATMDACC_AAL0_VALID = 0, /**< aal0 pdu */ + IX_ATMDACC_OAM_VALID, /**< OAM pdu */ + IX_ATMDACC_AAL2_VALID, /**< aal2 pdu @b reserved for future use */ + IX_ATMDACC_AAL5_VALID, /**< aal5 pdu complete and trailer is valid */ + IX_ATMDACC_AAL5_PARTIAL, /**< aal5 pdu not complete, trailer is missing */ + IX_ATMDACC_AAL5_CRC_ERROR, /**< aal5 pdu not complete, crc error/length error */ + IX_ATMDACC_MBUF_RETURN /**< empty buffer returned to the user */ +} IxAtmdAccPduStatus; + + +/** + * + * @enum IxAtmdAccAalType + * + * @ingroup IxAtmdAccAPI + * + * @brief IxAtmdAcc AAL Service Type : + * + * IxAtmdAccAalType defines the type of traffic to run on this VC + * + */ +typedef enum +{ + IX_ATMDACC_AAL5, /**< ITU-T AAL5 */ + IX_ATMDACC_AAL2, /**< ITU-T AAL2 @b reserved for future use */ + IX_ATMDACC_AAL0_48, /**< AAL0 48 byte payloads (cell header is added by NPE)*/ + IX_ATMDACC_AAL0_52, /**< AAL0 52 byte cell data (HEC is added by NPE) */ + IX_ATMDACC_OAM, /**< OAM cell transport service (HEC is added by NPE)*/ + IX_ATMDACC_MAX_SERVICE_TYPE /**< not a service, used for parameter validation */ +} IxAtmdAccAalType; + +/** + * + * @enum IxAtmdAccClpStatus + * + * @ingroup IxAtmdAccAPI + * + * @brief IxAtmdAcc CLP indication + * + * IxAtmdAccClpStatus defines the CLP status of the current PDU + * + */ +typedef enum +{ + IX_ATMDACC_CLP_NOT_SET = 0, /**< CLP indication is not set */ + IX_ATMDACC_CLP_SET = 1 /**< CLP indication is set */ +} IxAtmdAccClpStatus; + +/** + * @typedef IxAtmdAccUserId + * + * @ingroup IxAtmdAccAPI + * + * @brief User-supplied Id + * + * IxAtmdAccUserId is passed through callbacks and allows the + * IxAtmdAcc user to identify the source of a call back. The range of + * this user-owned Id is [0...2^32-1)]. + * + * The user provides this own Ids on a per-channel basis as a parameter + * in a call to @a ixAtmdAccRxVcConnect() or @a ixAtmdAccRxVcConnect() + * + * @sa ixAtmdAccRxVcConnect + * @sa ixAtmdAccTxVcConnect + * + */ +typedef unsigned int IxAtmdAccUserId; + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to RX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @brief Rx callback prototype + * + * IxAtmdAccRxVcRxCallback is the prototype of the Rx callback user + * function called once per PDU to pass a receive Pdu to a user on a + * partilcular connection. The callback is likely to push the mbufs + * to a protocol layer, and recycle the mbufs for a further use. + * + * @note -This function is called ONLY in the context of + * the @a ixAtmdAccRxDispatch() function + * + * @sa ixAtmdAccRxDispatch + * @sa ixAtmdAccRxVcConnect + * + * @param port @ref IxAtmLogicalPort [in] - the port on which this PDU was received + * a logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call + * to @a ixAtmdAccRxVcConnect() + * @param status @ref IxAtmdAccPduStatus [in] - an indication about the PDU validity. + * In the case of AAL0 the only possibile value is + * AAL0_VALID, in this case the client may optionally determine + * that an rx timeout occured by checking if the mbuf is + * compleletly or only partially filled, the later case + * indicating a timeout. + * In the case of OAM the only possible value is OAM valid. + * The status is set to @a IX_ATMDACC_MBUF_RETURN when + * the mbuf is released during a disconnect process. + * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU. + * For AAL5/AAL0_48 this information + * is set if the clp bit of any rx cell is set + * For AAL0-52/OAM the client may inspect the CLP in individual + * cell headers in the PDU, and this parameter is set to 0. + * @param *mbufPtr @ref IX_OSAL_MBUF [in] - depending on the servive type a pointer to + * an mbuf (AAL5/AAL0/OAM) or mbuf chain (AAL5 only), + * that comprises the complete PDU data. + * + * This parameter is guaranteed not to be a null pointer. + * + */ +typedef void (*IxAtmdAccRxVcRxCallback) (IxAtmLogicalPort port, + IxAtmdAccUserId userId, + IxAtmdAccPduStatus status, + IxAtmdAccClpStatus clp, + IX_OSAL_MBUF * mbufPtr); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @brief Callback prototype for free buffer level is low. + * + * IxAtmdAccRxVcFreeLowCallback is the prototype of the user function + * which get called on a per-VC basis, when more mbufs are needed to + * continue the ATM data reception. This function is likely to supply + * more available mbufs by one or many calls to the replenish function + * @a ixAtmdAccRxVcFreeReplenish() + * + * This function is called when the number of available buffers for + * reception is going under the threshold level as defined + * in @a ixAtmdAccRxVcFreeLowCallbackRegister() + * + * This function is called inside an Qmgr dispatch context. No system + * resource or interrupt-unsafe feature should be used inside this + * callback. + * + * @sa ixAtmdAccRxVcFreeLowCallbackRegister + * @sa IxAtmdAccRxVcFreeLowCallback + * @sa ixAtmdAccRxVcFreeReplenish + * @sa ixAtmdAccRxVcFreeEntriesQuery + * @sa ixAtmdAccRxVcConnect + * + * @param userId @ref IxAtmdAccUserId [in] - user Id provided in the call + * to @a ixAtmdAccRxVcConnect() + * + * @return None + * + */ +typedef void (*IxAtmdAccRxVcFreeLowCallback) (IxAtmdAccUserId userId); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to TX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @brief Buffer callback prototype. + * + * This function is called to relinguish ownership of a transmitted + * buffer chain to the user. + * + * @note -In the case of a chained mbuf the AmtdAcc component can + * chain many user buffers together and pass ownership to the user in + * one function call. + * + * @param userId @ref IxAtmdAccUserId [in] - user If provided at registration of this + * callback. + * @param mbufPtr @ref IX_OSAL_MBUF [in] - a pointer to mbufs or chain of mbufs and is + * guaranteed not to be a null pointer. + * + */ +typedef void (*IxAtmdAccTxVcBufferReturnCallback) (IxAtmdAccUserId userId, + IX_OSAL_MBUF * mbufPtr); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to Initialisation + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccInit (void) + * + * @brief Initialise the IxAtmdAcc Component + * + * This function initialise the IxAtmdAcc component. This function shall + * be called before any other function of the API. Its role is to + * initialise all internal resources of the IxAtmdAcc component. + * + * The ixQmgr component needs to be initialized prior the use of + * @a ixAtmdAccInit() + * + * @param none + * + * Failing to initilialize the IxAtmdAcc API before any use of it will + * result in a failed status. + * If the specified component is not present, a success status will still be + * returned, however, a warning indicating the NPE to download to is not + * present will be issued. + * + * @return @li IX_SUCCESS initialisation is complete (in case of component not + * being present, a warning is clearly indicated) + * @return @li IX_FAIL unable to process this request either + * because this IxAtmdAcc is already initialised + * or some unspecified error has occrred. + */ +PUBLIC IX_STATUS ixAtmdAccInit (void); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccShow (void) + * + * @brief Show IxAtmdAcc configuration on a per port basis + * + * @param none + * + * @return none + * + * @note - Display use printf() and are redirected to stdout + */ +PUBLIC void +ixAtmdAccShow (void); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccStatsShow (void) + * + * @brief Show all IxAtmdAcc stats + * + * @param none + * + * @return none + * + * @note - Stats display use printf() and are redirected to stdout + */ +PUBLIC void +ixAtmdAccStatsShow (void); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccStatsReset (void) + * + * @brief Reset all IxAtmdAcc stats + * + * @param none + * + * @return none + * + */ +PUBLIC void +ixAtmdAccStatsReset (void); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to RX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcConnect (IxAtmLogicalPort port, + unsigned int vpi, + unsigned int vci, + IxAtmdAccAalType aalServiceType, + IxAtmRxQueueId rxQueueId, + IxAtmdAccUserId userCallbackId, + IxAtmdAccRxVcRxCallback rxCallback, + unsigned int minimumReplenishCount, + IxAtmConnId * connIdPtr, + IxAtmNpeRxVcId * npeVcIdPtr ) + * + * @brief Connect to a Aal Pdu receive service for a particular + * port/vpi/vci, and service type. + * + * This function allows a user to connect to an Aal5/Aal0/OAM Pdu receive service + * for a particular port/vpi/vci. It registers the callback and allocates + * internal resources and a Connection Id to be used in further API calls + * related to this VCC. + * + * The function will setup VC receive service on the specified rx queue. + * + * This function is blocking and makes use internal locks, and hence + * should not be called from an interrupt context. + * + * On return from @a ixAtmdAccRxVcConnect() with a failure status, the + * connection Id parameter is unspecified. Its value cannot be used. + * A connId is the reference by which IxAtmdAcc refers to a + * connected VC. This identifier is the result of a succesful call + * to a connect function. This identifier is invalid after a + * sucessful call to a disconnect function. + * + * Calling this function for the same combination of Vpi, Vci and more + * than once without calling @a ixAtmdAccRxVcTryDisconnect() will result in a + * failure status. + * + * If this function returns success the user should supply receive + * buffers by calling @a ixAtmdAccRxVcFreeReplenish() and then call + * @a ixAtmdAccRxVcEnable() to begin receiving pdus. + * + * There is a choice of two receive Qs on which the VC pdus could be + * receive. The user must associate the VC with one of these. Essentially + * having two qs allows more flexible system configuration such as have + * high prioriy traffic on one q (e.g. voice) and low priority traffic on + * the other (e.g. data). The high priority Q could be serviced in + * preference to the low priority Q. One queue may be configured to be + * serviced as soon as there is traffic, the other queue may be configured + * to be serviced by a polling mechanism running at idle time. + * + * Two AAL0 services supporting 48 or 52 byte cell data are provided. + * Received AAL0 PDUs will be be a multiple of the cell data size (48/52). + * AAL0_52 is a raw cell service and includes an ATM cell header + * (excluding HEC) at the start of each cell. + * + * A single "OAM Rx channel" for all ports may be enabled by + * establishing a dedicated OAM Rx connection. + * + * The OAM service allows buffers containing 52 byte OAM F4/F5 cells + * to be transmitted and received over the dedicated OAM channels. + * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM + * service offered by AtmdAcc is a raw cell transport service. + * It is assumed that ITU I.610 procedures that make use of this + * service are implemented above AtmdAcc. + * + * Note that the dedicated OAM connections are established on + * reserved VPI,VCI, and (in the case of Rx) port values. + * These values are used purely to descriminate the dedicated OAM channels + * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be + * realised for particluar VPI/VCIs by manipulating the VPI,VCI + * fields of the ATM cell headers of cells in the buffers passed + * to AtmdAcc. + * + * Calling this function prior to enable the port will fail. + * + * @sa ixAtmdAccRxDispatch + * @sa ixAtmdAccRxVcEnable + * @sa ixAtmdAccRxVcDisable + * @sa ixAtmdAccRxVcTryDisconnect + * @sa ixAtmdAccPortEnable + * + * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port + * [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param vpi unsigned int [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI + * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI + * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service: AAL5, AAL0_48, AAL0_52, or OAM + * @param rxQueueId @ref IxAtmRxQueueId [in] - this identifieds which of two Qs the VC + * should use.when icoming traffic is processed + * @param userCallbackId @ref IxAtmdAccUserId [in] - user Id used later as a parameter to + * the supplied rxCallback. + * @param rxCallback [in] @ref IxAtmdAccRxVxRxCallback - function called when mbufs are received. + * This parameter cannot be a null pointer. + * @param bufferFreeCallback [in] - function to be called to return + * ownership of buffers to IxAtmdAcc user. + * @param minimumReplenishCount unsigned int [in] - For AAL5/AAL0 the number of free mbufs + * to be used with this channel. Use a high number when the expected traffic + * rate on this channel is high, or when the user's mbufs are small, or when + * the RxVcFreeLow Notification has to be invoked less often. When this + * value is IX_ATMDACC_DEFAULT_REPLENISH_COUNT, the minimum of + * resources will be used. Depending on traffic rate, pdu + * size and mbuf size, rxfree queue size, polling/interrupt rate, this value may + * require to be replaced by a different value in the range 1-128 + * For OAM the rxFree queue size is fixed by atmdAcc and this parameter is ignored. + * @param connIdPtr @ref IxAtmConnId [out] - pointer to a connection Id + * This parameter cannot be a null pointer. + * @param npeVcIdPtr @ref IxAtmNpeRxVcId [out] - pointer to an npe Vc Id + * This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS successful call to IxAtmdAccRxVcConnect + * @return @li IX_ATMDACC_BUSY cannot process this request : + * no VC is available + * @return @li IX_FAIL + * parameter error, + * VC already in use, + * attempt to connect AAL service on reserved OAM VPI/VCI, + * attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI, + * port is not initialised, + * or some other error occurs during processing. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcConnect (IxAtmLogicalPort port, + unsigned int vpi, + unsigned int vci, + IxAtmdAccAalType aalServiceType, + IxAtmRxQueueId rxQueueId, + IxAtmdAccUserId userCallbackId, + IxAtmdAccRxVcRxCallback rxCallback, + unsigned int minimumReplenishCount, + IxAtmConnId * connIdPtr, + IxAtmNpeRxVcId * npeVcIdPtr ); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId, + IX_OSAL_MBUF * mbufPtr) + * + * @brief Provide free mbufs for data reception on a connection. + * + * This function provides mbufs for data reception by the hardware. This + * function needs to be called by the user on a regular basis to ensure + * no packet loss. Providing free buffers is a connection-based feature; + * each connection can have different requirements in terms of buffer size + * number of buffers, recycling rate. This function could be invoked from + * within the context of a @a IxAtmdAccRxVcFreeLowCallback() callback + * for a particular VC + * + * Mbufs provided through this function call can be chained. They will be + * unchained internally. A call to this function with chained mbufs or + * multiple calls with unchained mbufs are equivalent, but calls with + * unchained mbufs are more efficients. + * + * Mbufs provided to this interface need to be able to hold at least one + * full cell payload (48/52 bytes, depending on service type). + * Chained buffers with a size less than the size supported by the hardware + * will be returned through the rx callback provided during the connect step. + * + * Failing to invoke this function prior to enabling the RX traffic + * can result in packet loss. + * + * This function is not reentrant for the same connId. + * + * This function does not use system resources and can be + * invoked from an interrupt context. + * + * @note - Over replenish is detected, and extra mbufs are returned through + * the rx callback provided during the connect step. + * + * @note - Mbuf provided to the replenish function should have a length greater or + * equal to 48/52 bytes according to service type. + * + * @note - The memory cache of mMbuf payload should be invalidated prior to Mbuf + * submission. Flushing the Mbuf headers is handled by IxAtmdAcc. + * + * @note - When a chained mbuf is provided, this function process the mbufs + * up to the hardware limit and invokes the user-supplied callback + * to release extra buffers. + * + * @sa ixAtmdAccRxVcFreeLowCallbackRegister + * @sa IxAtmdAccRxVcFreeLowCallback + * @sa ixAtmdAccRxVcConnect + * + * @param connId @ref IxAtmConnId [in] - connection Id as returned from a succesfull call to + * @a IxAtmdAccRxVcConnect() + * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a mbuf structure to be used for data + * reception. The mbuf pointed to by this parameter can be chained + * to an other mbuf. + * + * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcFreeReplenish() + * and the mbuf is now ready to use for incoming traffic. + * @return @li IX_ATMDACC_BUSY cannot process this request because + * the max number of outstanding free buffers has been reached + * or the internal resources have exhausted for this VC. + * The user is responsible for retrying this request later. + * @return @li IX_FAIL cannot process this request because of parameter + * errors or some unspecified internal error has occurred. + * + * @note - It is not always guaranteed the replenish step to be as fast as the + * hardware is consuming Rx Free mbufs. There is nothing in IxAtmdAcc to + * guarantee that replenish reaches the rxFree threshold level. If the + * threshold level is not reached, the next rxFree low notification for + * this channel will not be triggered. + * The preferred ways to replenish can be as follows (depending on + * applications and implementations) : + * @li Replenish in a rxFree low notification until the function + * ixAtmdAccRxVcFreeReplenish() returns IX_ATMDACC_BUSY + * @li Query the queue level using @sa ixAtmdAccRxVcFreeEntriesQuery, then + * , replenish using @a ixAtmdAccRxVcFreeReplenish(), then query the queue + * level again, and replenish if the threshold is still not reached. + * @li Trigger replenish from an other event source and use rxFree starvation + * to throttle the Rx traffic. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcFreeReplenish (IxAtmConnId connId, + IX_OSAL_MBUF * mbufPtr); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId, + unsigned int numberOfMbufs, + IxAtmdAccRxVcFreeLowCallback callback) + * + * @brief Configure the RX Free threshold value and register a callback + * to handle threshold notifications. + * + * The function ixAtmdAccRxVcFreeLowCallbackRegister sets the threshold value for + * a particular RX VC. When the number of buffers reaches this threshold + * the callback is invoked. + * + * This function should be called once per VC before RX traffic is + * enabled.This function will fail if the curent level of the free buffers + * is equal or less than the threshold value. + * + * @sa ixAtmdAccRxVcFreeLowCallbackRegister + * @sa IxAtmdAccRxVcFreeLowCallback + * @sa ixAtmdAccRxVcFreeReplenish + * @sa ixAtmdAccRxVcFreeEntriesQuery + * @sa ixAtmdAccRxVcConnect + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call + * to @a IxAtmdAccRxVcConnect() + * @param numberOfMbufs unsigned int [in] - threshold number of buffers. This number + * has to be a power of 2, one of the values 0,1,2,4,8,16,32.... + * The maximum value cannot be more than half of the rxFree queue + * size (which can be retrieved using @a ixAtmdAccRxVcFreeEntriesQuery() + * before any use of the @a ixAtmdAccRxVcFreeReplenish() function) + * @param callback @ref IxAtmdAccRxVcFreeLowCallback [in] - function telling the user that the number of + * free buffers has reduced to the threshold value. + * + * @return @li IX_SUCCESS Threshold set successfully. + * @return @li IX_FAIL parameter error or the current number of free buffers + * is less than or equal to the threshold supplied or some + * unspecified error has occrred. + * + * @note - the callback will be called when the threshold level will drop from + * exactly (numberOfMbufs + 1) to (numberOfMbufs). + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcFreeLowCallbackRegister (IxAtmConnId connId, + unsigned int numberOfMbufs, + IxAtmdAccRxVcFreeLowCallback callback); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId, + unsigned int *numberOfMbufsPtr) + * + * @brief Get the number of rx mbufs the system can accept to replenish the + * the rx reception mechanism on a particular channel + * + * The ixAtmdAccRxVcFreeEntriesQuery function is used to retrieve the current + * number of available mbuf entries for reception, on a per-VC basis. This + * function can be used to know the number of mbufs which can be provided + * using @a ixAtmdAccRxVcFreeReplenish(). + * + * This function can be used from a timer context, or can be associated + * with a threshold event, or can be used inside an active polling + * mechanism which is under user control. + * + * This function is reentrant and does not use system resources and can + * be invoked from an interrupt context. + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call + * to @a IxAtmdAccRxVcConnect() + * @param numberOfMbufsPtr unsigned int [out] - Pointer to the number of available entries. + * . This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS the current number of mbufs not yet used for incoming traffic + * @return @li IX_FAIL invalid parameter + * + * @sa ixAtmdAccRxVcFreeReplenish + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcFreeEntriesQuery (IxAtmConnId connId, + unsigned int *numberOfMbufsPtr); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcEnable (IxAtmConnId connId) + * + * @brief Start the RX service on a VC. + * + * This functions kicks-off the traffic reception for a particular VC. + * Once invoked, incoming PDUs will be made available by the hardware + * and are eventually directed to the @a IxAtmdAccRxVcRxCallback() callback + * registered for the connection. + * + * If the traffic is already running, this function returns IX_SUCCESS. + * This function can be invoked many times. + * + * IxAtmdAccRxVcFreeLowCallback event will occur only after + * @a ixAtmdAccRxVcEnable() function is invoked. + * + * Before using this function, the @a ixAtmdAccRxVcFreeReplenish() function + * has to be used to replenish the RX Free queue. If not, incoming traffic + * may be discarded.and in the case of interrupt driven reception the + * @a IxAtmdAccRxVcFreeLowCallback() callback may be invoked as a side effect + * during a replenish action. + * + * This function is not reentrant and should not be used inside an + * interrupt context. + * + * For an VC connection this function can be called after a call to + * @a ixAtmdAccRxVcDisable() and should not be called after + * @a ixAtmdAccRxVcTryDisconnect() + * + * @sa ixAtmdAccRxVcDisable + * @sa ixAtmdAccRxVcConnect + * @sa ixAtmdAccRxVcFreeReplenish + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call + * to @a IxAtmdAccRxVcConnect() + * + * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcEnable + * @return @li IX_ATMDACC_WARNING the channel is already enabled + * @return @li IX_FAIL invalid parameters or some unspecified internal + * error occured. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcEnable (IxAtmConnId connId); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcDisable (IxAtmConnId connId) + * + * @brief Stop the RX service on a VC. + * + * This functions stops the traffic reception for a particular VC connection. + * + * Once invoked, incoming Pdus are discarded by the hardware. Any Pdus + * pending will be freed to the user + * + * Hence once this function returns no more receive callbacks will be + * called for that VC. However, buffer free callbacks will be invoked + * until such time as all buffers supplied by the user have been freed + * back to the user + * + * Calling this function doe not invalidate the connId. + * @a ixAtmdAccRxVcEnable() can be invoked to enable Pdu reception again. + * + * If the traffic is already stopped, this function returns IX_SUCCESS. + * + * This function is not reentrant and should not be used inside an + * interrupt context. + * + * @sa ixAtmdAccRxVcConnect + * @sa ixAtmdAccRxVcEnable + * @sa ixAtmdAccRxVcDisable + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to @a + * IxAtmdAccRxVcConnect() + * + * @return @li IX_SUCCESS successful call to @a ixAtmdAccRxVcDisable(). + * @return @li IX_ATMDACC_WARNING the channel is already disabled + * @return @li IX_FAIL invalid parameters or some unspecified internal error occured + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcDisable (IxAtmConnId connId); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId) + * + * @brief Disconnect a VC from the RX service. + * + * This function deregisters the VC and guarantees that all resources + * associated with this VC are free. After its execution, the connection + * Id is not available. + * + * This function will fail until such time as all resources allocated to + * the VC connection have been freed. The user is responsible to delay and + * call again this function many times until a success status is returned. + * + * This function needs internal locks and should not be called from an + * interrupt context + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to + * @a IxAtmdAccRxVcConnect() + * + * @return @li IX_SUCCESS successful call to ixAtmdAccRxVcDisable + * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources + * associated with the connection have been freed. + * @return @li IX_FAIL cannot process this request because of a parameter + * error + * + */ +PUBLIC IX_STATUS ixAtmdAccRxVcTryDisconnect (IxAtmConnId connId); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to TX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccTxVcConnect (IxAtmLogicalPort port, + unsigned int vpi, + unsigned int vci, + IxAtmdAccAalType aalServiceType, + IxAtmdAccUserId userId, + IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback, + IxAtmConnId * connIdPtr) + * + * @brief Connect to a Aal Pdu transmit service for a particular + * port/vpi/vci and service type. + * + * This function allows a user to connect to an Aal5/Aal0/OAM Pdu transmit service + * for a particular port/vpi/vci. It registers the callback and allocates + * internal resources and a Connection Id to be used in further API calls + * related to this VC. + * + * The function will setup VC transmit service on the specified on the + * specified port. A connId is the reference by which IxAtmdAcc refers to a + * connected VC. This identifier is the result of a succesful call + * to a connect function. This identifier is invalid after a + * sucessful call to a disconnect function. + * + * This function needs internal locks, and hence should not be called + * from an interrupt context. + * + * On return from @a ixAtmdAccTxVcConnect() with a failure status, the + * connection Id parameter is unspecified. Its value cannot be used. + * + * Calling this function for the same combination of port, Vpi, Vci and + * more than once without calling @a ixAtmdAccTxVcTryDisconnect() will result + * in a failure status. + * + * Two AAL0 services supporting 48 or 52 byte cell data are provided. + * Submitted AAL0 PDUs must be a multiple of the cell data size (48/52). + * AAL0_52 is a raw cell service the client must format + * the PDU with an ATM cell header (excluding HEC) at the start of + * each cell, note that AtmdAcc does not validate the cell headers in + * a submitted PDU. + * + * For the OAM service an "OAM Tx channel" may be enabled for a port + * by establishing a single dedicated OAM Tx connection on that port. + * + * The OAM service allows buffers containing 52 byte OAM F4/F5 cells + * to be transmitted and received over the dedicated OAM channels. + * HEC is appended/removed, and CRC-10 performed by the NPE. The OAM + * service offered by AtmdAcc is a raw cell transport service. + * It is assumed that ITU I.610 procedures that make use of this + * service are implemented above AtmdAcc. + * + * Note that the dedicated OAM connections are established on + * reserved VPI,VCI, and (in the case of Rx) port values. + * These values are used purely to descriminate the dedicated OAM channels + * and do not identify a particular OAM F4/F5 flow. F4/F5 flows may be + * realised for particluar VPI/VCIs by manipulating the VPI,VCI + * fields of the ATM cell headers of cells in the buffers passed + * to AtmdAcc. + * + * Calling this function before enabling the port will fail. + * + * @sa ixAtmdAccTxVcTryDisconnect + * @sa ixAtmdAccPortTxScheduledModeEnable + * @sa ixAtmdAccPortEnable + * + * @param port @ref IxAtmLogicalPort [in] - VC identification : logical PHY port + * [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param vpi unsigned int [in] - VC identification : ATM Vpi [0..255] or IX_ATMDACC_OAM_VPI + * @param vci unsigned int [in] - VC identification : ATM Vci [0..65535] or IX_ATMDACC_OAM_VCI + * @param aalServiceType @ref IxAtmdAccAalType [in] - type of service AAL5, AAL0_48, AAL0_52, or OAM + * @param userId @ref IxAtmdAccUserId [in] - user id to be used later during callbacks related + * to this channel + * @param bufferFreeCallback @ref IxAtmdAccTxVcBufferReturnCallback [in] - function called when mbufs + * transmission is complete. This parameter cannot be a null + * pointer. + * @param connIdPtr @ref IxAtmConnId [out] - Pointer to a connection Id. + * This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS successful call to @a IxAtmdAccRxVcConnect(). + * @return @li IX_ATMDACC_BUSY cannot process this request + * because no VC is available + * @return @li IX_FAIL + * parameter error, + * VC already in use, + * attempt to connect AAL service on reserved OAM VPI/VCI, + * attempt to connect OAM service on VPI/VCI other than the reserved OAM VPI/VCI, + * port is not initialised, + * or some other error occurs during processing. + * + * @note - Unscheduled mode is not supported in ixp425 1.0. Therefore, the + * function @a ixAtmdAccPortTxScheduledModeEnable() need to be called + * for this port before any establishing a Tx Connection + */ +PUBLIC IX_STATUS ixAtmdAccTxVcConnect (IxAtmLogicalPort port, + unsigned int vpi, + unsigned int vci, + IxAtmdAccAalType aalServiceType, + IxAtmdAccUserId userId, + IxAtmdAccTxVcBufferReturnCallback bufferFreeCallback, + IxAtmConnId * connIdPtr); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccTxVcPduSubmit (IxAtmConnId connId, + IX_OSAL_MBUF * mbufPtr, + IxAtmdAccClpStatus clp, + unsigned int numberOfCells) + * + * @brief Submit a Pdu for transmission on connection. + * + * A data user calls this function to submit an mbufs containing a Pdu + * to be transmitted. The buffer supplied can be chained and the Pdu it + * contains must be complete. + * + * The transmission behavior of this call depends on the operational mode + * of the port on which the connection is made. + * + * In unscheduled mode the mbuf will be submitted to the hardware + * immediately if sufficent resource is available. Otherwise the function + * will return failure. + * + * In scheduled mode the buffer is queued internally in IxAtmdAcc. The cell + * demand is made known to the traffic shaping entity. Cells from the + * buffers are MUXed onto the port some time later as dictated by the + * traffic shaping entity. The traffic shaping entity does this by sending + * transmit schedules to IxAtmdAcc via @a ixAtmdAccPortTxProcess() function call. + * + * Note that the dedicated OAM channel is scheduled just like any + * other channel. This means that any OAM traffic relating to an + * active AAL0/AAL5 connection will be scheduled independantly of the + * AAL0/AAL5 traffic for that connection. + * + * When transmission is complete, the TX Done mechanism will give the + * owmnership of these buffers back to the customer. The tx done mechanism + * must be in operation before transmission is attempted. + * + * For AAL0/OAM submitted AAL0 PDUs must be a multiple of the cell data + * size (48/52). AAL0_52 and OAM are raw cell services, and the client + * must format the PDU with an ATM cell header (excluding HEC) at the + * start of each cell, note that AtmdAcc does not validate the cell headers in + * a submitted PDU. + * + * + * @sa IxAtmdAccTxVcBufferReturnCallback + * @sa ixAtmdAccTxDoneDispatch + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to + * @a ixAtmdAccTxVcConnect() + * @param mbufPtr @ref IX_OSAL_MBUF [in] - pointer to a chained structure of mbufs to transmit. + * This parameter cannot be a null pointer. + * @param clp @ref IxAtmdAccClpStatus [in] - clp indication for this PDU. All cells of this pdu + * will be sent with the clp bit set + * @param numberOfCells unsigned int [in] - number of cells in the PDU. + * + * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcPduSubmit() + * The pdu pointed by the mbufPtr parameter will be + * transmitted + * @return @li IX_ATMDACC_BUSY unable to process this request because + * internal resources are all used. The caller is responsible + * for retrying this request later. + * @return @li IX_FAIL unable to process this request because of error + * in the parameters (wrong connId supplied, + * or wrong mbuf pointer supplied), the total length of all buffers + * in the chain should be a multiple of the cell size + * ( 48/52 depending on the service type ), + * or unspecified error during processing + * + * @note - This function in not re-entrant for the same VC (e.g. : two + * thread cannot send PDUs for the same VC). But two threads can + * safely call this function with a different connection Id + * + * @note - In unscheduled mode, this function is not re-entrant on a per + * port basis. The size of pdus is limited to 8Kb. + * + * @note - 0-length mbufs should be removed from the chain before submission. + * The total length of the pdu (sdu + padding +trailer) has to be + * updated in the header of the first mbuf of a chain of mbufs. + * + * @note - Aal5 trailer information (UUI, CPI, SDU length) has to be supplied + * before submission. + * + * @note - The payload memory cache should be flushed, if needed, prior to + * transmission. Mbuf headers are flushed by IxAtmdAcc + * + * @note - This function does not use system resources and can be used + * inside an interrupt context + */ +PUBLIC IX_STATUS ixAtmdAccTxVcPduSubmit (IxAtmConnId connId, + IX_OSAL_MBUF * mbufPtr, + IxAtmdAccClpStatus clp, + unsigned int numberOfCells); + +/** + * + * @ingroup IxAtmdAccAPI + * + * @fn ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId) + * + * @brief Disconnect from a Aal Pdu transmit service for a particular + * port/vpi/vci. + * + * This function deregisters the VC and guarantees that all resources + * associated with this VC are free. After its execution, the connection + * Id is not available. + * + * This function will fail until such time as all resources allocated to + * the VC connection have been freed. The user is responsible to delay + * and call again this function many times until a success status is + * returned. + * + * After its execution, the connection Id is not available. + * + * @param connId @ref IxAtmConnId [in] - connection Id as resulted from a succesfull call to + * @a ixAtmdAccTxVcConnect() + * + * @return @li IX_SUCCESS successful call to @a ixAtmdAccTxVcTryDisconnect() + * @return @li IX_ATMDACC_RESOURCES_STILL_ALLOCATED not all resources + * associated with the connection have been freed. This condition will + * disappear after Tx and TxDone is complete for this channel. + * @return @li IX_FAIL unable to process this request because of errors + * in the parameters (wrong connId supplied) + * + * @note - This function needs internal locks and should not be called + * from an interrupt context + * + * @note - If the @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED error does not + * clear after a while, this may be linked to a previous problem + * of cell overscheduling. Diabling the port and retry a disconnect + * will free the resources associated with this channel. + * + * @sa ixAtmdAccPortTxProcess + * + */ +PUBLIC IX_STATUS ixAtmdAccTxVcTryDisconnect (IxAtmConnId connId); + +#endif /* IXATMDACC_H */ + +/** + * @} defgroup IxAtmdAccAPI + */ + + diff --git a/drivers/net/npe/include/IxAtmdAccCtrl.h b/drivers/net/npe/include/IxAtmdAccCtrl.h new file mode 100644 index 0000000..50ef582 --- /dev/null +++ b/drivers/net/npe/include/IxAtmdAccCtrl.h @@ -0,0 +1,1958 @@ + +/** + * @file IxAtmdAccCtrl.h + * + * @date 20-Mar-2002 + * + * @brief IxAtmdAcc Public API + * + * This file contains the public API of IxAtmdAcc, related to the + * control functions of the component. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/* ------------------------------------------------------ + Doxygen group definitions + ------------------------------------------------------ */ + +/** + * + * @defgroup IxAtmdAccCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Control API + * + * @brief The public API for the IXP400 Atm Driver Control component + * + * IxAtmdAcc is the low level interface by which AAL PDU get transmitted + * to,and received from the Utopia bus + * + * This part is related to the Control configuration + * + * @{ + */ + +#ifndef IXATMDACCCTRL_H +#define IXATMDACCCTRL_H + +#include "IxAtmdAcc.h" + +/* ------------------------------------------------------ + AtmdAccCtrl Data Types definition + ------------------------------------------------------ */ + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @def IX_ATMDACC_PORT_DISABLE_IN_PROGRESS +* +* @brief Port enable return code +* +* This constant is used to tell IxAtmDAcc user that the port disable +* functions are not complete. The user can call ixAtmdAccPortDisableComplete() +* to find out when the disable has finished. The port enable can then proceed. +* +*/ +#define IX_ATMDACC_PORT_DISABLE_IN_PROGRESS 5 + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @def IX_ATMDACC_ALLPDUS +* +* @brief All PDUs +* +* This constant is used to tell IxAtmDAcc to process all PDUs from +* the RX queue or the TX Done +* +* @sa IxAtmdAccRxDispatcher +* @sa IxAtmdAccTxDoneDispatcher +* +*/ +#define IX_ATMDACC_ALLPDUS 0xffffffff + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to RX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @brief Callback prototype for notification of available PDUs for + * an Rx Q. + * + * This a protoype for a function which is called when there is at + * least one Pdu available for processing on a particular Rx Q. + * + * This function should call @a ixAtmdAccRxDispatch() with + * the aprropriate number of parameters to read and process the Rx Q. + * + * @sa ixAtmdAccRxDispatch + * @sa ixAtmdAccRxVcConnect + * @sa ixAtmdAccRxDispatcherRegister + * + * @param rxQueueId @ref IxAtmRxQueueId [in] indicates which RX queue to has Pdus to process. + * @param numberOfPdusToProcess unsigned int [in] indicates the minimum number of + * PDUs available to process all PDUs from the queue. + * @param reservedPtr unsigned int* [out] pointer to a int location which can + * be written to, but does not retain written values. This is + * provided to make this prototype compatible + * with @a ixAtmdAccRxDispatch() + * + * @return @li int - ignored. + * + */ +typedef IX_STATUS (*IxAtmdAccRxDispatcher) (IxAtmRxQueueId rxQueueId, + unsigned int numberOfPdusToProcess, + unsigned int *reservedPtr); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to TX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @brief Callback prototype for transmitted mbuf when threshold level is + * crossed. + * + * IxAtmdAccTxDoneDispatcher is the prototype of the user function + * which get called when pdus are completely transmitted. This function + * is likely to call the @a ixAtmdAccTxDoneDispatch() function. + * + * This function is called when the number of available pdus for + * reception is crossing the threshold level as defined + * in @a ixAtmdAccTxDoneDispatcherRegister() + * + * This function is called inside an Qmgr dispatch context. No system + * resource or interrupt-unsafe feature should be used inside this + * callback. + * + * Transmitted buffers recycling implementation is a sytem-wide mechanism + * and needs to be set before any traffic is started. If this threshold + * mechanism is not used, the user is responsible for polling the + * transmitted buffers with @a ixAtmdAccTxDoneDispatch() + * and @a ixAtmdAccTxDoneLevelQuery() functions. + * + * @sa ixAtmdAccTxDoneDispatcherRegister + * @sa ixAtmdAccTxDoneDispatch + * @sa ixAtmdAccTxDoneLevelQuery + * + * @param numberOfPdusToProcess unsigned int [in] - The current number of pdus currently + * available for recycling + * @param *reservedPtr unsigned int [out] - pointer to a int location which can be + * written to but does not retain written values. This is provided + * to make this prototype compatible + * with @a ixAtmdAccTxDoneDispatch() + * + * @return @li IX_SUCCESS This is provided to make + * this prototype compatible with @a ixAtmdAccTxDoneDispatch() + * @return @li IX_FAIL invalid parameters or some unspecified internal + * error occured. This is provided to make + * this prototype compatible with @a ixAtmdAccTxDoneDispatch() + * + */ +typedef IX_STATUS (*IxAtmdAccTxDoneDispatcher) (unsigned int numberOfPdusToProcess, + unsigned int *reservedPtr); + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @brief Notification that the threshold number of scheduled cells +* remains in a port's transmit Q. +* +* The is the prototype for of the user notification function which +* gets called on a per-port basis, when the number of remaining +* scheduled cells to be transmitted decreases to the threshold level. +* The number of cells passed as a parameter can be used for scheduling +* purposes as the maximum number of cells that can be passed in a +* schedule table to the @a ixAtmdAccPortTxProcess() function. +* +* @sa ixAtmdAccPortTxCallbackRegister +* @sa ixAtmdAccPortTxProcess +* @sa ixAtmdAccPortTxFreeEntriesQuery +* +* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] +* @param numberOfAvailableCells unsigned int [in] - number of available +* cell entries.for the port +* +* @note - This functions shall not use system resources when used +* inside an interrupt context. +* +*/ +typedef void (*IxAtmdAccPortTxLowCallback) (IxAtmLogicalPort port, + unsigned int numberOfAvailableCells); + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @brief Prototype to submit cells for transmission +* +* IxAtmdAccTxVcDemandUpdateCallback is the prototype of the callback +* function used by AtmD to notify an ATM Scheduler that the user of +* a VC has submitted cells for transmission. +* +* @sa IxAtmdAccTxVcDemandUpdateCallback +* @sa IxAtmdAccTxVcDemandClearCallback +* @sa IxAtmdAccTxSchVcIdGetCallback +* @sa ixAtmdAccPortTxScheduledModeEnable +* +* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be updated +* is established +* @param vcId int [in] - Identifies the VC to be updated. This is the value +* returned by the @a IxAtmdAccTxSchVcIdGetCallback() call . +* @param numberOfCells unsigned int [in] - Indicates how many ATM cells should be added +* to the queue for this VC. +* +* @return @li IX_SUCCESS the function is registering the cell demand for +* this VC. +* @return @li IX_FAIL the function cannot register cell for this VC : the +* scheduler maybe overloaded or misconfigured +* +*/ +typedef IX_STATUS (*IxAtmdAccTxVcDemandUpdateCallback) (IxAtmLogicalPort port, + int vcId, + unsigned int numberOfCells); + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @brief prototype to remove all currently queued cells from a +* registered VC +* +* IxAtmdAccTxVcDemandClearCallback is the prototype of the function +* to remove all currently queued cells from a registered VC. The +* pending cell count for the specified VC is reset to zero. After the +* use of this callback, the scheduler shall not schedule more cells +* for this VC. +* +* This callback function is called during a VC disconnection +* @a ixAtmdAccTxVcTryDisconnect() +* +* @sa IxAtmdAccTxVcDemandUpdateCallback +* @sa IxAtmdAccTxVcDemandClearCallback +* @sa IxAtmdAccTxSchVcIdGetCallback +* @sa ixAtmdAccPortTxScheduledModeEnable +* @sa ixAtmdAccTxVcTryDisconnect +* +* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM port on which the VC to be cleared +* is established +* @param vcId int [in] - Identifies the VC to be cleared. This is the value +* returned by the @a IxAtmdAccTxSchVcIdGetCallback() call . +* +* @return none +* +*/ +typedef void (*IxAtmdAccTxVcDemandClearCallback) (IxAtmLogicalPort port, + int vcId); + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @brief prototype to get a scheduler vc id +* +* IxAtmdAccTxSchVcIdGetCallback is the prototype of the function to get +* a scheduler vcId +* +* @sa IxAtmdAccTxVcDemandUpdateCallback +* @sa IxAtmdAccTxVcDemandClearCallback +* @sa IxAtmdAccTxSchVcIdGetCallback +* @sa ixAtmdAccPortTxScheduledModeEnable +* +* @param port @ref IxAtmLogicalPort [in] - Specifies the ATM logical port on which the VC is +* established +* @param vpi unsigned int [in] - For AAL0/AAL5 specifies the ATM vpi on which the +* VC is established. +* For OAM specifies the dedicated "OAM Tx channel" VPI. +* @param vci unsigned int [in] - For AAL0/AAL5 specifies the ATM vci on which the +* VC is established. +* For OAM specifies the dedicated "OAM Tx channel" VCI. +* @param connId @ref IxAtmConnId [in] - specifies the IxAtmdAcc connection Id already +* associated with this VC +* @param vcId int* [out] - pointer to a vcId +* +* @return @li IX_SUCCESS the function is returning a Scheduler vcId for this +* VC +* @return @li IX_FAIL the function cannot process scheduling for this VC. +* the contents of vcId is unspecified +* +*/ +typedef IX_STATUS (*IxAtmdAccTxSchVcIdGetCallback) (IxAtmLogicalPort port, + unsigned int vpi, + unsigned int vci, + IxAtmConnId connId, + int *vcId); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to RX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccRxDispatcherRegister ( + IxAtmRxQueueId queueId, + IxAtmdAccRxDispatcher callback) + * + * @brief Register a notification callback to be invoked when there is + * at least one entry on a particular Rx queue. + * + * This function registers a callback to be invoked when there is at + * least one entry in a particular queue. The registered callback is + * called every time when the hardware adds one or more pdus to the + * specified Rx queue. + * + * This function cannot be used when a Rx Vc using this queue is + * already existing. + * + * @note -The callback function can be the API function + * @a ixAtmdAccRxDispatch() : every time the threhold level + * of the queue is reached, the ixAtmdAccRxDispatch() is + * invoked to remove all entries from the queue. + * + * @sa ixAtmdAccRxDispatch + * @sa IxAtmdAccRxDispatcher + * + * @param queueId @ref IxAtmRxQueueId [in] RX queue identification + * @param callback @ref IxAtmdAccRxDispatcher [in] function triggering the delivery of incoming + * traffic. This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS Successful call to @a ixAtmdAccRxDispatcherRegister() + * @return @li IX_FAIL error in the parameters, or there is an + * already active RX VC for this queue or some unspecified + * internal error occurred. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxDispatcherRegister ( + IxAtmRxQueueId queueId, + IxAtmdAccRxDispatcher callback); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId, + unsigned int numberOfPdusToProcess, + unsigned int *numberOfPdusProcessedPtr) + * + * + * @brief Control function which executes Rx processing for a particular + * Rx stream. + * + * The @a IxAtmdAccRxDispatch() function is used to process received Pdus + * available from one of the two incoming RX streams. When this function + * is invoked, the incoming traffic (up to the number of PDUs passed as + * a parameter) will be transferred to the IxAtmdAcc users through the + * callback @a IxAtmdAccRxVcRxCallback(), as registered during the + * @a ixAtmdAccRxVcConnect() call. + * + * The user receive callbacks will be executed in the context of this + * function. + * + * Failing to use this function on a regular basis when there is traffic + * will block incoming traffic and can result in Pdus being dropped by + * the hardware. + * + * This should be used to control when received pdus are handed off from + * the hardware to Aal users from a particluar stream. The function can + * be used from a timer context, or can be registered as a callback in + * response to an rx stream threshold event, or can be used inside an + * active polling mechanism which is under user control. + * + * @note - The signature of this function is directly compatible with the + * callback prototype which can be register with @a ixAtmdAccRxDispatcherRegister(). + * + * @sa ixAtmdAccRxDispatcherRegister + * @sa IxAtmdAccRxVcRxCallback + * @sa ixAtmdAccRxVcFreeEntriesQuery + * + * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which RX queue to process. + * @param numberOfPdusToProcess unsigned int [in] - indicates the maxiumum number of PDU to + * remove from the RX queue. A value of IX_ATMDACC_ALLPDUS indicates + * to process all PDUs from the queue. This includes at least the PDUs + * in the queue when the fuction is invoked. Because of real-time + * constraints, there is no guarantee thatthe queue will be empty + * when the function exits. If this parameter is greater than the + * number of entries of the queues, the function will succeed + * and the parameter numberOfPdusProcessedPtr will reflect the exact + * number of PDUs processed. + * @param *numberOfPdusProcessedPtr unsigned int [out] - indicates the actual number of PDU + * processed during this call. This parameter cannot be a null + * pointer. + * + * @return @li IX_SUCCESS the number of PDUs as indicated in + * numberOfPdusProcessedPtr are removed from the RX queue and the VC callback + * are called. + * @return @li IX_FAIL invalid parameters or some unspecified internal + * error occured. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxDispatch (IxAtmRxQueueId rxQueueId, + unsigned int numberOfPdusToProcess, + unsigned int *numberOfPdusProcessedPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId, + unsigned int *numberOfPdusPtr) + * + * @brief Query the number of entries in a particular RX queue. + * + * This function is used to retrieve the number of pdus received by + * the hardware and ready for distribution to users. + * + * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query. + * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of available + * PDUs in the RX queue. This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the + * number of incoming pdus waiting in this queue + * @return @li IX_FAIL an error occurs during processing. + * The value in numberOfPdusPtr is unspecified. + * + * @note - This function is reentrant, doesn't use system resources + * and can be used from an interrupt context. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxLevelQuery (IxAtmRxQueueId rxQueueId, + unsigned int *numberOfPdusPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId, + unsigned int *numberOfPdusPtr) + * + * @brief Query the size of a particular RX queue. + * + * This function is used to retrieve the number of pdus the system is + * able to queue when reception is complete. + * + * @param rxQueueId @ref IxAtmRxQueueId [in] - indicates which of two RX queues to query. + * @param numberOfPdusPtr unsigned int* [out] - Pointer to store the number of pdus + * the system is able to queue in the RX queue. This parameter + * cannot be a null pointer. + * + * @return @li IX_SUCCESS the value in numberOfPdusPtr specifies the + * number of pdus the system is able to queue. + * @return @li IX_FAIL an error occurs during processing. + * The value in numberOfPdusPtr is unspecified. + * + * @note - This function is reentrant, doesn't use system resources + * and can be used from an interrupt context. + * + */ +PUBLIC IX_STATUS ixAtmdAccRxQueueSizeQuery (IxAtmRxQueueId rxQueueId, + unsigned int *numberOfPdusPtr); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to TX traffic + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port, + unsigned int *numberOfCellsPtr) + * + * @brief Get the number of available cells the system can accept for + * transmission. + * + * The function is used to retrieve the number of cells that can be + * queued for transmission to the hardware. + * + * This number is based on the worst schedule table where one cell + * is stored in one schedule table entry, depending on the pdus size + * and mbuf size and fragmentation. + * + * This function doesn't use system resources and can be used from a + * timer context, or can be associated with a threshold event, or can + * be used inside an active polling mechanism + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param numberOfCellsPtr unsigned int* [out] - number of available cells. + * This parameter cannot be a null pointer. + * + * @sa ixAtmdAccPortTxProcess + * + * @return @li IX_SUCCESS numberOfCellsPtr contains the number of cells that can be scheduled + * for this port. + * @return @li IX_FAIL error in the parameters, or some processing error + * occured. + * + */ +PUBLIC IX_STATUS ixAtmdAccPortTxFreeEntriesQuery (IxAtmLogicalPort port, + unsigned int *numberOfCellsPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port, + unsigned int numberOfCells, + IxAtmdAccPortTxLowCallback callback) + * + * @brief Configure the Tx port threshold value and register a callback to handle + * threshold notifications. + * + * This function sets the threshold in cells + * + * @sa ixAtmdAccPortTxCallbackRegister + * @sa ixAtmdAccPortTxProcess + * @sa ixAtmdAccPortTxFreeEntriesQuery + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param numberOfCells unsigned int [in] - threshold value which triggers the callback + * invocation, This number has to be one of the + * values 0,1,2,4,8,16,32 .... + * The maximum value cannot be more than half of the txVc queue + * size (which can be retrieved using @a ixAtmdAccPortTxFreeEntriesQuery() + * before any Tx traffic is sent for this port) + * @param callback @ref IxAtmdAccPortTxLowCallback [in] - callback function to invoke when the threshold + * level is reached. + * This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS Successful call to @a ixAtmdAccPortTxCallbackRegister() + * @return @li IX_FAIL error in the parameters, Tx channel already set for this port + * threshold level is not correct or within the range regarding the + * queue size:or unspecified error during processing: + * + * @note - This callback function get called when the threshold level drops from + * (numberOfCells+1) cells to (numberOfCells) cells + * + * @note - This function should be called during system initialisation, + * outside an interrupt context + * + */ +PUBLIC IX_STATUS ixAtmdAccPortTxCallbackRegister (IxAtmLogicalPort port, + unsigned int numberOfCells, + IxAtmdAccPortTxLowCallback callback); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port, + IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback, + IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback, + IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback) + * + * @brief Put the port into Scheduled Mode + * + * This function puts the specified port into scheduled mode of + * transmission which means an external s/w entity controls the + * transmission of cells on this port. This faciltates traffic shaping on + * the port. + * + * Any buffers submitted on a VC for this port will be queued in IxAtmdAcc. + * The transmission of these buffers to and by the hardware will be driven + * by a transmit schedule submitted regulary in calls to + * @a ixAtmdAccPortTxProcess() by traffic shaping entity. + * + * The transmit schedule is expected to be dynamic in nature based on + * the demand in cells for each VC on the port. Hence the callback + * parameters provided to this function allow IxAtmdAcc to inform the + * shaping entity of demand changes for each VC on the port. + * + * By default a port is in Unscheduled Mode so if this function is not + * called, transmission of data is done without sheduling rules, on a + * first-come, first-out basis. + * + * Once a port is put in scheduled mode it cannot be reverted to + * un-scheduled mode. Note that unscheduled mode is not supported + * in ixp425 1.0 + * + * @note - This function should be called before any VCs have be + * connected on a port. Otherwise this function call will return failure. + * + * @note - This function uses internal locks and should not be called from + * an interrupt context + * + * @sa IxAtmdAccTxVcDemandUpdateCallback + * @sa IxAtmdAccTxVcDemandClearCallback + * @sa IxAtmdAccTxSchVcIdGetCallback + * @sa ixAtmdAccPortTxProcess + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param vcDemandUpdateCallback @ref IxAtmdAccTxVcDemandUpdateCallback [in] - callback function used to update + * the number of outstanding cells for transmission. This parameter + * cannot be a null pointer. + * @param vcDemandClearCallback @ref IxAtmdAccTxVcDemandClearCallback [in] - callback function used to remove all + * clear the number of outstanding cells for a VC. This parameter + * cannot be a null pointer. + * @param vcIdGetCallback @ref IxAtmdAccTxSchVcIdGetCallback [in] - callback function used to exchange vc + * Identifiers between IxAtmdAcc and the entity supplying the + * transmit schedule. This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS scheduler registration is complete and the port + * is now in scheduled mode. + * @return @li IX_FAIL failed (wrong parameters, or traffic is already + * enabled on this port, possibly without ATM shaping) + * + */ +PUBLIC IX_STATUS ixAtmdAccPortTxScheduledModeEnable (IxAtmLogicalPort port, + IxAtmdAccTxVcDemandUpdateCallback vcDemandUpdateCallback, + IxAtmdAccTxVcDemandClearCallback vcDemandClearCallback, + IxAtmdAccTxSchVcIdGetCallback vcIdGetCallback); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccPortTxProcess (IxAtmLogicalPort port, + IxAtmScheduleTable* scheduleTablePtr) + * + * @brief Transmit queue cells to the H/W based on the supplied schedule + * table. + * + * This function @a ixAtmdAccPortTxProcess() process the schedule + * table provided as a parameter to the function. As a result cells are + * sent to the underlaying hardware for transmission. + * + * The schedule table is executed in its entirety or not at all. So the + * onus is on the caller not to submit a table containing more cells than + * can be transmitted at that point. The maximum numbers that can be + * transmitted is guaranteed to be the number of cells as returned by the + * function @a ixAtmdAccPortTxFreeEntriesQuery(). + * + * When the scheduler is invoked on a threshold level, IxAtmdAcc gives the + * minimum number of cells (to ensure the callback will fire again later) + * and the maximum number of cells that @a ixAtmdAccPortTxProcess() + * will be able to process (assuming the ATM scheduler is able + * to produce the worst-case schedule table, i.e. one entry per cell). + * + * When invoked ouside a threshold level, the overall number of cells of + * the schedule table should be less than the number of cells returned + * by the @a ixAtmdAccPortTxFreeEntriesQuery() function. + * + * After invoking the @a ixAtmdAccPortTxProcess() function, it is the + * user choice to query again the queue level with the function + * @a ixAtmdAccPortTxFreeEntriesQuery() and, depending on a new cell + * number, submit an other schedule table. + * + * IxAtmdAcc will check that the number of cells in the schedule table + * is compatible with the current transmit level. If the + * + * Obsolete or invalid connection Id will be silently discarded. + * + * This function is not reentrant for the same port. + * + * This functions doesn't use system resources and can be used inside an + * interrupt context. + * + * This function is used as a response to the hardware requesting more + * cells to transmit. + * + * @sa ixAtmdAccPortTxScheduledModeEnable + * @sa ixAtmdAccPortTxFreeEntriesQuery + * @sa ixAtmdAccPortTxCallbackRegister + * @sa ixAtmdAccPortEnable + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * @param scheduleTablePtr @ref IxAtmScheduleTable* [in] - pointer to a scheduler update table. The + * content of this table is not modified by this function. This + * parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS the schedule table process is complete + * and cells are transmitted to the hardware + * @return @li IX_ATMDACC_WARNING : Traffic will be dropped: the schedule table exceed + * the hardware capacity If this error is ignored, further traffic + * and schedule will work correctly. + * Overscheduling does not occur when the schedule table does + * not contain more entries that the number of free entries returned + * by @a ixAtmdAccPortTxFreeEntriesQuery(). + * However, Disconnect attempts just after this error will fail permanently + * with the error code @a IX_ATMDACC_RESOURCES_STILL_ALLOCATED, and it is + * necessary to disable the port to make @a ixAtmdAccTxVcTryDisconnect() + * successful. + * @return @li IX_FAIL a wrong parameter is supplied, or the format of + * the schedule table is invalid, or the port is not Enabled, or + * an internal severe error occured. No cells is transmitted to the hardware + * + * @note - If the failure is linked to an overschedule of data cells + * the result is an inconsistency in the output traffic (one or many + * cells may be missing and the traffic contract is not respected). + * + */ +PUBLIC IX_STATUS ixAtmdAccPortTxProcess (IxAtmLogicalPort port, + IxAtmScheduleTable* scheduleTablePtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess, + unsigned int *numberOfPdusProcessedPtr) + * + * @brief Process a number of pending transmit done pdus from the hardware. + * + * As a by-product of Atm transmit operation buffers which transmission + * is complete need to be recycled to users. This function is invoked + * to service the oustanding list of transmitted buffers and pass them + * to VC users. + * + * Users are handed back pdus by invoking the free callback registered + * during the @a ixAtmdAccTxVcConnect() call. + * + * There is a single Tx done stream servicing all active Atm Tx ports + * which can contain a maximum of 64 entries. If this stream fills port + * transmission will stop so this function must be call sufficently + * frequently to ensure no disruption to the transmit operation. + * + * This function can be used from a timer context, or can be associated + * with a TxDone level threshold event (see @a ixAtmdAccTxDoneDispatcherRegister() ), + * or can be used inside an active polling mechanism under user control. + * + * For ease of use the signature of this function is compatible with the + * TxDone threshold event callback prototype. + * + * This functions can be used inside an interrupt context. + * + * @sa ixAtmdAccTxDoneDispatcherRegister + * @sa IxAtmdAccTxVcBufferReturnCallback + * @sa ixAtmdAccTxDoneLevelQuery + * + * @param numberOfPdusToProcess unsigned int [in] - maxiumum number of pdus to remove + * from the TX Done queue + * @param *numberOfPdusProcessedPtr unsigned int [out] - number of pdus removed from + * the TX Done queue. This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS the number of pdus as indicated in + * numberOfPdusToProcess are removed from the TX Done hardware + * and passed to the user through the Tx Done callback registered + * during a call to @a ixAtmdAccTxVcConnect() + * @return @li IX_FAIL invalid parameters or numberOfPdusProcessedPtr is + * a null pointer or some unspecified internal error occured. + * + */ +PUBLIC IX_STATUS +ixAtmdAccTxDoneDispatch (unsigned int numberOfPdusToProcess, + unsigned int *numberOfPdusProcessedPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr) + * + * @brief Query the current number of transmit pdus ready for + * recycling. + * + * This function is used to get the number of transmitted pdus which + * the hardware is ready to hand back to user. + * + * This function can be used from a timer context, or can be associated + * with a threshold event, on can be used inside an active polling + * mechanism + * + * @sa ixAtmdAccTxDoneDispatch + * + * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus transmitted + * at the time of this function call, and ready for recycling + * This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS numberOfPdusPtr contains the number of pdus + * ready for recycling at the time of this function call + * + * @return @li IX_FAIL wrong parameter (null pointer as parameter).or + * unspecified rocessing error occurs..The value in numberOfPdusPtr + * is unspecified. + * + */ +PUBLIC IX_STATUS +ixAtmdAccTxDoneLevelQuery (unsigned int *numberOfPdusPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr) + * + * @brief Query the TxDone queue size. + * + * This function is used to get the number of pdus which + * the hardware is able to store after transmission is complete + * + * The returned value can be used to set a threshold and enable + * a callback to be notified when the number of pdus is going over + * the threshold. + * + * @sa ixAtmdAccTxDoneDispatcherRegister + * + * @param *numberOfPdusPtr unsigned int [out] - Pointer to the number of pdus the system + * is able to queue after transmission + * + * @return @li IX_SUCCESS numberOfPdusPtr contains the the number of + * pdus the system is able to queue after transmission + * @return @li IX_FAIL wrong parameter (null pointer as parameter).or + * unspecified rocessing error occurs..The value in numberOfPdusPtr + * is unspecified. + * + * @note - This function is reentrant, doesn't use system resources + * and can be used from an interrupt context. + */ +PUBLIC IX_STATUS +ixAtmdAccTxDoneQueueSizeQuery (unsigned int *numberOfPdusPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus, + IxAtmdAccTxDoneDispatcher notificationCallback) + * + * @brief Configure the Tx Done stream threshold value and register a + * callback to handle threshold notifications. + * + * This function sets the threshold level in term of number of pdus at + * which the supplied notification function should be called. + * + * The higher the threshold value is, the less events will be necessary + * to process transmitted buffers. + * + * Transmitted buffers recycling implementation is a sytem-wide mechanism + * and needs to be set prior any traffic is started. If this threshold + * mechanism is not used, the user is responsible for polling the + * transmitted buffers thanks to @a ixAtmdAccTxDoneDispatch() and + * @a ixAtmdAccTxDoneLevelQuery() functions. + * + * This function should be called during system initialisation outside + * an interrupt context + * + * @sa ixAtmdAccTxDoneDispatcherRegister + * @sa ixAtmdAccTxDoneDispatch + * @sa ixAtmdAccTxDoneLevelQuery + * + * @param numberOfPdus unsigned int [in] - The number of TxDone pdus which triggers the + * callback invocation This number has to be a power of 2, one of the + * values 0,1,2,4,8,16,32 ... + * The maximum value cannot be more than half of the txDone queue + * size (which can be retrieved using @a ixAtmdAccTxDoneQueueSizeQuery()) + * @param notificationCallback @ref IxAtmdAccTxDoneDispatcher [in] - The function to invoke. (This + * parameter can be @a ixAtmdAccTxDoneDispatch()).This + * parameter ust not be a null pointer. + * + * @return @li IX_SUCCESS Successful call to ixAtmdAccTxDoneDispatcherRegister + * @return @li IX_FAIL error in the parameters: + * + * @note - The notificationCallback will be called exactly when the threshold level + * will increase from (numberOfPdus) to (numberOfPdus+1) + * + * @note - If there is no Tx traffic, there is no guarantee that TxDone Pdus will + * be released to the user (when txDone level is permanently under the threshold + * level. One of the preffered way to return resources to the user is to use + * a mix of txDone notifications, used together with a slow + * rate timer and an exclusion mechanism protecting from re-entrancy + * + * @note - The TxDone threshold will only hand back buffers when the threshold level is + * crossed. Setting this threshold to a great number reduce the interrupt rate + * and the cpu load, but also increase the number of outstanding mbufs and has + * a system wide impact when these mbufs are needed by other components. + * + */ +PUBLIC IX_STATUS ixAtmdAccTxDoneDispatcherRegister (unsigned int numberOfPdus, + IxAtmdAccTxDoneDispatcher notificationCallback); + +/* ------------------------------------------------------ + Part of the IxAtmdAcc interface related to Utopia config + ------------------------------------------------------ */ + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @defgroup IxAtmdAccUtopiaCtrlAPI IXP400 ATM Driver Access (IxAtmdAcc) Utopia Control API + * + * @brief The public API for the IXP400 Atm Driver Control component + * + * IxAtmdAcc is the low level interface by which AAL PDU get + * transmitted to,and received from the Utopia bus + * + * This part is related to the UTOPIA configuration. + * + * @{ + */ + +/** + * + * @brief Utopia configuration + * + * This structure is used to set the Utopia parameters + * @li contains the values of Utopia registers, to be set during initialisation + * @li contains debug commands for NPE, to be used during development steps + * + * @note - the exact description of all parameters is done in the Utopia reference + * documents. + * + */ +typedef struct +{ + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxConfig_ + * @brief Utopia Tx Config Register + */ + struct UtTxConfig_ + { + + unsigned int reserved_1:1; /**< [31] These bits are always 0.*/ + unsigned int txInterface:1; /**< [30] Utopia Transmit Interface. The following encoding + * is used to set the Utopia Transmit interface as ATM master + * or PHY slave: + * @li 1 - PHY + * @li 0 - ATM + */ + unsigned int txMode:1; /**< [29] Utopia Transmit Mode. The following encoding is used + * to set the Utopia Transmit mode to SPHY or MPHY: + * @li 1 - SPHY + * @li 0 - MPHY + */ + unsigned int txOctet:1; /**< [28] Utopia Transmit cell transfer protocol. Used to set + * the Utopia cell transfer protocol to Octet-level handshaking. + * Note this is only applicable in SPHY mode. + * @li 1 - Octet-handshaking enabled + * @li 0 - Cell-handshaking enabled + */ + unsigned int txParity:1; /**< [27] Utopia Transmit parity enabled when set. TxEvenParity + * defines the parity format odd/even. + * @li 1 - Enable Parity generation. + * @li 0 - ut_op_prty held low. + */ + unsigned int txEvenParity:1; /**< [26] Utopia Transmit Parity Mode + * @li 1 - Even Parity Generated. + * @li 0 - Odd Parity Generated. + */ + unsigned int txHEC:1; /**< [25] Header Error Check Insertion Mode. Specifies if the transmit + * cell header check byte is calculated and inserted when set. + * @li 1 - Generate HEC. + * @li 0 - Disable HEC generation. + */ + unsigned int txCOSET:1; /**< [24] If enabled the HEC is Exclusive-OR'ed with the value 0x55 before + * being presented on the Utopia bus. + * @li 1 - Enable HEC ExOR with value 0x55 + * @li 0 - Use generated HEC value. + */ + + unsigned int reserved_2:1; /**< [23] These bits are always 0 + */ + unsigned int txCellSize:7; /**< [22:16] Transmit expected cell size. Configures the cell size + * for the transmit module: Values between 52-64 are valid. + */ + unsigned int reserved_3:3; /**< [15:13] These bits are always 0 */ + unsigned int txAddrRange:5; /**< [12:8] When configured as an ATM master in MPHY mode this + * register specifies the upper limit of the PHY polling logical + * range. The number of active PHYs are TxAddrRange + 1. + */ + unsigned int reserved_4:3; /**< [7:5] These bits are always 0 */ + unsigned int txPHYAddr:5; /**< [4:0] When configured as a slave in an MPHY system this register + * specifies the physical address of the PHY. + */ + } + + utTxConfig; /**< Tx config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxStatsConfig_ + * @brief Utopia Tx stats Register + */ + struct UtTxStatsConfig_ + { + + unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] + @li Note: if VCStatsTxGFC is set to 0 the GFC field is ignored in test. */ + + unsigned int vci:16; /**< [19:4] ATM VCI [15:0] or PHY Address[4] */ + + unsigned int pti:3; /**< [3:1] ATM PTI [2:0] or PHY Address[3:1] + @li Note: if VCStatsTxPTI is set to 0 the PTI field is ignored in test. + @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port + address as defined by this register is used for ATM statistics [4:0]. */ + + unsigned int clp:1; /**< [0] ATM CLP or PHY Address [0] + @li Note: if VCStatsTxCLP is set to 0 the CLP field is ignored in test. + @li Note: if VCStatsTxEnb is set to 0 only the transmit PHY port + address as defined by this register is used for ATM statistics [4:0]. */ + } + + utTxStatsConfig; /**< Tx stats config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxDefineIdle_ + * @brief Utopia Tx idle cells Register + */ + struct UtTxDefineIdle_ + { + + unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] + @li Note: if VCIdleTxGFC is set to 0 the GFC field is ignored in test. */ + + unsigned int vci:16; /**< [19:4] ATM VCI [15:0] */ + + unsigned int pti:3; /**< [3:1] ATM PTI PTI [2:0] + @li Note: if VCIdleTxPTI is set to 0 the PTI field is ignored in test.*/ + + unsigned int clp:1; /**< [0] ATM CLP [0] + @li Note: if VCIdleTxCLP is set to 0 the CLP field is ignored in test.*/ + } + + utTxDefineIdle; /**< Tx idle cell config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxEnableFields_ + * @brief Utopia Tx ienable fields Register + */ + struct UtTxEnableFields_ + { + + unsigned int defineTxIdleGFC:1; /**< [31] This register is used to include or exclude the GFC + field of the ATM header when testing for Idle cells. + @li 1 - GFC field is valid. + @li 0 - GFC field ignored.*/ + + unsigned int defineTxIdlePTI:1; /**< [30] This register is used to include or exclude the PTI + field of the ATM header when testing for Idle cells. + @li 1 - PTI field is valid + @li 0 - PTI field ignored.*/ + + unsigned int defineTxIdleCLP:1; /**< [29] This register is used to include or + exclude the CLP field of the ATM header when testing for Idle cells. + @li 1 - CLP field is valid. + @li 0 - CLP field ignored. */ + + unsigned int phyStatsTxEnb:1; /**< [28] This register is used to enable or disable ATM + statistics gathering based on the specified PHY address as defined + in TxStatsConfig register. + @li 1 - Enable statistics for specified transmit PHY address. + @li 0 - Disable statistics for specified transmit PHY address. */ + + unsigned int vcStatsTxEnb:1; /**< [27] This register is used to change the ATM + statistics-gathering mode from the specified logical PHY address + to a specific VPI/VCI address. + @li 1 - Enable statistics for specified VPI/VCI address. + @li 0 - Disable statistics for specified VPI/VCI address */ + + unsigned int vcStatsTxGFC:1; /**< [26] This register is used to include or exclude the GFC + field of the ATM header when ATM VPI/VCI statistics are enabled. + GFC is only available at the UNI and uses the first 4-bits of + the VPI field. + @li 1 - GFC field is valid + @li 0 - GFC field ignored.*/ + + unsigned int vcStatsTxPTI:1; /**< [25] This register is used to include or exclude the PTI + field of the ATM header when ATM VPI/VCI statistics are enabled. + @li 1 - PTI field is valid + @li 0 - PTI field ignored.*/ + + unsigned int vcStatsTxCLP:1; /**< [24] This register is used to include or exclude the CLP + field of the ATM header when ATM VPI/VCI statistics are enabled. + @li 1 - CLP field is valid + @li 0 - CLP field ignored. */ + + unsigned int reserved_1:3; /**< [23-21] These bits are always 0 */ + + unsigned int txPollStsInt:1; /**< [20] Enable the assertion of the ucp_tx_poll_sts condition + where there is a change in polling status. + @li 1 - ucp_tx_poll_sts asserted whenever there is a change in status + @li 0 - ucp_tx_poll_sts asserted if ANY transmit PHY is available + */ + unsigned int txCellOvrInt:1; /**< [19] Enable TxCellCount overflow CBI Transmit Status condition + assertion. + @li 1 - If TxCellCountOvr is set assert the Transmit Status Condition. + @li 0 - No CBI Transmit Status condition assertion */ + + unsigned int txIdleCellOvrInt:1; /**< [18] Enable TxIdleCellCount overflow Transmit Status Condition + @li 1 - If TxIdleCellCountOvr is set assert the Transmit Status Condition + @li 0 - No CBI Transmit Status condition assertion..*/ + + unsigned int enbIdleCellCnt:1; /**< [17] Enable Transmit Idle Cell Count. + @li 1 - Enable count of Idle cells transmitted. + @li 0 - No count is maintained. */ + + unsigned int enbTxCellCnt:1; /**< [16] Enable Transmit Valid Cell Count of non-idle/non-error cells + @li 1 - Enable count of valid cells transmitted- non-idle/non-error + @li 0 - No count is maintained.*/ + + unsigned int reserved_2:16; /**< [15:0] These bits are always 0 */ + } utTxEnableFields; /**< Tx enable Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable0_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable0_ + { + + unsigned int phy0:5; /**< [31-27] Tx Mapping value of logical phy 0 */ + + unsigned int phy1:5; /**< [26-22] Tx Mapping value of logical phy 1 */ + + unsigned int phy2:5; /**< [21-17] Tx Mapping value of logical phy 2 */ + + unsigned int reserved_1:1; /**< [16] These bits are always 0.*/ + + unsigned int phy3:5; /**< [15-11] Tx Mapping value of logical phy 3 */ + + unsigned int phy4:5; /**< [10-6] Tx Mapping value of logical phy 4 */ + + unsigned int phy5:5; /**< [5-1] Tx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utTxTransTable0; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable1_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable1_ + { + + unsigned int phy6:5; /**< [31-27] Tx Mapping value of logical phy 6 */ + + unsigned int phy7:5; /**< [26-22] Tx Mapping value of logical phy 7 */ + + unsigned int phy8:5; /**< [21-17] Tx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy9:5; /**< [15-11] Tx Mapping value of logical phy 3 */ + + unsigned int phy10:5; /**< [10-6] Tx Mapping value of logical phy 4 */ + + unsigned int phy11:5; /**< [5-1] Tx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utTxTransTable1; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable2_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable2_ + { + + unsigned int phy12:5; /**< [31-27] Tx Mapping value of logical phy 6 */ + + unsigned int phy13:5; /**< [26-22] Tx Mapping value of logical phy 7 */ + + unsigned int phy14:5; /**< [21-17] Tx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy15:5; /**< [15-11] Tx Mapping value of logical phy 3 */ + + unsigned int phy16:5; /**< [10-6] Tx Mapping value of logical phy 4 */ + + unsigned int phy17:5; /**< [5-1] Tx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utTxTransTable2; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable3_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable3_ + { + + unsigned int phy18:5; /**< [31-27] Tx Mapping value of logical phy 6 */ + + unsigned int phy19:5; /**< [26-22] Tx Mapping value of logical phy 7 */ + + unsigned int phy20:5; /**< [21-17] Tx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy21:5; /**< [15-11] Tx Mapping value of logical phy 3 */ + + unsigned int phy22:5; /**< [10-6] Tx Mapping value of logical phy 4 */ + + unsigned int phy23:5; /**< [5-1] Tx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utTxTransTable3; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable4_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable4_ + { + + unsigned int phy24:5; /**< [31-27] Tx Mapping value of logical phy 6 */ + + unsigned int phy25:5; /**< [26-22] Tx Mapping value of logical phy 7 */ + + unsigned int phy26:5; /**< [21-17] Tx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy27:5; /**< [15-11] Tx Mapping value of logical phy 3 */ + + unsigned int phy28:5; /**< [10-6] Tx Mapping value of logical phy 4 */ + + unsigned int phy29:5; /**< [5-1] Tx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utTxTransTable4; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxTransTable5_ + * @brief Utopia Tx translation table Register + */ + struct UtTxTransTable5_ + { + + unsigned int phy30:5; /**< [31-27] Tx Mapping value of logical phy 6 */ + + unsigned int reserved_1:27; /**< [26-0] These bits are always 0 */ + + } utTxTransTable5; /**< Tx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxConfig_ + * @brief Utopia Rx config Register + */ + struct UtRxConfig_ + { + + unsigned int rxInterface:1; /**< [31] Utopia Receive Interface. The following encoding is used + to set the Utopia Receive interface as ATM master or PHY slave: + @li 1 - PHY + @li 0 - ATM */ + + unsigned int rxMode:1; /**< [30] Utopia Receive Mode. The following encoding is used to set + the Utopia Receive mode to SPHY or MPHY: + @li 1 - SPHY + @li 0 - MPHY */ + + unsigned int rxOctet:1; /**< [29] Utopia Receive cell transfer protocol. Used to set the Utopia + cell transfer protocol to Octet-level handshaking. Note this is only + applicable in SPHY mode. + @li 1 - Octet-handshaking enabled + @li 0 - Cell-handshaking enabled */ + + unsigned int rxParity:1; /**< [28] Utopia Receive Parity Checking enable. + @li 1 - Parity checking enabled + @li 0 - Parity checking disabled */ + + unsigned int rxEvenParity:1;/**< [27] Utopia Receive Parity Mode + @li 1 - Check for Even Parity + @li 0 - Check for Odd Parity.*/ + + unsigned int rxHEC:1; /**< [26] RxHEC Header Error Check Mode. Enables/disables cell header + error checking on the received cell header. + @li 1 - HEC checking enabled + @li 0 - HEC checking disabled */ + + unsigned int rxCOSET:1; /**< [25] If enabled the HEC is Exclusive-OR'ed with the value 0x55 + before being tested with the received HEC. + @li 1 - Enable HEC ExOR with value 0x55. + @li 0 - Use generated HEC value.*/ + + unsigned int rxHECpass:1; /**< [24] Specifies if the incoming cell HEC byte should be transferred + after optional processing to the NPE2 Coprocessor Bus Interface or + if it should be discarded. + @li 1 - HEC maintained 53-byte/UDC cell sent to NPE2. + @li 0 - HEC discarded 52-byte/UDC cell sent to NPE2 coprocessor.*/ + + unsigned int reserved_1:1; /**< [23] These bits are always 0 */ + + unsigned int rxCellSize:7; /**< [22:16] Receive cell size. Configures the receive cell size. + Values between 52-64 are valid */ + + unsigned int rxHashEnbGFC:1; /**< [15] Specifies if the VPI field [11:8]/GFC field should be + included in the Hash data input or if the bits should be padded + with 1'b0. + @li 1 - VPI [11:8]/GFC field valid and used in Hash residue calculation. + @li 0 - VPI [11:8]/GFC field padded with 1'b0 */ + + unsigned int rxPreHash:1; /**< [14] Enable Pre-hash value generation. Specifies if the + incoming cell data should be pre-hashed to allow VPI/VCI header look-up + in a hash table. + @li 1 - Pre-hashing enabled + @li 0 - Pre-hashing disabled */ + + unsigned int reserved_2:1; /**< [13] These bits are always 0 */ + + unsigned int rxAddrRange:5; /**< [12:8] In ATM master, MPHY mode, + * this register specifies the upper + * limit of the PHY polling logical range. The number of active PHYs are + * RxAddrRange + 1. + */ + unsigned int reserved_3:3; /**< [7-5] These bits are always 0 .*/ + unsigned int rxPHYAddr:5; /**< [4:0] When configured as a slave in an MPHY system this register + * specifies the physical address of the PHY. + */ + } utRxConfig; /**< Rx config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxStatsConfig_ + * @brief Utopia Rx stats config Register + */ + struct UtRxStatsConfig_ + { + + unsigned int vpi:12; /**< [31:20] ATM VPI VPI [11:0] OR GFC [3:0] and VPI [7:0] + @li Note: if VCStatsRxGFC is set to 0 the GFC field is ignored in test. */ + + unsigned int vci:16; /**< [19:4] VCI [15:0] or PHY Address [4] */ + + unsigned int pti:3; /**< [3:1] PTI [2:0] or or PHY Address [3:1] + @li Note: if VCStatsRxPTI is set to 0 the PTI field is ignored in test. + @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used + for statistics gathering.. */ + + unsigned int clp:1; /**< [0] CLP [0] or PHY Address [0] + @li Note: if VCStatsRxCLP is set to 0 the CLP field is ignored in test. + @li Note: if VCStatsRxEnb is set to 0 only the PHY port address is used + for statistics gathering.. */ + } utRxStatsConfig; /**< Rx stats config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxDefineIdle_ + * @brief Utopia Rx idle cells config Register + */ + struct UtRxDefineIdle_ + { + + unsigned int vpi:12; /**< [31:20] ATM VPI [11:0] OR GFC [3:0] and VPI [7:0] + @li Note: if VCIdleRxGFC is set to 0 the GFC field is ignored in test. */ + + unsigned int vci:16; /**< [19:4] ATM VCI [15:0] */ + + unsigned int pti:3; /**< [3:1] ATM PTI PTI [2:0] + @li Note: if VCIdleRxPTI is set to 0 the PTI field is ignored in test.*/ + + unsigned int clp:1; /**< [0] ATM CLP [0] + @li Note: if VCIdleRxCLP is set to 0 the CLP field is ignored in test.*/ + } utRxDefineIdle; /**< Rx idle cell config Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxEnableFields_ + * @brief Utopia Rx enable Register + */ + struct UtRxEnableFields_ + { + + unsigned int defineRxIdleGFC:1;/**< [31] This register is used to include or exclude the GFC + field of the ATM header when testing for Idle cells. + @li 1 - GFC field is valid. + @li 0 - GFC field ignored.*/ + + unsigned int defineRxIdlePTI:1;/**< [30] This register is used to include or exclude the PTI + field of the ATM header when testing for Idle cells. + @li 1 - PTI field is valid. + @li 0 - PTI field ignored.*/ + + unsigned int defineRxIdleCLP:1;/**< [29] This register is used to include or exclude the CLP + field of the ATM header when testing for Idle cells. + @li 1 - CLP field is valid. + @li 0 - CLP field ignored.*/ + + unsigned int phyStatsRxEnb:1;/**< [28] This register is used to enable or disable ATM statistics + gathering based on the specified PHY address as defined in RxStatsConfig + register. + @li 1 - Enable statistics for specified receive PHY address. + @li 0 - Disable statistics for specified receive PHY address.*/ + + unsigned int vcStatsRxEnb:1;/**< [27] This register is used to enable or disable ATM statistics + gathering based on a specific VPI/VCI address. + @li 1 - Enable statistics for specified VPI/VCI address. + @li 0 - Disable statistics for specified VPI/VCI address.*/ + + unsigned int vcStatsRxGFC:1;/**< [26] This register is used to include or exclude the GFC field + of the ATM header when ATM VPI/VCI statistics are enabled. GFC is only + available at the UNI and uses the first 4-bits of the VPI field. + @li 1 - GFC field is valid. + @li 0 - GFC field ignored. */ + + unsigned int vcStatsRxPTI:1;/**< [25] This register is used to include or exclude the PTI field + of the ATM header when ATM VPI/VCI statistics are enabled. + @li 1 - PTI field is valid. + @li 0 - PTI field ignored.*/ + + unsigned int vcStatsRxCLP:1;/**< [24] This register is used to include or exclude the CLP field + of the ATM header when ATM VPI/VCI statistics are enabled. + @li 1 - CLP field is valid. + @li 0 - CLP field ignored. */ + + unsigned int discardHecErr:1;/**< [23] Discard cells with an invalid HEC. + @li 1 - Discard cells with HEC errors + @li 0 - Cells with HEC errors are passed */ + + unsigned int discardParErr:1;/**< [22] Discard cells containing parity errors. + @li 1 - Discard cells with parity errors + @li 0 - Cells with parity errors are passed */ + + unsigned int discardIdle:1; /**< [21] Discard Idle Cells based on DefineIdle register values + @li 1 - Discard IDLE cells + @li 0 - IDLE cells passed */ + + unsigned int enbHecErrCnt:1;/**< [20] Enable Receive HEC Error Count. + @li 1 - Enable count of received cells containing HEC errors + @li 0 - No count is maintained. */ + + unsigned int enbParErrCnt:1;/**< [19] Enable Parity Error Count + @li 1 - Enable count of received cells containing Parity errors + @li 0 - No count is maintained. */ + + unsigned int enbIdleCellCnt:1;/**< [18] Enable Receive Idle Cell Count. + @li 1 - Enable count of Idle cells received. + @li 0 - No count is maintained.*/ + + unsigned int enbSizeErrCnt:1;/**< [17] Enable Receive Size Error Count. + @li 1 - Enable count of received cells of incorrect size + @li 0 - No count is maintained. */ + + unsigned int enbRxCellCnt:1;/**< [16] Enable Receive Valid Cell Count of non-idle/non-error cells. + @li 1 - Enable count of valid cells received - non-idle/non-error + @li 0 - No count is maintained. */ + + unsigned int reserved_1:3; /**< [15:13] These bits are always 0 */ + + unsigned int rxCellOvrInt:1; /**< [12] Enable CBI Utopia Receive Status Condition if the RxCellCount + register overflows. + @li 1 - CBI Receive Status asserted. + @li 0 - No CBI Receive Status asserted.*/ + + unsigned int invalidHecOvrInt:1; /**< [11] Enable CBI Receive Status Condition if the InvalidHecCount + register overflows. + @li 1 - CBI Receive Condition asserted. + @li 0 - No CBI Receive Condition asserted */ + + unsigned int invalidParOvrInt:1; /**< [10] Enable CBI Receive Status Condition if the InvalidParCount + register overflows + @li 1 - CBI Receive Condition asserted. + @li 0 - No CBI Receive Condition asserted */ + + unsigned int invalidSizeOvrInt:1; /**< [9] Enable CBI Receive Status Condition if the InvalidSizeCount + register overflows. + @li 1 - CBI Receive Status Condition asserted. + @li 0 - No CBI Receive Status asserted */ + + unsigned int rxIdleOvrInt:1; /**< [8] Enable CBI Receive Status Condition if the RxIdleCount overflows. + @li 1 - CBI Receive Condition asserted. + @li 0 - No CBI Receive Condition asserted */ + + unsigned int reserved_2:3; /**< [7:5] These bits are always 0 */ + + unsigned int rxAddrMask:5; /**< [4:0] This register is used as a mask to allow the user to increase + the PHY receive address range. The register should be programmed with + the address-range limit, i.e. if set to 0x3 the address range increases + to a maximum of 4 addresses. */ + } utRxEnableFields; /**< Rx enable Utopia register */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable0_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable0_ + { + + unsigned int phy0:5; /**< [31-27] Rx Mapping value of logical phy 0 */ + + unsigned int phy1:5; /**< [26-22] Rx Mapping value of logical phy 1 */ + + unsigned int phy2:5; /**< [21-17] Rx Mapping value of logical phy 2 */ + + unsigned int reserved_1:1; /**< [16] These bits are always 0 */ + + unsigned int phy3:5; /**< [15-11] Rx Mapping value of logical phy 3 */ + + unsigned int phy4:5; /**< [10-6] Rx Mapping value of logical phy 4 */ + + unsigned int phy5:5; /**< [5-1] Rx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } + + utRxTransTable0; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable1_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable1_ + { + + unsigned int phy6:5; /**< [31-27] Rx Mapping value of logical phy 6 */ + + unsigned int phy7:5; /**< [26-22] Rx Mapping value of logical phy 7 */ + + unsigned int phy8:5; /**< [21-17] Rx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy9:5; /**< [15-11] Rx Mapping value of logical phy 3 */ + + unsigned int phy10:5; /**< [10-6] Rx Mapping value of logical phy 4 */ + + unsigned int phy11:5; /**< [5-1] Rx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } + + utRxTransTable1; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable2_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable2_ + { + + unsigned int phy12:5; /**< [31-27] Rx Mapping value of logical phy 6 */ + + unsigned int phy13:5; /**< [26-22] Rx Mapping value of logical phy 7 */ + + unsigned int phy14:5; /**< [21-17] Rx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy15:5; /**< [15-11] Rx Mapping value of logical phy 3 */ + + unsigned int phy16:5; /**< [10-6] Rx Mapping value of logical phy 4 */ + + unsigned int phy17:5; /**< [5-1] Rx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utRxTransTable2; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable3_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable3_ + { + + unsigned int phy18:5; /**< [31-27] Rx Mapping value of logical phy 6 */ + + unsigned int phy19:5; /**< [26-22] Rx Mapping value of logical phy 7 */ + + unsigned int phy20:5; /**< [21-17] Rx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy21:5; /**< [15-11] Rx Mapping value of logical phy 3 */ + + unsigned int phy22:5; /**< [10-6] Rx Mapping value of logical phy 4 */ + + unsigned int phy23:5; /**< [5-1] Rx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utRxTransTable3; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable4_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable4_ + { + + unsigned int phy24:5; /**< [31-27] Rx Mapping value of logical phy 6 */ + + unsigned int phy25:5; /**< [26-22] Rx Mapping value of logical phy 7 */ + + unsigned int phy26:5; /**< [21-17] Rx Mapping value of logical phy 8 */ + + unsigned int reserved_1:1; /**< [16-0] These bits are always 0 */ + + unsigned int phy27:5; /**< [15-11] Rx Mapping value of logical phy 3 */ + + unsigned int phy28:5; /**< [10-6] Rx Mapping value of logical phy 4 */ + + unsigned int phy29:5; /**< [5-1] Rx Mapping value of logical phy 5 */ + + unsigned int reserved_2:1; /**< [0] These bits are always 0 */ + } utRxTransTable4; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxTransTable5_ + * @brief Utopia Rx translation table Register + */ + struct UtRxTransTable5_ + { + + unsigned int phy30:5; /**< [31-27] Rx Mapping value of logical phy 6 */ + + unsigned int reserved_1:27; /**< [26-0] These bits are always 0 */ + + } utRxTransTable5; /**< Rx translation table */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtSysConfig_ + * @brief NPE setup Register + */ + struct UtSysConfig_ + { + + unsigned int reserved_1:2; /**< [31-30] These bits are always 0 */ + unsigned int txEnbFSM:1; /**< [29] Enables the operation ofthe Utopia Transmit FSM + * @li 1 - FSM enabled + * @li 0 - FSM inactive + */ + unsigned int rxEnbFSM:1; /**< [28] Enables the operation ofthe Utopia Revieve FSM + * @li 1 - FSM enabled + * @li 0 - FSM inactive + */ + unsigned int disablePins:1; /**< [27] Disable Utopia interface I/O pins forcing the signals to an + * inactive state. Note that this bit is set on reset and must be + * de-asserted + * @li 0 - Normal data transfer + * @li 1 - Utopia interface pins are forced inactive + */ + unsigned int tstLoop:1; /**< [26] Test Loop Back Enable. + * @li Note: For loop back to function RxMode and Tx Mode must both be set + * to single PHY mode. + * @li 0 - Loop back + * @li 1 - Normal operating mode + */ + + unsigned int txReset:1; /**< [25] Resets the Utopia Coprocessor transmit module to a known state. + * @li Note: All transmit configuration and status registers will be reset + * to their reset values. + * @li 0 - Normal operating mode + * @li 1 - Reset transmit modules + */ + + unsigned int rxReset:1; /**< [24] Resets the Utopia Coprocessor receive module to a known state. + * @li Note: All receive configuration and status registers will be reset + * to their reset values. + * @li 0 - Normal operating mode + * @li 1 - Reset receive modules + */ + + unsigned int reserved_2:24; /**< [23-0] These bits are always 0 */ + } utSysConfig; /**< NPE debug config */ + +} +IxAtmdAccUtopiaConfig; + +/** +* +* @brief Utopia status +* +* This structure is used to set/get the Utopia status parameters +* @li contains debug cell counters, to be accessed during a read operation +* +* @note - the exact description of all parameters is done in the Utopia reference +* documents. +* +*/ +typedef struct +{ + + unsigned int utTxCellCount; /**< count of cells transmitted */ + + unsigned int utTxIdleCellCount; /**< count of idle cells transmitted */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtTxCellConditionStatus_ + * @brief Utopia Tx Status Register + */ + struct UtTxCellConditionStatus_ + { + + unsigned int reserved_1:2; /**< [31:30] These bits are always 0 */ + unsigned int txFIFO2Underflow:1; /**< [29] This bit is set if 64-byte + * Transmit FIFO2 indicates a FIFO underflow + * error condition. + */ + unsigned int txFIFO1Underflow:1; /**< [28] This bit is set if + * 64-byte Transmit FIFO1 indicates a FIFO + * underflow error condition. + */ + unsigned int txFIFO2Overflow:1; /**< [27] This bit is set if 64-byte + * Transmit FIFO2 indicates a FIFO overflow + * error condition. + */ + unsigned int txFIFO1Overflow:1; /**< [26] This bit is set if 64-byte + * Transmit FIFO1 indicates a FIFO overflow + * error condition. + */ + unsigned int txIdleCellCountOvr:1; /**< [25] This bit is set if the + * TxIdleCellCount register overflows. + */ + unsigned int txCellCountOvr:1; /**< [24] This bit is set if the + * TxCellCount register overflows + */ + unsigned int reserved_2:24; /**< [23:0] These bits are always 0 */ + } utTxCellConditionStatus; /**< Tx cells condition status */ + + unsigned int utRxCellCount; /**< count of cell received */ + unsigned int utRxIdleCellCount; /**< count of idle cell received */ + unsigned int utRxInvalidHECount; /**< count of invalid cell + * received because of HEC errors + */ + unsigned int utRxInvalidParCount; /**< count of invalid cell received + * because of parity errors + */ + unsigned int utRxInvalidSizeCount; /**< count of invalid cell + * received because of cell + * size errors + */ + + /** + * @ingroup IxAtmdAccUtopiaCtrlAPI + * @struct UtRxCellConditionStatus_ + * @brief Utopia Rx Status Register + */ + struct UtRxCellConditionStatus_ + { + + unsigned int reserved_1:3; /**< [31:29] These bits are always 0.*/ + unsigned int rxCellCountOvr:1; /**< [28] This bit is set if the RxCellCount register overflows. */ + unsigned int invalidHecCountOvr:1; /**< [27] This bit is set if the InvalidHecCount register overflows.*/ + unsigned int invalidParCountOvr:1; /**< [26] This bit is set if the InvalidParCount register overflows.*/ + unsigned int invalidSizeCountOvr:1; /**< [25] This bit is set if the InvalidSizeCount register overflows.*/ + unsigned int rxIdleCountOvr:1; /**< [24] This bit is set if the RxIdleCount register overflows.*/ + unsigned int reserved_2:4; /**< [23:20] These bits are always 0 */ + unsigned int rxFIFO2Underflow:1; /**< [19] This bit is set if 64-byte Receive FIFO2 + * indicates a FIFO underflow error condition. + */ + unsigned int rxFIFO1Underflow:1; /**< [18] This bit is set if 64-byte Receive + * FIFO1 indicates a FIFO underflow error condition + . */ + unsigned int rxFIFO2Overflow:1; /**< [17] This bit is set if 64-byte Receive FIFO2 + * indicates a FIFO overflow error condition. + */ + unsigned int rxFIFO1Overflow:1; /**< [16] This bit is set if 64-byte Receive FIFO1 + * indicates a FIFO overflow error condition. + */ + unsigned int reserved_3:16; /**< [15:0] These bits are always 0. */ + } utRxCellConditionStatus; /**< Rx cells condition status */ + +} IxAtmdAccUtopiaStatus; + +/** + * @} defgroup IxAtmdAccUtopiaCtrlAPI + */ + + /** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig * + ixAtmdAccUtopiaConfigPtr) + * + * @brief Send the configuration structure to the Utopia interface + * + * This function downloads the @a IxAtmdAccUtopiaConfig structure to + * the Utopia and has the following effects + * @li setup the Utopia interface + * @li initialise the NPE + * @li reset the Utopia cell counters and status registers to known values + * + * This action has to be done once at initialisation. A lock is preventing + * the concurrent use of @a ixAtmdAccUtopiaStatusGet() and + * @A ixAtmdAccUtopiaConfigSet() + * + * @param *ixAtmdAccNPEConfigPtr @ref IxAtmdAccUtopiaConfig [in] - pointer to a structure to download to + * Utopia. This parameter cannot be a null pointer. + * + * @return @li IX_SUCCESS successful download + * @return @li IX_FAIL error in the parameters, or configuration is not + * complete or failed + * + * @sa ixAtmdAccUtopiaStatusGet + * + */ +PUBLIC IX_STATUS ixAtmdAccUtopiaConfigSet (const IxAtmdAccUtopiaConfig * + ixAtmdAccUtopiaConfigPtr); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus * + ixAtmdAccUtopiaStatus) + * + * @brief Get the Utopia interface configuration. + * + * This function reads the Utopia registers and the Cell counts + * and fills the @a IxAtmdAccUtopiaStatus structure + * + * A lock is preventing the concurrent + * use of @a ixAtmdAccUtopiaStatusGet() and @A ixAtmdAccUtopiaConfigSet() + * + * @param ixAtmdAccUtopiaStatus @ref IxAtmdAccUtopiaStatus [out] - pointer to structure to be updated from internal + * hardware counters. This parameter cannot be a NULL pointer. + * + * @return @li IX_SUCCESS successful read + * @return @li IX_FAIL error in the parameters null pointer, or + * configuration read is not complete or failed + * + * @sa ixAtmdAccUtopiaConfigSet + * + */ +PUBLIC IX_STATUS ixAtmdAccUtopiaStatusGet (IxAtmdAccUtopiaStatus * + ixAtmdAccUtopiaStatus); + +/** + * + * @ingroup IxAtmdAcc + * + * @fn ixAtmdAccPortEnable (IxAtmLogicalPort port) + * + * @brief enable a PHY logical port + * + * This function enables the transmission over one port. It should be + * called before accessing any resource from this port and before the + * establishment of a VC. + * + * When a port is enabled, the cell transmission to the Utopia interface + * is started. If there is no traffic already running, idle cells are + * sent over the interface. + * + * This function can be called multiple times. + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * + * @return @li IX_SUCCESS enable is complete + * @return @li IX_ATMDACC_WARNING port already enabled + * @return @li IX_FAIL enable failed, wrong parameter, or cannot + * initialise this port (the port is maybe already in use, + * or there is a hardware issue) + * + * @note - This function needs internal locks and should not be + * called from an interrupt context + * + * @sa ixAtmdAccPortDisable + * + */ +PUBLIC IX_STATUS ixAtmdAccPortEnable (IxAtmLogicalPort port); + +/** + * + * @ingroup IxAtmdAccCtrlAPI + * + * @fn ixAtmdAccPortDisable (IxAtmLogicalPort port) + * + * @brief disable a PHY logical port + * + * This function disable the transmission over one port. + * + * When a port is disabled, the cell transmission to the Utopia interface + * is stopped. + * + * @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] + * + * @return @li IX_SUCCESS disable is complete + * @return @li IX_ATMDACC_WARNING port already disabled + * @return @li IX_FAIL disable failed, wrong parameter . + * + * @note - This function needs internal locks and should not be called + * from an interrupt context + * + * @note - The response from hardware is done through the txDone mechanism + * to ensure the synchrnisation with tx resources. Therefore, the + * txDone mechanism needs to be serviced to make a PortDisable complete. + * + * @sa ixAtmdAccPortEnable + * @sa ixAtmdAccPortDisableComplete + * @sa ixAtmdAccTxDoneDispatch + * + */ +PUBLIC IX_STATUS ixAtmdAccPortDisable (IxAtmLogicalPort port); + +/** +* +* @ingroup IxAtmdAccCtrlAPI +* +* @fn ixAtmdAccPortDisableComplete (IxAtmLogicalPort port) +* +* @brief disable a PHY logical port +* +* This function indicates if the port disable for a port has completed. This +* function will return TRUE if the port has never been enabled. +* +* @param port @ref IxAtmLogicalPort [in] - logical PHY port [@a IX_UTOPIA_PORT_0 .. @a IX_UTOPIA_MAX_PORTS - 1] +* +* @return @li TRUE disable is complete +* @return @li FALSE disable failed, wrong parameter . +* +* @note - This function needs internal locks and should not be called +* from an interrupt context +* +* @sa ixAtmdAccPortEnable +* @sa ixAtmdAccPortDisable +* +*/ +PUBLIC BOOL ixAtmdAccPortDisableComplete (IxAtmLogicalPort port); + +#endif /* IXATMDACCCTRL_H */ + +/** + * @} defgroup IxAtmdAccCtrlAPI + */ + + diff --git a/drivers/net/npe/include/IxAtmm.h b/drivers/net/npe/include/IxAtmm.h new file mode 100644 index 0000000..fcf523f --- /dev/null +++ b/drivers/net/npe/include/IxAtmm.h @@ -0,0 +1,795 @@ +/** + * @file IxAtmm.h + * + * @date 3-DEC-2001 + * + * @brief Header file for the IXP400 ATM Manager component (IxAtmm) + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + + +/** + * @defgroup IxAtmm IXP400 ATM Manager (IxAtmm) API + * + * @brief IXP400 ATM Manager component Public API + * + * @{ + */ + +#ifndef IXATMM_H +#define IXATMM_H + +/* + * Put the user defined include files required + */ +#include "IxAtmSch.h" +#include "IxOsalTypes.h" + +/* + * #defines and macros used in this file. + */ + +/** + * @def IX_ATMM_RET_ALREADY_INITIALIZED + * + * @brief Component has already been initialized + */ +#define IX_ATMM_RET_ALREADY_INITIALIZED 2 + +/** + * @def IX_ATMM_RET_INVALID_PORT + * + * @brief Specified port does not exist or is out of range */ +#define IX_ATMM_RET_INVALID_PORT 3 + +/** + * @def IX_ATMM_RET_INVALID_VC_DESCRIPTOR + * + * @brief The VC description does not adhere to ATM standards */ +#define IX_ATMM_RET_INVALID_VC_DESCRIPTOR 4 + +/** + * @def IX_ATMM_RET_VC_CONFLICT + * + * @brief The VPI/VCI values supplied are either reserved, or they + * conflict with a previously registered VC on this port */ +#define IX_ATMM_RET_VC_CONFLICT 5 + +/** + * @def IX_ATMM_RET_PORT_CAPACITY_IS_FULL + * + * @brief The virtual connection cannot be established on the port + * because the remaining port capacity is not sufficient to + * support it */ +#define IX_ATMM_RET_PORT_CAPACITY_IS_FULL 6 + +/** + * @def IX_ATMM_RET_NO_SUCH_VC + * + * @brief No registered VC, as described by the supplied VCI/VPI or + * VC identifier values, exists on this port */ +#define IX_ATMM_RET_NO_SUCH_VC 7 + +/** + * @def IX_ATMM_RET_INVALID_VC_ID + * + * @brief The specified VC identifier is out of range. */ +#define IX_ATMM_RET_INVALID_VC_ID 8 + +/** + * @def IX_ATMM_RET_INVALID_PARAM_PTR + * + * @brief A pointer parameter was NULL. */ +#define IX_ATMM_RET_INVALID_PARAM_PTR 9 + +/** + * @def IX_ATMM_UTOPIA_SPHY_ADDR + * + * @brief The phy address when in SPHY mode */ +#define IX_ATMM_UTOPIA_SPHY_ADDR 31 + +/** + * @def IX_ATMM_THREAD_PRI_HIGH + * + * @brief The value of high priority thread */ +#define IX_ATMM_THREAD_PRI_HIGH 90 + +/* + * Typedefs whose scope is limited to this file. + */ + +/** @brief Definition for use in the @ref IxAtmmVc structure. + * Indicates the direction of a VC */ +typedef enum +{ + IX_ATMM_VC_DIRECTION_TX=0, /**< Atmm Vc direction transmit*/ + IX_ATMM_VC_DIRECTION_RX, /**< Atmm Vc direction receive*/ + IX_ATMM_VC_DIRECTION_INVALID /**< Atmm Vc direction invalid*/ +} IxAtmmVcDirection; + +/** @brief Definition for use with @ref IxAtmmVcChangeCallback + * callback. Indicates that the event type represented by the + * callback for this VC. */ +typedef enum +{ + IX_ATMM_VC_CHANGE_EVENT_REGISTER=0, /**< Atmm Vc event register*/ + IX_ATMM_VC_CHANGE_EVENT_DEREGISTER, /**< Atmm Vc event de-register*/ + IX_ATMM_VC_CHANGE_EVENT_INVALID /**< Atmm Vc event invalid*/ +} IxAtmmVcChangeEvent; + +/** @brief Definitions for use with @ref ixAtmmUTOPIAInit interface to + * indicate that UTOPIA loopback should be enabled or disabled + * on initialisation. */ +typedef enum +{ + IX_ATMM_UTOPIA_LOOPBACK_DISABLED=0, /**< Atmm Utopia loopback mode disabled*/ + IX_ATMM_UTOPIA_LOOPBACK_ENABLED, /**< Atmm Utopia loopback mode enabled*/ + IX_ATMM_UTOPIA_LOOPBACK_INVALID /**< Atmm Utopia loopback mode invalid*/ +} IxAtmmUtopiaLoopbackMode; + +/** @brief This structure describes the required attributes of a + * virtual connection. +*/ +typedef struct { + unsigned vpi; /**< VPI value of this virtual connection */ + unsigned vci; /**< VCI value of this virtual connection. */ + IxAtmmVcDirection direction; /**< VC direction */ + + /** Traffic descriptor of this virtual connection. This structure + * is defined by the @ref IxAtmSch component. */ + IxAtmTrafficDescriptor trafficDesc; +} IxAtmmVc; + + +/** @brief Definitions for use with @ref ixAtmmUtopiaInit interface to + * indicate that UTOPIA multi-phy/single-phy mode is used. + */ +typedef enum +{ + IX_ATMM_MPHY_MODE = 0, /**< Atmm phy mode mphy*/ + IX_ATMM_SPHY_MODE, /**< Atmm phy mode sphy*/ + IX_ATMM_PHY_MODE_INVALID /**< Atmm phy mode invalid*/ +} IxAtmmPhyMode; + + +/** @brief Structure contains port-specific information required to + * initialize IxAtmm, and specifically, the IXP400 UTOPIA + * Level-2 device. */ +typedef struct { + unsigned reserved_1:11; /**< [31:21] Should be zero */ + unsigned UtopiaTxPhyAddr:5; /**< [20:16] Address of the + * transmit (Tx) PHY for this + * port on the 5-bit UTOPIA + * Level-2 address bus */ + unsigned reserved_2:11; /**< [15:5] Should be zero */ + unsigned UtopiaRxPhyAddr:5; /**< [4:0] Address of the receive + * (Rx) PHY for this port on the + * 5-bit UTOPIA Level-2 + * address bus */ +} IxAtmmPortCfg; + +/** @brief Callback type used with @ref ixAtmmVcChangeCallbackRegister interface + * Defines a callback type which will be used to notify registered + * users of registration/deregistration events on a particular port + * + * @param eventType @ref IxAtmmVcChangeEvent [in] - Event indicating + * whether the VC supplied has been added or + * removed + * + * @param port @ref IxAtmLogicalPort [in] - Specifies the port on which the event has + * occurred + * + * @param vcChanged @ref IxAtmmVc* [in] - Pointer to a structure which gives + * details of the VC which has been added + * or removed on the port + */ +typedef void (*IxAtmmVcChangeCallback) (IxAtmmVcChangeEvent eventType, + IxAtmLogicalPort port, + const IxAtmmVc* vcChanged); + +/* + * Variable declarations global to this file only. Externs are followed by + * static variables. + */ + +/* + * Extern function prototypes + */ + +/* + * Function declarations + */ + + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmInit (void) + * + * @brief Interface to initialize the IxAtmm software component. Can + * be called once only. + * + * Must be called before any other IxAtmm API is called. + * + * @param "none" + * + * @return @li IX_SUCCESS : IxAtmm has been successfully initialized. + * Calls to other IxAtmm interfaces may now be performed. + * @return @li IX_FAIL : IxAtmm has already been initialized. + */ +PUBLIC IX_STATUS +ixAtmmInit (void); + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmUtopiaInit (unsigned numPorts, + IxAtmmPhyMode phyMode, + IxAtmmPortCfg portCfgs[], + IxAtmmUtopiaLoopbackMode loopbackMode) + * + * @brief Interface to initialize the UTOPIA Level-2 ATM coprocessor + * for the specified number of physical ports. The function + * must be called before the ixAtmmPortInitialize interface + * can operate successfully. + * + * @param numPorts unsigned [in] - Indicates the total number of logical + * ports that are active on the device. Up to 12 ports are + * supported. + * + * @param phyMode @ref IxAtmmPhyMode [in] - Put the Utopia coprocessor in SPHY + * or MPHY mode. + * + * @param portCfgs[] @ref IxAtmmPortCfg [in] - Pointer to an array of elements + * detailing the UTOPIA specific port characteristics. The + * length of the array must be equal to the number of ports + * activated. ATM ports are referred to by the relevant + * offset in this array in all subsequent IxAtmm interface + * calls. + * + * @param loopbackMode @ref IxAtmmUtopiaLoopbackMode [in] - Value must be one of + * @ref IX_ATMM_UTOPIA_LOOPBACK_ENABLED or @ref + * IX_ATMM_UTOPIA_LOOPBACK_DISABLED indicating whether + * loopback should be enabled on the device. Loopback can + * only be supported on a single PHY, therefore the numPorts + * parameter must be 1 if loopback is enabled. + * + * @return @li IX_SUCCESS : Indicates that the UTOPIA device has been + * successfully initialized for the supplied ports. + * @return @li IX_ATMM_RET_ALREADY_INITIALIZED : The UTOPIA device has + * already been initialized. + * @return @li IX_FAIL : The supplied parameters are invalid or have been + * rejected by the UTOPIA-NPE device. + * + * @warning + * This interface may only be called once. + * Port identifiers are assumed to range from 0 to (numPorts - 1) in all + * instances. + * In all subsequent calls to interfaces supplied by IxAtmm, the specified + * port value is expected to represent the offset in the portCfgs array + * specified in this interface. i.e. The first port in this array will + * subsequently be represented as port 0, the second port as port 1, + * and so on.*/ +PUBLIC IX_STATUS +ixAtmmUtopiaInit (unsigned numPorts, + IxAtmmPhyMode phyMode, + IxAtmmPortCfg portCfgs[], + IxAtmmUtopiaLoopbackMode loopbackMode); + + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmPortInitialize (IxAtmLogicalPort port, + unsigned txPortRate, + unsigned rxPortRate) + * + * @brief The interface is called following @ref ixAtmmUtopiaInit () + * and before calls to any other IxAtmm interface. It serves + * to activate the registered ATM port with IxAtmm. + * + * The transmit and receive port rates are specified in bits per + * second. This translates to ATM cells per second according to the + * following formula: CellsPerSecond = portRate / (53*8) The + * IXP400 device supports only 53 byte cells. The client shall make + * sure that the off-chip physical layer device has already been + * initialized. + * + * IxAtmm will configure IxAtmdAcc and IxAtmSch to enable scheduling + * on the port. + * + * This interface must be called once for each active port in the + * system. The first time the interface is invoked, it will configure + * the mechanism by which the handling of transmit, transmit-done and + * receive are driven with the IxAtmdAcc component. + * + * This function is reentrant. + * + * @note The minimum tx rate that will be accepted is 424 bit/s which equates + * to 1 cell (53 bytes) per second. + * + * @param port @ref IxAtmLogicalPort [in] - Identifies the port which is to be + * initialized. + * + * @param txPortRate unsigned [in] - Value specifies the + * transmit port rate for this port in + * bits/second. This value is used by the ATM Scheduler + * component is evaluating VC access requests for the port. + * + * @param rxPortRate unsigned [in] - Value specifies the + * receive port rate for this port in bits/second. + * + * @return @li IX_SUCCESS : The specificed ATM port has been successfully + * initialized. IxAtmm is ready to accept VC registrations on + * this port. + * + * @return @li IX_ATMM_RET_ALREADY_INITIALIZED : ixAtmmPortInitialize has + * already been called successfully on this port. The current + * call is rejected. + * + * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the + * input is not valid. The request is rejected. + * + * @return @li IX_FAIL : IxAtmm could not initialize the port because the + * inputs are not understood. + * + * @sa ixAtmmPortEnable, ixAtmmPortDisable + * + */ +PUBLIC IX_STATUS +ixAtmmPortInitialize (IxAtmLogicalPort port, + unsigned txPortRate, + unsigned rxPortRate); + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmPortModify (IxAtmLogicalPort port, + unsigned txPortRate, + unsigned rxPortRate) + * + * @brief A client may call this interface to change the existing + * port rate (expressed in bits/second) on an established ATM + * port. + * + * @param port @ref IxAtmLogicalPort [in] - Identifies the port which is to be + * initialized. + * + * @param txPortRate unsigned [in] - Value specifies the`` + * transmit port rate for this port in + * bits/second. This value is used by the ATM Scheduler + * component is evaluating VC access requests for the port. + * + * @param rxPortRate unsigned [in] - Value specifies the + * receive port rate for this port in + * bits/second. + * + * @return @li IX_SUCCESS : The indicated ATM port rates have been + * successfully modified. + * + * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the + * input is not valid. The request is rejected. + * + * @return @li IX_FAIL : IxAtmm could not update the port because the + * inputs are not understood, or the interface was called before + * the port was initialized. */ +PUBLIC IX_STATUS +ixAtmmPortModify (IxAtmLogicalPort port, + unsigned txPortRate, + unsigned rxPortRate); + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmPortQuery (IxAtmLogicalPort port, + unsigned *txPortRate, + unsigned *rxPortRate); + + * + * @brief The client may call this interface to request details on + * currently registered transmit and receive rates for an ATM + * port. + * + * @param port @ref IxAtmLogicalPort [in] - Value identifies the port from which the + * rate details are requested. + * + * @param *txPortRate unsigned [out] - Pointer to a value + * which will be filled with the value of the transmit port + * rate specified in bits/second. + * + * @param *rxPortRate unsigned [out] - Pointer to a value + * which will be filled with the value of the receive port + * rate specified in bits/second. + * + * @return @li IX_SUCCESS : The information requested on the specified + * port has been successfully supplied in the output. + * + * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the + * input is not valid. The request is rejected. + * + * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was + * NULL. + * + * @return @li IX_FAIL : IxAtmm could not update the port because the + * inputs are not understood, or the interface was called before + * the port was initialized. */ +PUBLIC IX_STATUS +ixAtmmPortQuery (IxAtmLogicalPort port, + unsigned *txPortRate, + unsigned *rxPortRate); + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmPortEnable(IxAtmLogicalPort port) + * + * @brief The client call this interface to enable transmit for an ATM + * port. At initialisation, all the ports are disabled. + * + * @param port @ref IxAtmLogicalPort [in] - Value identifies the port + * + * @return @li IX_SUCCESS : Transmission over this port is started. + * + * @return @li IX_FAIL : The port parameter is not valid, or the + * port is already enabled + * + * @note - When a port is disabled, Rx and Tx VC Connect requests will fail + * + * @note - This function uses system resources and should not be used + * inside an interrupt context. + * + * @sa ixAtmmPortDisable */ +PUBLIC IX_STATUS +ixAtmmPortEnable(IxAtmLogicalPort port); + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmPortDisable(IxAtmLogicalPort port) + * + * @brief The client call this interface to disable transmit for an ATM + * port. At initialisation, all the ports are disabled. + * + * @param port @ref IxAtmLogicalPort [in] - Value identifies the port + * + * @return @li IX_SUCCESS : Transmission over this port is stopped. + * + * @return @li IX_FAIL : The port parameter is not valid, or the + * port is already disabled + * + * @note - When a port is disabled, Rx and Tx VC Connect requests will fail + * + * @note - This function call does not stop RX traffic. It is supposed + * that this function is invoked when a serious problem + * is detected (e.g. physical layer broken). Then, the RX traffic + * is not passing. + * + * @note - This function is blocking until the hw acknowledge that the + * transmission is stopped. + * + * @note - This function uses system resources and should not be used + * inside an interrupt context. + * + * @sa ixAtmmPortEnable */ +PUBLIC IX_STATUS +ixAtmmPortDisable(IxAtmLogicalPort port); + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmVcRegister (IxAtmLogicalPort port, + IxAtmmVc *vcToAdd, + IxAtmSchedulerVcId *vcId) + * + * @brief This interface is used to register an ATM Virtual + * Connection on the specified ATM port. + * + * Each call to this interface registers a unidirectional virtual + * connection with the parameters specified. If a bi-directional VC + * is needed, the function should be called twice (once for each + * direction, Tx & Rx) where the VPI and VCI and port parameters in + * each call are identical. + * + * With the addition of each new VC to a port, a series of + * callback functions are invoked by the IxAtmm component to notify + * possible external components of the change. The callback functions + * are registered using the @ref ixAtmmVcChangeCallbackRegister interface. + * + * The IxAtmSch component is notified of the registration of transmit + * VCs. + * + * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the specified VC is + * to be registered. + * + * @param *vcToAdd @ref IxAtmmVc [in] - Pointer to an @ref IxAtmmVc structure + * containing a description of the VC to be registered. The + * client shall fill the vpi, vci and direction and relevant + * trafficDesc members of this structure before calling this + * function. + * + * @param *vcId @ref IxAtmSchedulerVcId [out] - Pointer to an integer value which is filled + * with the per-port unique identifier value for this VC. + * This identifier will be required when a request is + * made to deregister or change this VC. VC identifiers + * for transmit VCs will have a value between 0-43, + * i.e. 32 data Tx VCs + 12 OAM Tx Port VCs. + * Receive VCs will have a value between 44-66, + * i.e. 32 data Rx VCs + 1 OAM Rx VC. + * + * @return @li IX_SUCCESS : The VC has been successfully registered on + * this port. The VC is ready for a client to configure IxAtmdAcc + * for receive and transmit operations on the VC. + * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the + * input is not valid or has not been initialized. The request + * is rejected. + * @return @li IX_ATMM_RET_INVALID_VC_DESCRIPTOR : The descriptor + * pointed to by vcToAdd is invalid. The registration request + * is rejected. + * @return @li IX_ATMM_RET_VC_CONFLICT : The VC requested conflicts with + * reserved VPI and/or VCI values or with another VC already activated + * on this port. + * @return @li IX_ATMM_RET_PORT_CAPACITY_IS_FULL : The VC cannot be + * registered in the port becuase the port capacity is + * insufficient to support the requested ATM traffic contract. + * The registration request is rejected. + * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was + * NULL. + * + * @warning IxAtmm has no capability of signaling or negotiating a virtual + * connection. Negotiation of the admission of the VC to the network + * is beyond the scope of this function. This is assumed to be + * performed by the calling client, if appropriate, + * before or after this function is called. + */ +PUBLIC IX_STATUS +ixAtmmVcRegister (IxAtmLogicalPort port, + IxAtmmVc *vcToAdd, + IxAtmSchedulerVcId *vcId); + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmVcDeregister (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId) + * + * @brief Function called by a client to deregister a VC from the + * system. + * + * With the removal of each new VC from a port, a series of + * registered callback functions are invoked by the IxAtmm component + * to notify possible external components of the change. The callback + * functions are registered using the @ref ixAtmmVcChangeCallbackRegister. + * + * The IxAtmSch component is notified of the removal of transmit VCs. + * + * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be + * removed is currently registered. + * + * @param vcId @ref IxAtmSchedulerVcId [in] - VC identifier value of the VC to + * be deregistered. This value was supplied to the client when + the VC was originally registered. This value can also be + queried from the IxAtmm component through the @ref ixAtmmVcQuery + * interface. + * + * @return @li IX_SUCCESS : The specified VC has been successfully + * removed from this port. + * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the + * input is not valid or has not been initialized. The request + * is rejected. + * @return @li IX_FAIL : There is no registered VC associated with the + * supplied identifier registered on this port. */ +PUBLIC IX_STATUS +ixAtmmVcDeregister (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId); + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmVcQuery (IxAtmLogicalPort port, + unsigned vpi, + unsigned vci, + IxAtmmVcDirection direction, + IxAtmSchedulerVcId *vcId, + IxAtmmVc *vcDesc) + * + * @brief This interface supplies information about an active VC on a + * particular port when supplied with the VPI, VCI and + * direction of that VC. + * + * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be + * queried is currently registered. + * + * @param vpi unsigned [in] - ATM VPI value of the requested VC. + * + * @param vci unsigned [in] - ATM VCI value of the requested VC. + * + * @param direction @ref IxAtmmVcDirection [in] - One of @ref + * IX_ATMM_VC_DIRECTION_TX or @ref IX_ATMM_VC_DIRECTION_RX + * indicating the direction (Tx or Rx) of the requested VC. + * + * @param *vcId @ref IxAtmSchedulerVcId [out] - Pointer to an integer value which will be + * filled with the VC identifier value for the requested + * VC (as returned by @ref ixAtmmVcRegister), if it + * exists on this port. + * + * @param *vcDesc @ref IxAtmmVc [out] - Pointer to an @ref IxAtmmVc structure + * which will be filled with the specific details of the + * requested VC, if it exists on this port. + * + * @return @li IX_SUCCESS : The specified VC has been found on this port + * and the requested details have been returned. + * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the + * input is not valid or has not been initialized. The request + * is rejected. + * @return @li IX_ATMM_RET_NO_SUCH_VC : No VC exists on the specified + * port which matches the search criteria (VPI, VCI, direction) + * given. No data is returned. + * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was + * NULL. + * + */ +PUBLIC IX_STATUS +ixAtmmVcQuery (IxAtmLogicalPort port, + unsigned vpi, + unsigned vci, + IxAtmmVcDirection direction, + IxAtmSchedulerVcId *vcId, + IxAtmmVc *vcDesc); + + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmVcIdQuery (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, IxAtmmVc *vcDesc) + * + * @brief This interface supplies information about an active VC on a + * particular port when supplied with a vcId for that VC. + * + * @param port @ref IxAtmLogicalPort [in] - Identifies port on which the VC to be + * queried is currently registered. + * + * @param vcId @ref IxAtmSchedulerVcId [in] - Value returned by @ref ixAtmmVcRegister which + * uniquely identifies the requested VC on this port. + * + * @param *vcDesc @ref IxAtmmVc [out] - Pointer to an @ref IxAtmmVc structure + * which will be filled with the specific details of the + * requested VC, if it exists on this port. + * + * @return @li IX_SUCCESS : The specified VC has been found on this port + * and the requested details have been returned. + * @return @li IX_ATMM_RET_INVALID_PORT : The port value indicated in the + * input is not valid or has not been initialized. The request + * is rejected. + * @return @li IX_ATMM_RET_NO_SUCH_VC : No VC exists on the specified + * port which matches the supplied identifier. No data is + * returned. + * @return @li IX_ATMM_RET_INVALID_PARAM_PTR : A pointer parameter was + * NULL. + */ +PUBLIC IX_STATUS +ixAtmmVcIdQuery (IxAtmLogicalPort port, IxAtmSchedulerVcId vcId, IxAtmmVc *vcDesc); + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmVcChangeCallbackRegister (IxAtmmVcChangeCallback callback) + * + * @brief This interface is invoked to supply a function to IxAtmm + * which will be called to notify the client if a new VC is + * registered with IxAtmm or an existing VC is removed. + * + * The callback, when invoked, will run within the context of the call + * to @ref ixAtmmVcRegister or @ref ixAtmmVcDeregister which caused + * the change of state. + * + * A maximum of 32 calbacks may be registered in with IxAtmm. + * + * @param callback @ref IxAtmmVcChangeCallback [in] - Callback which complies + * with the @ref IxAtmmVcChangeCallback definition. This + * function will be invoked by IxAtmm with the appropiate + * parameters for the relevant VC when any VC has been + * registered or deregistered with IxAtmm. + * + * @return @li IX_SUCCESS : The specified callback has been registered + * successfully with IxAtmm and will be invoked when appropriate. + * @return @li IX_FAIL : Either the supplied callback is invalid, or + * IxAtmm has already registered 32 and connot accommodate + * any further registrations of this type. The request is + * rejected. + * + * @warning The client must not call either the @ref + * ixAtmmVcRegister or @ref ixAtmmVcDeregister interfaces + * from within the supplied callback function. */ +PUBLIC IX_STATUS ixAtmmVcChangeCallbackRegister (IxAtmmVcChangeCallback callback); + + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmVcChangeCallbackDeregister (IxAtmmVcChangeCallback callback) + * + * @brief This interface is invoked to deregister a previously supplied + * callback function. + * + * @param callback @ref IxAtmmVcChangeCallback [in] - Callback which complies + * with the @ref IxAtmmVcChangeCallback definition. This + * function will removed from the table of callbacks. + * + * @return @li IX_SUCCESS : The specified callback has been deregistered + * successfully from IxAtmm. + * @return @li IX_FAIL : Either the supplied callback is invalid, or + * is not currently registered with IxAtmm. + */ +PUBLIC IX_STATUS +ixAtmmVcChangeCallbackDeregister (IxAtmmVcChangeCallback callback); + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmUtopiaStatusShow (void) + * + * @brief Display utopia status counters + * + * @param "none" + * + * @return @li IX_SUCCESS : Show function was successful + * @return @li IX_FAIL : Internal failure + */ +PUBLIC IX_STATUS +ixAtmmUtopiaStatusShow (void); + +/** + * @ingroup IxAtmm + * + * @fn ixAtmmUtopiaCfgShow (void) + * + * @brief Display utopia information(config registers and status registers) + * + * @param "none" + * + * @return @li IX_SUCCESS : Show function was successful + * @return @li IX_FAIL : Internal failure + */ +PUBLIC IX_STATUS +ixAtmmUtopiaCfgShow (void); + +#endif +/* IXATMM_H */ + +/** @} */ diff --git a/drivers/net/npe/include/IxDmaAcc.h b/drivers/net/npe/include/IxDmaAcc.h new file mode 100644 index 0000000..45c7527 --- /dev/null +++ b/drivers/net/npe/include/IxDmaAcc.h @@ -0,0 +1,260 @@ +/** + * @file IxDmaAcc.h + * + * @date 15 October 2002 + * + * @brief API of the IXP400 DMA Access Driver Component (IxDma) + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/*--------------------------------------------------------------------- + Doxygen group definitions + ---------------------------------------------------------------------*/ + +#ifndef IXDMAACC_H +#define IXDMAACC_H + +#include "IxOsal.h" +#include "IxNpeDl.h" +/** + * @defgroup IxDmaTypes IXP400 DMA Types (IxDmaTypes) + * @brief The common set of types used in the DMA component + * @{ + */ + +/** + * @ingroup IxDmaTypes + * @enum IxDmaReturnStatus + * @brief Dma return status definitions + */ +typedef enum +{ + IX_DMA_SUCCESS = IX_SUCCESS, /**< DMA Transfer Success */ + IX_DMA_FAIL = IX_FAIL, /**< DMA Transfer Fail */ + IX_DMA_INVALID_TRANSFER_WIDTH, /**< Invalid transfer width */ + IX_DMA_INVALID_TRANSFER_LENGTH, /**< Invalid transfer length */ + IX_DMA_INVALID_TRANSFER_MODE, /**< Invalid transfer mode */ + IX_DMA_INVALID_ADDRESS_MODE, /**< Invalid address mode */ + IX_DMA_REQUEST_FIFO_FULL /**< DMA request queue is full */ +} IxDmaReturnStatus; + +/** + * @ingroup IxDmaTypes + * @enum IxDmaTransferMode + * @brief Dma transfer mode definitions + * @note Copy and byte swap, and copy and reverse modes only support multiples of word data length. + */ +typedef enum +{ + IX_DMA_COPY_CLEAR = 0, /**< copy and clear source*/ + IX_DMA_COPY, /**< copy */ + IX_DMA_COPY_BYTE_SWAP, /**< copy and byte swap (endian) */ + IX_DMA_COPY_REVERSE, /**< copy and reverse */ + IX_DMA_TRANSFER_MODE_INVALID /**< Invalid transfer mode */ +} IxDmaTransferMode; + +/** + * @ingroup IxDmaTypes + * @enum IxDmaAddressingMode + * @brief Dma addressing mode definitions + * @note Fixed source address to fixed destination address addressing mode is not supported. + */ +typedef enum +{ + IX_DMA_INC_SRC_INC_DST = 0, /**< Incremental source address to incremental destination address */ + IX_DMA_INC_SRC_FIX_DST, /**< Incremental source address to incremental destination address */ + IX_DMA_FIX_SRC_INC_DST, /**< Incremental source address to incremental destination address */ + IX_DMA_FIX_SRC_FIX_DST, /**< Incremental source address to incremental destination address */ + IX_DMA_ADDRESSING_MODE_INVALID /**< Invalid Addressing Mode */ +} IxDmaAddressingMode; + +/** + * @ingroup IxDmaTypes + * @enum IxDmaTransferWidth + * @brief Dma transfer width definitions + * @Note Fixed addresses (either source or destination) do not support burst transfer width. + */ +typedef enum +{ + IX_DMA_32_SRC_32_DST = 0, /**< 32-bit src to 32-bit dst */ + IX_DMA_32_SRC_16_DST, /**< 32-bit src to 16-bit dst */ + IX_DMA_32_SRC_8_DST, /**< 32-bit src to 8-bit dst */ + IX_DMA_16_SRC_32_DST, /**< 16-bit src to 32-bit dst */ + IX_DMA_16_SRC_16_DST, /**< 16-bit src to 16-bit dst */ + IX_DMA_16_SRC_8_DST, /**< 16-bit src to 8-bit dst */ + IX_DMA_8_SRC_32_DST, /**< 8-bit src to 32-bit dst */ + IX_DMA_8_SRC_16_DST, /**< 8-bit src to 16-bit dst */ + IX_DMA_8_SRC_8_DST, /**< 8-bit src to 8-bit dst */ + IX_DMA_8_SRC_BURST_DST, /**< 8-bit src to burst dst - Not supported for fixed destination address */ + IX_DMA_16_SRC_BURST_DST, /**< 16-bit src to burst dst - Not supported for fixed destination address */ + IX_DMA_32_SRC_BURST_DST, /**< 32-bit src to burst dst - Not supported for fixed destination address */ + IX_DMA_BURST_SRC_8_DST, /**< burst src to 8-bit dst - Not supported for fixed source address */ + IX_DMA_BURST_SRC_16_DST, /**< burst src to 16-bit dst - Not supported for fixed source address */ + IX_DMA_BURST_SRC_32_DST, /**< burst src to 32-bit dst - Not supported for fixed source address*/ + IX_DMA_BURST_SRC_BURST_DST, /**< burst src to burst dst - Not supported for fixed source and destination address +*/ + IX_DMA_TRANSFER_WIDTH_INVALID /**< Invalid transfer width */ +} IxDmaTransferWidth; + +/** + * @ingroup IxDmaTypes + * @enum IxDmaNpeId + * @brief NpeId numbers to identify NPE A, B or C + */ +typedef enum +{ + IX_DMA_NPEID_NPEA = 0, /**< Identifies NPE A */ + IX_DMA_NPEID_NPEB, /**< Identifies NPE B */ + IX_DMA_NPEID_NPEC, /**< Identifies NPE C */ + IX_DMA_NPEID_MAX /**< Total Number of NPEs */ +} IxDmaNpeId; +/* @} */ +/** + * @defgroup IxDmaAcc IXP400 DMA Access Driver (IxDmaAcc) API + * + * @brief The public API for the IXP400 IxDmaAcc component + * + * @{ + */ + +/** + * @ingroup IxDmaAcc + * @brief DMA Request Id type + */ +typedef UINT32 IxDmaAccRequestId; + +/** + * @ingroup IxDmaAcc + * @def IX_DMA_REQUEST_FULL + * @brief DMA request queue is full + * This constant is a return value used to tell the user that the IxDmaAcc + * queue is full. + * + */ +#define IX_DMA_REQUEST_FULL 16 + +/** + * @ingroup IxDmaAcc + * @brief DMA completion notification + * This function is called to notify a client that the DMA has been completed + * @param status @ref IxDmaReturnStatus [out] - reporting to client + * + */ +typedef void (*IxDmaAccDmaCompleteCallback) (IxDmaReturnStatus status); + +/** + * @ingroup IxDmaAcc + * + * @fn ixDmaAccInit(IxNpeDlNpeId npeId) + * + * @brief Initialise the DMA Access component + * This function will initialise the DMA Access component internals + * @param npeId @ref IxNpeDlNpeId [in] - NPE to use for Dma Transfer + * @return @li IX_SUCCESS succesfully initialised the component + * @return @li IX_FAIL Initialisation failed for some unspecified + * internal reason. + */ +PUBLIC IX_STATUS +ixDmaAccInit(IxNpeDlNpeId npeId); + +/** + * @ingroup IxDmaAcc + * + * @fn ixDmaAccDmaTransfer( + IxDmaAccDmaCompleteCallback callback, + UINT32 SourceAddr, + UINT32 DestinationAddr, + UINT16 TransferLength, + IxDmaTransferMode TransferMode, + IxDmaAddressingMode AddressingMode, + IxDmaTransferWidth TransferWidth) + * + * @brief Perform DMA transfer + * This function will perform DMA transfer between devices within the + * IXP400 memory map. + * @note The following are restrictions for IxDmaAccDmaTransfer: + * @li The function is non re-entrant. + * @li The function assumes host devices are operating in big-endian mode. + * @li Fixed address does not suport burst transfer width + * @li Fixed source address to fixed destinatiom address mode is not suported + * @li The incrementing source address for expansion bus will not support a burst transfer width and copy and clear mode + * + * @param callback @ref IxDmaAccDmaCompleteCallback [in] - function pointer to be stored and called when the DMA transfer is completed. This cannot be NULL. + * @param SourceAddr UINT32 [in] - Starting address of DMA source. Must be a valid IXP400 memory map address. + * @param DestinationAddr UINT32 [in] - Starting address of DMA destination. Must be a valid IXP400 memory map address. + * @param TransferLength UINT16 [in] - The size of DMA data transfer. The range must be from 1-64Kbyte + * @param TransferMode @ref IxDmaTransferMode [in] - The DMA transfer mode + * @param AddressingMode @ref IxDmaAddressingMode [in] - The DMA addressing mode + * @param TransferWidth @ref IxDmaTransferWidth [in] - The DMA transfer width + * + * @return @li IX_DMA_SUCCESS Notification that the DMA request is succesful + * @return @li IX_DMA_FAIL IxDmaAcc not yet initialised or some internal error has occured + * @return @li IX_DMA_INVALID_TRANSFER_WIDTH Transfer width is nit valid + * @return @li IX_DMA_INVALID_TRANSFER_LENGTH Transfer length outside of valid range + * @return @li IX_DMA_INVALID_TRANSFER_MODE Transfer Mode not valid + * @return @li IX_DMA_REQUEST_FIFO_FULL IxDmaAcc request queue is full + */ +PUBLIC IxDmaReturnStatus +ixDmaAccDmaTransfer( + IxDmaAccDmaCompleteCallback callback, + UINT32 SourceAddr, + UINT32 DestinationAddr, + UINT16 TransferLength, + IxDmaTransferMode TransferMode, + IxDmaAddressingMode AddressingMode, + IxDmaTransferWidth TransferWidth); +/** + * @ingroup IxDmaAcc + * + * @fn ixDmaAccShow(void) + * + * @brief Display some component information for debug purposes + * Show some internal operation information relating to the DMA service. + * At a minimum the following will show. + * - the number of the DMA pend (in queue) + * @param None + * @return @li None + */ +PUBLIC IX_STATUS +ixDmaAccShow(void); + +#endif /* IXDMAACC_H */ + diff --git a/drivers/net/npe/include/IxEthAcc.h b/drivers/net/npe/include/IxEthAcc.h new file mode 100644 index 0000000..ff706c4 --- /dev/null +++ b/drivers/net/npe/include/IxEthAcc.h @@ -0,0 +1,2512 @@ +/** @file IxEthAcc.h + * + * @brief this file contains the public API of @ref IxEthAcc component + * + * Design notes: + * The IX_OSAL_MBUF address is to be specified on bits [31-5] and must + * be cache aligned (bits[4-0] cleared) + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * + */ + +#ifndef IxEthAcc_H +#define IxEthAcc_H + +#include +#include + +/** + * @defgroup IxEthAcc IXP400 Ethernet Access (IxEthAcc) API + * + * @brief ethAcc is a library that does provides access to the internal IXP400 10/100Bt Ethernet MACs. + * + *@{ + */ + +/** + * @ingroup IxEthAcc + * @brief Definition of the Ethernet Access status + */ +typedef enum /* IxEthAccStatus */ +{ + IX_ETH_ACC_SUCCESS = IX_SUCCESS, /**< return success*/ + IX_ETH_ACC_FAIL = IX_FAIL, /**< return fail*/ + IX_ETH_ACC_INVALID_PORT, /**< return invalid port*/ + IX_ETH_ACC_PORT_UNINITIALIZED, /**< return uninitialized*/ + IX_ETH_ACC_MAC_UNINITIALIZED, /**< return MAC uninitialized*/ + IX_ETH_ACC_INVALID_ARG, /**< return invalid arg*/ + IX_ETH_TX_Q_FULL, /**< return tx queue is full*/ + IX_ETH_ACC_NO_SUCH_ADDR /**< return no such address*/ +} IxEthAccStatus; + +/** + * @ingroup IxEthAcc + * @enum IxEthAccPortId + * @brief Definition of the IXP400 Mac Ethernet device. + */ +typedef enum +{ + IX_ETH_PORT_1 = 0, /**< Ethernet Port 1 */ + IX_ETH_PORT_2 = 1 /**< Ethernet port 2 */ + ,IX_ETH_PORT_3 = 2 /**< Ethernet port 3 */ +} IxEthAccPortId; + +/** + * @ingroup IxEthAcc + * + * @def IX_ETH_ACC_NUMBER_OF_PORTS + * + * @brief Definition of the number of ports + * + */ +#ifdef __ixp46X +#define IX_ETH_ACC_NUMBER_OF_PORTS (3) +#else +#define IX_ETH_ACC_NUMBER_OF_PORTS (2) +#endif + +/** + * @ingroup IxEthAcc + * + * @def IX_IEEE803_MAC_ADDRESS_SIZE + * + * @brief Definition of the size of the MAC address + * + */ +#define IX_IEEE803_MAC_ADDRESS_SIZE (6) + + +/** + * + * @brief Definition of the IEEE 802.3 Ethernet MAC address structure. + * + * The data should be packed with bytes xx:xx:xx:xx:xx:xx + * @note + * The data must be packed in network byte order. + */ +typedef struct +{ + UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< MAC address */ +} IxEthAccMacAddr; + +/** + * @ingroup IxEthAcc + * @def IX_ETH_ACC_NUM_TX_PRIORITIES + * @brief Definition of the number of transmit priorities + * + */ +#define IX_ETH_ACC_NUM_TX_PRIORITIES (8) + +/** + * @ingroup IxEthAcc + * @enum IxEthAccTxPriority + * @brief Definition of the relative priority used to transmit a frame + * + */ +typedef enum +{ + IX_ETH_ACC_TX_PRIORITY_0 = 0, /** STA */ + IX_ETHACC_RX_APTYPE = 0x30 /**< 802.11, AP <=> AP */ +} IxEthAccRxFrameType; + +/** + * @ingroup IxEthAcc + * @enum IxEthAccDuplexMode + * @brief Definition to provision the duplex mode of the MAC. + * + */ +typedef enum +{ + IX_ETH_ACC_FULL_DUPLEX, /**< Full duplex operation of the MAC */ + IX_ETH_ACC_HALF_DUPLEX /**< Half duplex operation of the MAC */ +} IxEthAccDuplexMode; + + +/** + * @ingroup IxEthAcc + * @struct IxEthAccNe + * @brief Definition of service-specific informations. + * + * This structure defines the Ethernet service-specific informations + * and enable QoS and VLAN features. + */ +typedef struct +{ + UINT32 ixReserved_next; /**< reserved for chaining */ + UINT32 ixReserved_lengths; /**< reserved for buffer lengths */ + UINT32 ixReserved_data; /**< reserved for buffer pointer */ + UINT8 ixDestinationPortId; /**< Destination portId for this packet, if known by NPE */ + UINT8 ixSourcePortId; /**< Source portId for this packet */ + UINT16 ixFlags; /**< BitField of option for this frame */ + UINT8 ixQoS; /**< QoS class of the frame */ + UINT8 ixReserved; /**< reserved */ + UINT16 ixVlanTCI; /**< Vlan TCI */ + UINT8 ixDestMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Destination MAC address */ + UINT8 ixSourceMac[IX_IEEE803_MAC_ADDRESS_SIZE]; /**< Source MAC address */ +} IxEthAccNe; + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_PORT_UNKNOWN + * + * @brief Contents of the field @a IX_ETHACC_NE_DESTPORTID when no + * destination port can be found by the NPE for this frame. + * + */ +#define IX_ETHACC_NE_PORT_UNKNOWN (0xff) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_DESTMAC + * + * @brief The location of the destination MAC address in the Mbuf header. + * + */ +#define IX_ETHACC_NE_DESTMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestMac + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_SOURCEMAC + * + * @brief The location of the source MAC address in the Mbuf header. + * + */ +#define IX_ETHACC_NE_SOURCEMAC(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourceMac + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_VLANTCI + * + * @brief The VLAN Tag Control Information associated with this frame + * + * The VLAN Tag Control Information associated with this frame. On Rx + * path, this field is extracted from the packet header. + * On Tx path, the value of this field is inserted in the frame when + * the port is configured to insert or replace vlan tags in the + * egress frames. + * + * @sa IX_ETHACC_NE_FLAGS + */ +#define IX_ETHACC_NE_VLANTCI(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixVlanTCI + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_SOURCEPORTID + * + * @brief The port where this frame came from. + * + * The port where this frame came from. This field is set on receive + * with the port information. This field is ignored on Transmit path. + */ +#define IX_ETHACC_NE_SOURCEPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixSourcePortId + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_DESTPORTID + * + * @brief The destination port where this frame should be sent. + * + * The destination port where this frame should be sent. + * + * @li In the transmit direction, this field contains the destination port + * and is ignored unless @a IX_ETHACC_NE_FLAG_DST is set. + * + * @li In the receive direction, this field contains the port where the + * destination MAC addresses has been learned. If the destination + * MAC address is unknown, then this value is set to the reserved value + * @a IX_ETHACC_NE_PORT_UNKNOWN + * + */ +#define IX_ETHACC_NE_DESTPORTID(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixDestinationPortId + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_QOS + * + * @brief QualityOfService class (QoS) for this received frame. + * + */ +#define IX_ETHACC_NE_QOS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixQoS + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_FLAGS + * + * @brief Bit Mask of the different flags associated with a frame + * + * The flags are the bit-oring combination + * of the following different fields : + * + * @li IP flag (Rx @a IX_ETHACC_NE_IPMASK) + * @li Spanning Tree flag (Rx @a IX_ETHACC_NE_STMASK) + * @li Link layer type (Rx and Tx @a IX_ETHACC_NE_LINKMASK) + * @li VLAN Tagged Frame (Rx @a IX_ETHACC_NE_VLANMASK) + * @li New source MAC address (Rx @a IX_ETHACC_NE_NEWSRCMASK) + * @li Multicast flag (Rx @a IX_ETHACC_NE_MCASTMASK) + * @li Broadcast flag (Rx @a IX_ETHACC_NE_BCASTMASK) + * @li Destination port flag (Tx @a IX_ETHACC_NE_PORTMASK) + * @li Tag/Untag Tx frame (Tx @a IX_ETHACC_NE_TAGMODEMASK) + * @li Overwrite destination port (Tx @a IX_ETHACC_NE_PORTOVERMASK) + * @li Filtered frame (Rx @a IX_ETHACC_NE_STMASK) + * @li VLAN Enabled (Rx and Tx @a IX_ETHACC_NE_VLANENABLEMASK) + */ +#define IX_ETHACC_NE_FLAGS(mBufPtr) ((IxEthAccNe *)&((mBufPtr)->ix_ne))->ixFlags + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_BCASTMASK + * + * @brief This mask defines if a received frame is a broadcast frame. + * + * This mask defines if a received frame is a broadcast frame. + * The BCAST flag is set when the destination MAC address of + * a frame is broadcast. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_BCASTMASK (0x1) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_MCASTMASK + * + * @brief This mask defines if a received frame is a multicast frame. + * + * This mask defines if a received frame is a multicast frame. + * The MCAST flag is set when the destination MAC address of + * a frame is multicast. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_MCASTMASK (0x1 << 1) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_IPMASK + * + * @brief This mask defines if a received frame is a IP frame. + * + * This mask applies to @a IX_ETHACC_NE_FLAGS and defines if a received + * frame is a IP frame. The IP flag is set on Rx direction, depending on + * the frame contents. The flag is set when the length/type field of a + * received frame is 0x8000. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_IPMASK (0x1 << 2) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_VLANMASK + * + * @brief This mask defines if a received frame is VLAN tagged. + * + * This mask defines if a received frame is VLAN tagged. + * When set, the Rx frame is VLAN-tagged and the tag value + * is available thru @a IX_ETHACC_NE_VLANID. + * Note that when sending frames which are already tagged + * this flag should be set, to avoid inserting another VLAN tag. + * + * @sa IX_ETHACC_NE_FLAGS + * @sa IX_ETHACC_NE_VLANID + * + */ +#define IX_ETHACC_NE_VLANMASK (0x1 << 3) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_LINKMASK + * + * @brief This mask is the link layer protocol indicator + * + * This mask applies to @a IX_ETHACC_NE_FLAGS. + * It reflects the state of a frame as it exits an NPE on the Rx path + * or enters an NPE on the Tx path. Its values are as follows: + * @li 0x00 - IEEE802.3 - 8802 (Rx) / IEEE802.3 - 8802 (Tx) + * @li 0x01 - IEEE802.3 - Ethernet (Rx) / IEEE802.3 - Ethernet (Tx) + * @li 0x02 - IEEE802.11 AP -> STA (Rx) / IEEE802.11 STA -> AP (Tx) + * @li 0x03 - IEEE802.11 AP -> AP (Rx) / IEEE802.11 AP->AP (Tx) + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_LINKMASK (0x3 << 4) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_STMASK + * + * @brief This mask defines if a received frame is a Spanning Tree frame. + * + * This mask applies to @a IX_ETHACC_NE_FLAGS. + * On rx direction, it defines if a received if frame is a Spanning Tree frame. + * Setting this fkag on transmit direction overrides the port settings + * regarding the VLAN options and + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_STMASK (0x1 << 6) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_FILTERMASK + * + * @brief This bit indicates whether a frame has been filtered by the Rx service. + * + * This mask applies to @a IX_ETHACC_NE_FLAGS. + * Certain frames, which should normally be fully filtered by the NPE to due + * the destination MAC address being on the same segment as the Rx port are + * still forwarded to the XScale (although the payload is invalid) in order + * to learn the MAC address of the transmitting station, if this is unknown. + * Normally EthAcc will filter and recycle these framess internally and no + * frames with the FILTER bit set will be received by the client. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_FILTERMASK (0x1 << 7) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_PORTMASK + * + * @brief This mask defines the rule to transmit a frame + * + * This mask defines the rule to transmit a frame. When set, a frame + * is transmitted to the destination port as set by the macro + * @a IX_ETHACC_NE_DESTPORTID. If not set, the destination port + * is searched using the destination MAC address. + * + * @note This flag is meaningful only for multiport Network Engines. + * + * @sa IX_ETHACC_NE_FLAGS + * @sa IX_ETHACC_NE_DESTPORTID + * + */ +#define IX_ETHACC_NE_PORTOVERMASK (0x1 << 8) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_TAGMODEMASK + * + * @brief This mask defines the tagging rules to apply to a transmit frame. + * + * This mask defines the tagging rules to apply to a transmit frame + * regardless of the default setting for a port. When used together + * with @a IX_ETHACC_NE_TAGOVERMASK and when set, the + * frame will be tagged prior to transmission. When not set, + * the frame will be untagged prior to transmission. This is accomplished + * irrespective of the Egress tagging rules, constituting a per-frame override. + * + * @sa IX_ETHACC_NE_FLAGS + * @sa IX_ETHACC_NE_TAGOVERMASK + * + */ +#define IX_ETHACC_NE_TAGMODEMASK (0x1 << 9) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_TAGOVERMASK + * + * @brief This mask defines the rule to transmit a frame + * + * This mask defines the rule to transmit a frame. When set, the + * default transmit rules of a port are overriden. + * When not set, the default rules as set by @ref IxEthDB should apply. + * + * @sa IX_ETHACC_NE_FLAGS + * @sa IX_ETHACC_NE_TAGMODEMASK + * + */ +#define IX_ETHACC_NE_TAGOVERMASK (0x1 << 10) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_VLANENABLEMASK + * + * @brief This mask defines if a frame is a VLAN frame or not + * + * When set, frames undergo normal VLAN processing on the Tx path + * (membership filtering, tagging, tag removal etc). If this flag is + * not set, the frame is considered to be a regular non-VLAN frame + * and no VLAN processing will be performed. + * + * Note that VLAN-enabled NPE images will always set this flag in all + * Rx frames, and images which are not VLAN enabled will clear this + * flag for all received frames. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_VLANENABLEMASK (0x1 << 14) + +/** + * @ingroup IxEthAcc + * + * @def IX_ETHACC_NE_NEWSRCMASK + * + * @brief This mask defines if a received frame has been learned. + * + * This mask defines if the source MAC address of a frame is + * already known. If the bit is set, the source MAC address was + * unknown to the NPE at the time the frame was received. + * + * @sa IX_ETHACC_NE_FLAGS + * + */ +#define IX_ETHACC_NE_NEWSRCMASK (0x1 << 15) + +/** + * @ingroup IxEthAcc + * + * @brief This defines the recommanded minimum size of MBUF's submitted + * to the frame receive service. + * + */ +#define IX_ETHACC_RX_MBUF_MIN_SIZE (2048) + +/** + * @ingroup IxEthAcc + * + * @brief This defines the highest MII address of any attached PHYs + * + * The maximum number for PHY address is 31, add on for range checking. + * + */ +#define IXP425_ETH_ACC_MII_MAX_ADDR 32 + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccInit(void) + * + * @brief Initializes the IXP400 Ethernet Access Service. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * This should be called once per module initialization. + * @pre + * The NPE must first be downloaded with the required microcode which supports all + * required features. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Service has failed to initialize. + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccInit(void); + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccUnload(void) + * + * @brief Unload the Ethernet Access Service. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @return void + * + *
+ */ +PUBLIC void ixEthAccUnload(void); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortInit( IxEthAccPortId portId) + * + * @brief Initializes an NPE/Ethernet MAC Port. + * + * The NPE/Ethernet port initialisation includes the following steps + * @li Initialize the NPE/Ethernet MAC hardware. + * @li Verify NPE downloaded and operational. + * @li The NPE shall be available for usage once this API returns. + * @li Verify that the Ethernet port is present before initializing + * + * @li Reentrant - no + * @li ISR Callable - no + * + * This should be called once per mac device. + * The NPE/MAC shall be in disabled state after init. + * + * @pre + * The component must be initialized via @a ixEthAccInit + * The NPE must first be downloaded with the required microcode which supports all + * required features. + * + * Dependant on Services: (Must be initialized before using this service may be initialized) + * ixNPEmh - NPE Message handling service. + * ixQmgr - Queue Manager component. + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS: if the ethernet port is not present, a warning is issued. + * @li @a IX_ETH_ACC_FAIL : The NPE processor has failed to initialize. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortInit(IxEthAccPortId portId); + + +/************************************************************************* + + ##### ## ##### ## ##### ## ##### # # + # # # # # # # # # # # # # # + # # # # # # # # # # # # ###### + # # ###### # ###### ##### ###### # # # + # # # # # # # # # # # # # + ##### # # # # # # # # # # # + +*************************************************************************/ + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxFrameSubmit( + IxEthAccPortId portId, + IX_OSAL_MBUF *buffer, + IxEthAccTxPriority priority) + * + * @brief This function shall be used to submit MBUFs buffers for transmission on a particular MAC device. + * + * When the frame is transmitted, the buffer shall be returned thru the + * callback @a IxEthAccPortTxDoneCallback. + * + * In case of over-submitting, the order of the frames on the + * network may be modified. + * + * Buffers shall be not queued for transmission if the port is disabled. + * The port can be enabled using @a ixEthAccPortEnable + * + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * + * @pre + * @a ixEthAccPortTxDoneCallbackRegister must be called to register a function to allow this service to + * return the buffer to the calling service. + * + * @note + * If the buffer submit fails for any reason the user has retained ownership of the buffer. + * + * @param portId @ref IxEthAccPortId [in] - MAC port ID to transmit Ethernet frame on. + * @param buffer @ref IX_OSAL_MBUF [in] - pointer to an MBUF formatted buffer. Chained buffers are supported for transmission. + * Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is ignored. + * @param priority @ref IxEthAccTxPriority [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Failed to queue frame for transmission. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ + +PUBLIC IxEthAccStatus ixEthAccPortTxFrameSubmit( + IxEthAccPortId portId, + IX_OSAL_MBUF *buffer, + IxEthAccTxPriority priority); + +/** + * @ingroup IxEthAcc + * + * @brief Function prototype for Ethernet Tx Buffer Done callback. Registered + * via @a ixEthAccTxBufferDoneCallbackRegister + * + * This function is called once the previously submitted buffer is no longer required by this service. + * It may be returned upon successful transmission of the frame or during the shutdown of + * the port prior to the transmission of a queued frame. + * The calling of this registered function is not a guarantee of successful transmission of the buffer. + * + * + * @li Reentrant - yes , The user provided function should be reentrant. + * @li ISR Callable - yes , The user provided function must be callable from an ISR. + * + * + * Calling Context : + * @par + * This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun + * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. + * The decision is system specific. + * + * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC + * via @a ixEthAccPortTxDoneCallbackRegister. It allows the same callback to be used for multiple MACs. + * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Tx mbuf descriptor. + * + * @return void + * + * @note + * The field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified by the access layer and reset to NULL. + * + *
+ */ +typedef void (*IxEthAccPortTxDoneCallback) ( UINT32 callbackTag, IX_OSAL_MBUF *buffer ); + + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxDoneCallbackRegister( IxEthAccPortId portId, + IxEthAccPortTxDoneCallback txCallbackFn, + UINT32 callbackTag) + * + * @brief Register a callback function to allow + * the transmitted buffers to return to the user. + * + * This function registers the transmit buffer done function callback for a particular port. + * + * The registered callback function is called once the previously submitted buffer is no longer required by this service. + * It may be returned upon successful transmission of the frame or shutdown of port prior to submission. + * The calling of this registered function is not a guarantee of successful transmission of the buffer. + * + * If called several times the latest callback shall be registered for a particular port. + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * @pre + * The port must be initialized via @a ixEthAccPortInit + * + * + * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device. + * @param txCallbackFn @ref IxEthAccPortTxDoneCallback [in] - Function to be called to return transmit buffers to the user. + * @param callbackTag UINT32 [in] - This tag shall be provided to the callback function. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxDoneCallbackRegister(IxEthAccPortId portId, + IxEthAccPortTxDoneCallback txCallbackFn, + UINT32 callbackTag); + + + +/** + * @ingroup IxEthAcc + * + * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortRxCallbackRegister + * + * It is the responsibility of the user function to free any MBUF's which it receives. + * + * @li Reentrant - yes , The user provided function should be reentrant. + * @li ISR Callable - yes , The user provided function must be callable from an ISR. + * @par + * + * This function dispatches frames to the user level + * via the provided function. The invocation shall be made for each + * frame dequeued from the Ethernet QM queue. The user is required to free any MBUF's + * supplied via this callback. In addition the registered callback must free up MBUF's + * from the receive free queue when the port is disabled + * + * If called several times the latest callback shall be registered for a particular port. + * + * Calling Context : + * @par + * This callback is called in the context of the queue manager dispatch loop @a ixQmgrgrDispatcherLoopRun + * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. + * The decision is system specific. + * + * + * @param callbackTag UINT32 [in] - This tag is that provided when the callback was registered for a particular MAC + * via @a ixEthAccPortRxCallbackRegister. It allows the same callback to be used for multiple MACs. + * @param mbuf @ref IX_OSAL_MBUF [in] - Pointer to the Rx mbuf header. Mbufs may be chained if + * the frame length is greater than the supplied mbuf length. + * @param reserved [in] - deprecated parameter The information is passed + * thru the IxEthAccNe header destination port ID field + * (@sa IX_ETHACC_NE_DESTPORTID). For backward + * compatibility,the value is equal to IX_ETH_DB_UNKNOWN_PORT (0xff). + * + * @return void + * + * @note + * Buffers may not be filled up to the length supplied in + * @a ixEthAccPortRxFreeReplenish(). The firmware fills + * them to the previous 64 bytes boundary. The user has to be aware + * that the length of the received mbufs may be smaller than the length + * of the supplied mbufs. + * The mbuf header contains the following modified field + * @li @a IX_OSAL_MBUF_PKT_LEN is set in the header of the first mbuf and indicates + * the total frame size + * @li @a IX_OSAL_MBUF_MLEN is set each mbuf header and indicates the payload length + * @li @a IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR contains a pointer to the next + * mbuf, or NULL at the end of a chain. + * @li @a IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR is modified. Its value is reset to NULL + * @li @a IX_OSAL_MBUF_FLAGS contains the bit 4 set for a broadcast packet and the bit 5 + * set for a multicast packet. Other bits are unmodified. + * + *
+ */ +typedef void (*IxEthAccPortRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF *buffer, UINT32 reserved); + +/** + * @ingroup IxEthAcc + * + * @brief Function prototype for Ethernet Frame Rx callback. Registered via @a ixEthAccPortMultiBufferRxCallbackRegister + * + * It is the responsibility of the user function to free any MBUF's which it receives. + * + * @li Reentrant - yes , The user provided function should be reentrant. + * @li ISR Callable - yes , The user provided function must be callable from an ISR. + * @par + * + * This function dispatches many frames to the user level + * via the provided function. The invocation shall be made for multiple frames + * dequeued from the Ethernet QM queue. The user is required to free any MBUF's + * supplied via this callback. In addition the registered callback must free up MBUF's + * from the receive free queue when the port is disabled + * + * If called several times the latest callback shall be registered for a particular port. + * + * Calling Context : + * @par + * This callback is called in the context of the queue manager dispatch loop @a ixQmgrDispatcherLoopRun + * within the @ref IxQMgrAPI component. The calling context may be from interrupt or high priority thread. + * The decision is system specific. + * + * + * @param callbackTag - This tag is that provided when the callback was registered for a particular MAC + * via @a ixEthAccPortMultiBufferRxCallbackRegister. It allows the same callback to be used for multiple MACs. + * @param mbuf - Pointer to an array of Rx mbuf headers. Mbufs + * may be chained if + * the frame length is greater than the supplied mbuf length. + * The end of the array contains a zeroed entry (NULL pointer). + * + * @return void + * + * @note The mbufs passed to this callback have the same structure than the + * buffers passed to @a IxEthAccPortRxCallback interfac. + * + * @note The usage of this callback is exclusive with the usage of + * @a ixEthAccPortRxCallbackRegister and @a IxEthAccPortRxCallback + * + * @sa ixEthAccPortMultiBufferRxCallbackRegister + * @sa IxEthAccPortMultiBufferRxCallback + * @sa ixEthAccPortRxCallbackRegister + * @sa IxEthAccPortRxCallback + *
+ */ + +typedef void (*IxEthAccPortMultiBufferRxCallback) (UINT32 callbackTag, IX_OSAL_MBUF **buffer); + + + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortRxCallback rxCallbackFn, UINT32 callbackTag) + * + * @brief Register a callback function to allow + * the reception of frames. + * + * The registered callback function is called once a frame is received by this service. + * + * If called several times the latest callback shall be registered for a particular port. + * + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * + * @param portId @ref IxEthAccPortId [in] - Register callback for a particular MAC device. + * @param rxCallbackFn @ref IxEthAccPortRxCallback [in] - Function to be called when Ethernet frames are availble. + * @param callbackTag UINT32 [in] - This tag shall be provided to the callback function. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxCallbackRegister(IxEthAccPortId portId, + IxEthAccPortRxCallback rxCallbackFn, + UINT32 callbackTag); + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMultiBufferRxCallbackRegister( IxEthAccPortId portId, IxEthAccPortMultiBufferRxCallback rxCallbackFn, UINT32 callbackTag) + * + * @brief Register a callback function to allow + * the reception of frames. + * + * The registered callback function is called once a frame is + * received by this service. If many frames are already received, + * the function is called once. + * + * If called several times the latest callback shall be registered for a particular port. + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * + * @param portId - Register callback for a particular MAC device. + * @param rxCallbackFn - @a IxEthAccMultiBufferRxCallbackFn - Function to be called when Ethernet frames are availble. + * @param callbackTag - This tag shall be provided to the callback function. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * @li @a IX_ETH_ACC_INVALID_ARG : An argument other than portId is invalid. + * + * @sa ixEthAccPortMultiBufferRxCallbackRegister + * @sa IxEthAccPortMultiBufferRxCallback + * @sa ixEthAccPortRxCallbackRegister + * @sa IxEthAccPortRxCallback + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMultiBufferRxCallbackRegister(IxEthAccPortId portId, + IxEthAccPortMultiBufferRxCallback rxCallbackFn, + UINT32 callbackTag); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer) + * + * @brief This function provides buffers for the Ethernet receive path. + * + * This component does not have a buffer management mechanisms built in. All Rx buffers must be supplied to it + * via this interface. + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * @param portId @ref IxEthAccPortId [in] - Provide buffers only to specific Rx MAC. + * @param buffer @ref IX_OSAL_MBUF [in] - Provide an MBUF to the Ethernet receive mechanism. + * Buffers size smaller than IX_ETHACC_RX_MBUF_MIN_SIZE may result in poor + * performances and excessive buffer chaining. Buffers + * larger than this size may be suitable for jumbo frames. + * Chained packets are not supported and the field IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR must be NULL. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Buffer has was not able to queue the + * buffer in the receive service. + * @li @a IX_ETH_ACC_FAIL : Buffer size is less than IX_ETHACC_RX_MBUF_MIN_SIZE + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + * @note + * If the buffer replenish operation fails it is the responsibility + * of the user to free the buffer. + * + * @note + * Sufficient buffers must be supplied to the component to maintain + * receive throughput and avoid rx buffer underflow conditions. + * To meet this goal, It is expected that the user preload the + * component with a sufficent number of buffers prior to enabling the + * NPE Ethernet receive path. The recommended minimum number of + * buffers is 8. + * + * @note + * For maximum performances, the mbuf size should be greater + * than the maximum frame size (Ethernet header, payload and FCS) + 64. + * Supplying smaller mbufs to the service results in mbuf + * chaining and degraded performances. The recommended size + * is @a IX_ETHACC_RX_MBUF_MIN_SIZE, which is + * enough to take care of 802.3 frames and "baby jumbo" frames without + * chaining, and "jumbo" frame within chaining. + * + * @note + * Buffers may not be filled up to their length. The firware fills + * them up to the previous 64 bytes boundary. The user has to be aware + * that the length of the received mbufs may be smaller than the length + * of the supplied mbufs. + * + * @warning This function checks the parameters if the NDEBUG + * flag is not defined. Turning on the argument checking (disabled by + * default) results in a lower EthAcc performance as this function + * is part of the data path. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxFreeReplenish( IxEthAccPortId portId, IX_OSAL_MBUF *buffer); + + + +/*************************************************************** + + #### #### # # ##### ##### #### # + # # # # ## # # # # # # # + # # # # # # # # # # # # + # # # # # # # ##### # # # + # # # # # ## # # # # # # + #### #### # # # # # #### ###### + + + ##### # ## # # ###### + # # # # # ## # # + # # # # # # # # ##### + ##### # ###### # # # # + # # # # # ## # + # ###### # # # # ###### + +***************************************************************/ + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortEnable(IxEthAccPortId portId) + * + * @brief This enables an Ethernet port for both Tx and Rx. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre The port must first be initialized via @a ixEthAccPortInit and the MAC address + * must be set using @a ixEthAccUnicastMacAddressSet before enabling it + * The rx and Tx Done callbacks registration via @a + * ixEthAccPortTxDoneCallbackRegister amd @a ixEthAccPortRxCallbackRegister + * has to be done before enabling the traffic. + * + * @param portId @ref IxEthAccPortId [in] - Port id to act upon. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized + * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortDisable(IxEthAccPortId portId) + * + * @brief This disables an Ethernet port for both Tx and Rx. + * + * Free MBufs are returned to the user via the registered callback when the port is disabled + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre The port must be enabled with @a ixEthAccPortEnable, otherwise this + * function has no effect + * + * @param portId @ref IxEthAccPortId [in] - Port id to act upon. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is not initialized + * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled) + * + * @brief Get the enabled state of a port. + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * @pre The port must first be initialized via @a ixEthAccPortInit + * + * @param portId @ref IxEthAccPortId [in] - Port id to act upon. + * @param enabled BOOL [out] - location to store the state of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortEnabledQuery(IxEthAccPortId portId, BOOL *enabled); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId) + * + * @brief Put the Ethernet MAC device in non-promiscuous mode. + * + * In non-promiscuous mode the MAC filters all frames other than + * destination MAC address which matches the following criteria: + * @li Unicast address provisioned via @a ixEthAccUnicastMacAddressSet + * @li All broadcast frames. + * @li Multicast addresses provisioned via @a ixEthAccMulticastAddressJoin + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @sa ixEthAccPortPromiscuousModeSet + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClear(IxEthAccPortId portId); + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId) + * + * @brief Put the MAC device in promiscuous mode. + * + * If the device is in promiscuous mode then all all received frames shall be forwared + * to the NPE for processing. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @sa ixEthAccPortPromiscuousModeClear + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSet(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortUnicastMacAddressSet( IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) + * + * @brief Configure unicast MAC address for a particular port + * + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSet(IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortUnicastMacAddressGet( IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) + * + * @brief Get unicast MAC address for a particular MAC port + * + * @pre + * The MAC address must first be set via @a ixEthAccMacPromiscuousModeSet + * If the MAC address has not been set, the function returns a + * IX_ETH_ACC_MAC_UNINITIALIZED status + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * @param *macAddr @ref IxEthAccMacAddr [out] - Ethernet MAC address. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_MAC_UNINITIALIZED : port MAC address is not initialized. + * @li @a IX_ETH_ACC_FAIL : macAddr is invalid. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortUnicastMacAddressGet(IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + + + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMulticastAddressJoin( IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) + * + * @brief Add a multicast address to the MAC address table. + * + * @note + * Due to the operation of the Ethernet MAC multicast filtering mechanism, frames which do not + * have a multicast destination address which were provisioned via this API may be forwarded + * to the NPE's. This is a result of the hardware comparison algorithm used in the destination mac address logic + * within the Ethernet MAC. + * + * See Also: IXP425 hardware development manual. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Error writing to the MAC registers + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressJoin(IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMulticastAddressJoinAll( IxEthAccPortId portId) + * + * @brief Filter all frames with multicast dest. + * + * This function clears the MAC address table, and then sets + * the MAC to forward ALL multicast frames to the NPE. + * Specifically, it forwards all frames whose destination address + * has the LSB of the highest byte set (01:00:00:00:00:00). This + * bit is commonly referred to as the "multicast bit". + * Broadcast frames will still be forwarded. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressJoinAll(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMulticastAddressLeave( IxEthAccPortId portId, + IxEthAccMacAddr *macAddr) + * + * @brief Remove a multicast address from the MAC address table. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * @param *macAddr @ref IxEthAccMacAddr [in] - Ethernet Mac address. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_NO_SUCH_ADDR : Failed if MAC address was not in the table. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressLeave(IxEthAccPortId portId, + IxEthAccMacAddr *macAddr); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMulticastAddressLeaveAll( IxEthAccPortId portId) + * + * @brief This function unconfigures the multicast filtering settings + * + * This function first clears the MAC address table, and then sets + * the MAC as configured by the promiscuous mode current settings. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMulticastAddressLeaveAll(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortUnicastAddressShow(IxEthAccPortId portId) + * + * @brief Displays unicast MAC address + * + * Displays unicast address which is configured using + * @a ixEthAccUnicastMacAddressSet. This function also displays the MAC filter used + * to filter multicast frames. + * + * Other functions modify the MAC filtering + * + * @li @a ixEthAccPortMulticastAddressJoinAll() - all multicast + * frames are forwarded to the application + * @li @a ixEthAccPortMulticastAddressLeaveAll() - rollback the + * effects of @a ixEthAccPortMulticastAddressJoinAll() + * @li @a ixEthAccPortMulticastAddressLeave() - unprovision a new + * filtering address + * @li @a ixEthAccPortMulticastAddressJoin() - provision a new + * filtering address + * @li @a ixEthAccPortPromiscuousModeSet() - all frames are + * forwarded to the application regardless of the multicast + * address provisioned + * @li @a ixEthAccPortPromiscuousModeClear() - frames are forwarded + * to the application following the multicast address provisioned + * + * In all cases, unicast and broadcast addresses are forwarded to + * the application. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return void + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShow(IxEthAccPortId portId); + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortMulticastAddressShow( IxEthAccPortId portId) + * + * @brief Displays multicast MAC address + * + * Displays multicast address which have been configured using @a ixEthAccMulticastAddressJoin + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] - Ethernet port id. + * + * @return void + * + *
+ */ +PUBLIC void ixEthAccPortMulticastAddressShow( IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortDuplexModeSet( IxEthAccPortId portId, IxEthAccDuplexMode mode ) + * + * @brief Set the duplex mode for the MAC. + * + * Configure the IXP400 MAC to either full or half duplex. + * + * @note + * The configuration should match that provisioned on the PHY. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * @param mode @ref IxEthAccDuplexMode [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortDuplexModeSet(IxEthAccPortId portId,IxEthAccDuplexMode mode); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortDuplexModeGet( IxEthAccPortId portId, IxEthAccDuplexMode *mode ) + * + * @brief Get the duplex mode for the MAC. + * + * return the duplex configuration of the IXP400 MAC. + * + * @note + * The configuration should match that provisioned on the PHY. + * See @a ixEthAccDuplexModeSet + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * @param *mode @ref IxEthAccDuplexMode [out] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ * + */ +PUBLIC IxEthAccStatus +ixEthAccPortDuplexModeGet(IxEthAccPortId portId,IxEthAccDuplexMode *mode ); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxFrameAppendPaddingEnable( IxEthAccPortId portId) + * + * @brief Enable padding bytes to be appended to runt frames submitted to + * this port + * + * Enable up to 60 null-bytes padding bytes to be appended to runt frames + * submitted to this port. This is the default behavior of the access + * component. + * + * @warning Do not change this behaviour while the port is enabled. + * + * @note When Tx padding is enabled, Tx FCS generation is turned on + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @sa ixEthAccPortTxFrameAppendFCSDusable + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendPaddingEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxFrameAppendPaddingDisable( IxEthAccPortId portId) + * + * @brief Disable padding bytes to be appended to runt frames submitted to + * this port + * + * Disable padding bytes to be appended to runt frames + * submitted to this port. This is not the default behavior of the access + * component. + * + * @warning Do not change this behaviour while the port is enabled. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendPaddingDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxFrameAppendFCSEnable( IxEthAccPortId portId) + * + * @brief Enable the appending of Ethernet FCS to all frames submitted to this port + * + * When enabled, the FCS is added to the submitted frames. This is the default + * behavior of the access component. + * Do not change this behaviour while the port is enabled. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendFCSEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortTxFrameAppendFCSDisable( IxEthAccPortId portId) + * + * @brief Disable the appending of Ethernet FCS to all frames submitted to this port. + * + * When disabled, the Ethernet FCS is not added to the submitted frames. + * This is not the default + * behavior of the access component. + * + * @note Since the FCS is not appended to the frame it is expected that the frame submitted to the + * component includes a valid FCS at the end of the data, although this will not be validated. + * + * The component shall forward the frame to the Ethernet MAC WITHOUT modification. + * + * Do not change this behaviour while the port is enabled. + * + * @note Tx FCS append is not disabled while Tx padding is enabled. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @sa ixEthAccPortTxFrameAppendPaddingEnable + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxFrameAppendFCSDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortRxFrameAppendFCSEnable( IxEthAccPortId portId) + * + * @brief Forward frames with FCS included in the receive buffer. + * + * The FCS is not striped from the receive buffer. + * The received frame length includes the FCS size (4 bytes). ie. + * A minimum sized ethernet frame shall have a length of 64bytes. + * + * Frame FCS validity checks are still carried out on all received frames. + * + * This is not the default + * behavior of the access component. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxFrameAppendFCSEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccPortRxFrameAppendFCSDisable( IxEthAccPortId portId) + * + * @brief Do not forward the FCS portion of the received Ethernet frame to the user. + * The FCS is striped from the receive buffer. + * The received frame length does not include the FCS size (4 bytes). + * Frame FCS validity checks are still carried out on all received frames. + * + * This is the default behavior of the component. + * Do not change this behaviour while the port is enabled. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxFrameAppendFCSDisable(IxEthAccPortId portId); + + + + +/** + * @ingroup IxEthAcc + * + * @enum IxEthAccSchedulerDiscipline + * + * @brief Definition for the port scheduling discipline + * + * Select the port scheduling discipline on receive and transmit path + * @li FIFO : No Priority : In this configuration all frames are processed + * in the access component in the strict order in which + * the component received them. + * @li FIFO : Priority : This shall be a very simple priority mechanism. + * Higher prior-ity frames shall be forwarded + * before lower priority frames. There shall be no + * fairness mechanisms applied across different + * priorities. Higher priority frames could starve + * lower priority frames indefinitely. + */ +typedef enum +{ + FIFO_NO_PRIORITY, /** + */ +PUBLIC IxEthAccStatus +ixEthAccTxSchedulingDisciplineSet(IxEthAccPortId portId, + IxEthAccSchedulerDiscipline sched); + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched) + * + * @brief Set the Rx scheduling to one of @a IxEthAccSchedulerDiscipline + * + * The default behavior of the component is @a FIFO_NO_PRIORITY. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @param sched : @a IxEthAccSchedulerDiscipline + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : Set appropriate discipline. + * @li @a IX_ETH_ACC_FAIL : Invalid/unsupported discipline. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccRxSchedulingDisciplineSet(IxEthAccSchedulerDiscipline sched); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccNpeLoopbackEnable(IxEthAccPortId portId) + * + * @brief Enable NPE loopback + * + * When this loopback mode is enabled all the transmitted frames are + * received on the same port, without payload. + * + * This function is recommended for power-up diagnostic checks and + * should never be used under normal Ethernet traffic operations. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @param portId : ID of the port + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : NPE loopback mode enabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortNpeLoopbackEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId) + * + * @brief Disable NPE loopback + * + * This function is used to disable the NPE loopback if previously + * enabled using ixEthAccNpeLoopbackEnable. + * + * This function is recommended for power-up diagnostic checks and + * should never be used under normal Ethernet traffic operations. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : NPE loopback successfully disabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortNpeLoopbackDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortTxEnable(IxEthAccPortId portId) + * + * @brief Enable Tx on the port + * + * This function is the complement of ixEthAccPortTxDisable and should + * be used only after Tx was disabled. A MAC core reset is required before + * this function is called (see @a ixEthAccPortMacReset). + * + * This function is the recommended usage scenario for emergency security + * shutdown and hardware failure recovery and should never be used for throttling + * traffic. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : Tx successfully enabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortTxDisable(IxEthAccPortId portId) + * + * @brief Disable Tx on the port + * + * This function can be used to disable Tx in the MAC core. + * Tx can be re-enabled, although this is not guaranteed, by performing + * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortTxEnable. + * Note that using this function is not recommended, except for shutting + * down Tx for emergency reasons. For proper port shutdown and re-enabling + * see ixEthAccPortEnable and ixEthAccPortDisable. + * + * This function is the recommended usage scenario for emergency security + * shutdown and hardware failure recovery and should never be used for throttling + * traffic. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @pre + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : Tx successfully disabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortTxDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortRxEnable(IxEthAccPortId portId) + * + * @brief Enable Rx on the port + * + * This function is the complement of ixEthAccPortRxDisable and should + * be used only after Rx was disabled. + * + * This function is the recommended usage scenario for emergency security + * shutdown and hardware failure recovery and should never be used for throttling + * traffic. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @pre + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : Rx successfully enabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxEnable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortRxDisable(IxEthAccPortId portId) + * + * @brief Disable Rx on the port + * + * This function can be used to disable Rx in the MAC core. + * Rx can be re-enabled, although this is not guaranteed, by performing + * a MAC core reset (@a ixEthAccPortMacReset) and calling ixEthAccPortRxEnable. + * Note that using this function is not recommended, except for shutting + * down Rx for emergency reasons. For proper port shutdown and re-enabling + * see ixEthAccPortEnable and ixEthAccPortDisable. + * + * This function is the recommended usage scenario for emergency security + * shutdown and hardware failure recovery and should never be used for throttling + * traffic. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : Rx successfully disabled + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortRxDisable(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn IxEthAccStatus ixEthAccPortMacReset(IxEthAccPortId portId) + * + * @brief Reset MAC core on the port + * + * This function will perform a MAC core reset (NPE Ethernet coprocessor). + * This function is inherently unsafe and the NPE recovery is not guaranteed + * after this function is called. The proper manner of performing port disable + * and enable (which will reset the MAC as well) is ixEthAccPortEnable/ixEthAccPortDisable. + * + * This function is the recommended usage scenario for hardware failure recovery + * and should never be used for throttling traffic. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @note Calling ixEthAccPortDisable followed by ixEthAccPortEnable is + * guaranteed to restore correct Ethernet Tx/Rx operation. + * + * @param portId : ID of the port + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS : MAC core reset + * @li @a IX_ETH_ACC_FAIL : Invalid port or Ethernet service not initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccPortMacReset(IxEthAccPortId portId); + +/********************************************************************************* + #### ##### ## ##### # #### ##### # #### #### + # # # # # # # # # # # # + #### # # # # # #### # # # #### + # # ###### # # # # # # # + # # # # # # # # # # # # # # # + #### # # # # # #### # # #### #### +**********************************************************************************/ + + +/** + * + * @brief This struct defines the statistics returned by this component. + * + * The component returns MIB2 EthObj variables which are obtained from the + * hardware or maintained by this component. + * + * + */ +typedef struct +{ + UINT32 dot3StatsAlignmentErrors; /**< link error count (rx) */ + UINT32 dot3StatsFCSErrors; /**< link error count (rx) */ + UINT32 dot3StatsInternalMacReceiveErrors; /**< link error count (rx) */ + UINT32 RxOverrunDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxLearnedEntryDiscards; /**< NPE: discarded frames count(rx) */ + UINT32 RxLargeFramesDiscards; /**< NPE: discarded frames count(rx) */ + UINT32 RxSTPBlockedDiscards; /**< NPE: discarded frames count(rx) */ + UINT32 RxVLANTypeFilterDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxVLANIdFilterDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxInvalidSourceDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxBlackListDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxWhiteListDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 RxUnderflowEntryDiscards; /**< NPE: discarded frames count (rx) */ + UINT32 dot3StatsSingleCollisionFrames; /**< link error count (tx) */ + UINT32 dot3StatsMultipleCollisionFrames; /**< link error count (tx) */ + UINT32 dot3StatsDeferredTransmissions; /**< link error count (tx) */ + UINT32 dot3StatsLateCollisions; /**< link error count (tx) */ + UINT32 dot3StatsExcessiveCollsions; /**< link error count (tx) */ + UINT32 dot3StatsInternalMacTransmitErrors; /**< link error count (tx) */ + UINT32 dot3StatsCarrierSenseErrors; /**< link error count (tx) */ + UINT32 TxLargeFrameDiscards; /**< NPE: discarded frames count (tx) */ + UINT32 TxVLANIdFilterDiscards; /**< NPE: discarded frames count (tx) */ + +}IxEthEthObjStats; + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMibIIStatsGet(IxEthAccPortId portId ,IxEthEthObjStats *retStats ) + * + * @brief Returns the statistics maintained for a port. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * + * @param portId @ref IxEthAccPortId [in] + * @param retStats @ref IxEthEthObjStats [out] + * @note Please note the user is responsible for cache coheriency of the retStat + * buffer. The data is actually populated via the NPE's. As such cache safe + * memory should be used in the retStats argument. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Invalid arguments. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccMibIIStatsGet(IxEthAccPortId portId, IxEthEthObjStats *retStats ); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats) + * + * @brief Returns and clears the statistics maintained for a port. + * + * @li Reentrant - yes + * @li ISR Callable - yes + * + * @pre + * + * @param portId @ref IxEthAccPortId [in] + * @param retStats @ref IxEthEthObjStats [out] + * @note Please note the user is responsible for cache coheriency of the retStats + * buffer. The data is actually populated via the NPE's. As such cache safe + * memory should be used in the retStats argument. + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : invalid arguments. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccMibIIStatsGetClear(IxEthAccPortId portId, IxEthEthObjStats *retStats); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMibIIStatsClear(IxEthAccPortId portId) + * + * @brief Clears the statistics maintained for a port. + * + * @li Reentrant - yes + * @li ISR Callable - no + * + * @pre + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : Invalid arguments. + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * @li @a IX_ETH_ACC_PORT_UNINITIALIZED : portId is un-initialized + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccMibIIStatsClear(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMacInit(IxEthAccPortId portId) + * + * @brief Initializes the ethernet MAC settings + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @param portId @ref IxEthAccPortId [in] + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_INVALID_PORT : portId is invalid. + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccMacInit(IxEthAccPortId portId); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccStatsShow(IxEthAccPortId portId) + * + * + * @brief Displays a ports statistics on the standard io console using printf. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @pre + * + * @param portId @ref IxEthAccPortId [in] + * + * @return void + * + *
+ */ +PUBLIC void ixEthAccStatsShow(IxEthAccPortId portId); + +/************************************************************************* + + # # # # # # ##### # #### + ## ## # # ## ## # # # # # + # ## # # # # ## # # # # # # + # # # # # # # # # # # + # # # # # # # # # # # + # # # # # # ##### # #### + +*************************************************************************/ + + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMiiReadRtn (UINT8 phyAddr, + UINT8 phyReg, + UINT16 *value) + * + * + * @brief Reads a 16 bit value from a PHY + * + * Reads a 16-bit word from a register of a MII-compliant PHY. Reading + * is performed through the MII management interface. This function returns + * when the read operation has successfully completed, or when a timeout has elapsed. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31) + * @param phyReg UINT8 [in] - the number of the MII register to read (0-31) + * @param value UINT16 [in] - the value read from the register + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : failed to read the register. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccMiiReadRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 *value); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMiiWriteRtn (UINT8 phyAddr, + UINT8 phyReg, + UINT16 value) + * + * + * @brief Writes a 16 bit value to a PHY + * + * Writes a 16-bit word from a register of a MII-compliant PHY. Writing + * is performed through the MII management interface. This function returns + * when the write operation has successfully completed, or when a timeout has elapsed. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT8 [in] - the address of the Ethernet PHY (0-31) + * @param phyReg UINT8 [in] - the number of the MII register to write (0-31) + * @param value UINT16 [out] - the value to write to the register + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : failed to write register. + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccMiiWriteRtn (UINT8 phyAddr, UINT8 phyReg, UINT16 value); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMiiAccessTimeoutSet(UINT32 timeout) + * + * @brief Overrides the default timeout value and retry count when reading or + * writing MII registers using ixEthAccMiiWriteRtn or ixEthAccMiiReadRtn + * + * The default behavior of the component is to use a IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS ms + * timeout (declared as 100 in IxEthAccMii_p.h) and a retry count of IX_ETH_ACC_MII_TIMEOUT_10TH_SECS + * (declared as 5 in IxEthAccMii_p.h). + * + * The MII read and write functions will attempt to read the status of the register up + * to the retry count times, delaying between each attempt with the timeout value. + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @pre + * + * @param timeout UINT32 [in] - new timeout value, in milliseconds + * @param timeout UINT32 [in] - new retry count (a minimum value of 1 must be used) + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : invalid parameter(s) + * + *
+ */ +PUBLIC IxEthAccStatus +ixEthAccMiiAccessTimeoutSet(UINT32 timeout, UINT32 retryCount); + +/** + * @ingroup IxEthAcc + * + * @fn ixEthAccMiiStatsShow (UINT32 phyAddr) + * + * + * @brief Displays detailed information on a specified PHY + * + * Displays the current values of the first eigth MII registers for a PHY, + * + * @li Reentrant - no + * @li ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and + * generating the MDIO clock. + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * + * @return IxEthAccStatus + * @li @a IX_ETH_ACC_SUCCESS + * @li @a IX_ETH_ACC_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IxEthAccStatus ixEthAccMiiStatsShow (UINT32 phyAddr); + + + +/******* BOARD SPECIFIC DEPRECATED API *********/ + +/* The following functions are high level functions which rely + * on the properties and interface of some Ethernet PHYs. The + * implementation is hardware specific and has been moved to + * the hardware-specific component IxEthMii. + */ + + #include "IxEthMii.h" + +/** + * @ingroup IxEthAcc + * + * @def ixEthAccMiiPhyScan + * + * @brief : deprecated API entry point. This definition + * ensures backward compatibility + * + * See @ref ixEthMiiPhyScan + * + * @note this feature is board specific + * + */ +#define ixEthAccMiiPhyScan(phyPresent) ixEthMiiPhyScan(phyPresent,IXP425_ETH_ACC_MII_MAX_ADDR) + +/** + * @ingroup IxEthAcc + * + * @def ixEthAccMiiPhyConfig + * + * @brief : deprecated API entry point. This definition + * ensures backward compatibility + * + * See @ref ixEthMiiPhyConfig + * + * @note this feature is board specific + */ +#define ixEthAccMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate) \ + ixEthMiiPhyConfig(phyAddr,speed100,fullDuplex,autonegotiate) + +/** + * @ingroup IxEthAcc + * + * @def ixEthAccMiiPhyReset + * + * @brief : deprecated API entry point. This definition + * ensures backward compatibility + * + * See @ref ixEthMiiPhyReset + * + * @note this feature is board specific + */ +#define ixEthAccMiiPhyReset(phyAddr) \ + ixEthMiiPhyReset(phyAddr) + +/** + * @ingroup IxEthAcc + * + * @def ixEthAccMiiLinkStatus + * + * @brief : deprecated API entry point. This definition + * ensures backward compatibility + * + * See @ref ixEthMiiLinkStatus + * + * @note this feature is board specific + */ +#define ixEthAccMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg) \ + ixEthMiiLinkStatus(phyAddr,linkUp,speed100,fullDuplex,autoneg) + + + +/** + * @ingroup IxEthAcc + * + * @def ixEthAccMiiShow + * + * @brief : deprecated API entry point. This definition + * ensures backward compatibility + * + * See @ref ixEthMiiPhyShow + * + * @note this feature is board specific + */ +#define ixEthAccMiiShow(phyAddr) \ + ixEthMiiPhyShow(phyAddr) + +#endif /* ndef IxEthAcc_H */ +/** + *@} + */ diff --git a/drivers/net/npe/include/IxEthAccDataPlane_p.h b/drivers/net/npe/include/IxEthAccDataPlane_p.h new file mode 100644 index 0000000..8b8e6b2 --- /dev/null +++ b/drivers/net/npe/include/IxEthAccDataPlane_p.h @@ -0,0 +1,245 @@ +/** + * @file IxEthAccDataPlane_p.h + * + * @author Intel Corporation + * @date 12-Feb-2002 + * + * @brief Internal Header file for IXP425 Ethernet Access component. + * + * Design Notes: + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + + + +#ifndef IxEthAccDataPlane_p_H +#define IxEthAccDataPlane_p_H + +#include +#include + +/** + * @addtogroup IxEthAccPri + *@{ + */ + +/* typedefs global to this file*/ + +typedef struct +{ + IX_OSAL_MBUF *pHead; + IX_OSAL_MBUF *pTail; +}IxEthAccDataPlaneQList; + + +/** + * @struct IxEthAccDataPlaneStats + * @brief Statistics data structure associated with the data plane + * + */ +typedef struct +{ + UINT32 addToSwQ; + UINT32 removeFromSwQ; + UINT32 unchainedTxMBufs; + UINT32 chainedTxMBufs; + UINT32 unchainedTxDoneMBufs; + UINT32 chainedTxDoneMBufs; + UINT32 unchainedRxMBufs; + UINT32 chainedRxMBufs; + UINT32 unchainedRxFreeMBufs; + UINT32 chainedRxFreeMBufs; + UINT32 rxCallbackCounter; + UINT32 rxCallbackBurstRead; + UINT32 txDoneCallbackCounter; + UINT32 unexpectedError; +} IxEthAccDataPlaneStats; + +/** + * @fn ixEthAccMbufFromSwQ + * @brief used during disable steps to convert mbufs from + * swq format, ready to be pushed into hw queues for NPE, + * back into XScale format + */ +IX_OSAL_MBUF *ixEthAccMbufFromSwQ(IX_OSAL_MBUF *mbuf); + +/** + * @fn ixEthAccDataPlaneShow + * @brief Show function (for data plane statistics + */ +void ixEthAccDataPlaneShow(void); + +/* + * lock dataplane when atomic operation is required + */ +#define IX_ETH_ACC_DATA_PLANE_LOCK(arg) arg = ixOsalIrqLock(); +#define IX_ETH_ACC_DATA_PLANE_UNLOCK(arg) ixOsalIrqUnlock(arg); + +/* + * Use MBUF fields + */ +#define IX_ETHACC_NE_SHARED(mBufPtr) \ + ((IxEthAccNe *)&((mBufPtr)->ix_ne)) + +#if 1 + +#define IX_ETHACC_NE_NEXT(mBufPtr) (mBufPtr)->ix_ne.reserved[0] + +/* tm - wrong!! len and pkt_len are in the second word - #define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[3] */ +#define IX_ETHACC_NE_LEN(mBufPtr) (mBufPtr)->ix_ne.reserved[1] + +#define IX_ETHACC_NE_DATA(mBufPtr)(mBufPtr)->ix_ne.reserved[2] + +#else + +#define IX_ETHACC_NE_NEXT(mBufPtr) \ + IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_next + +#define IX_ETHACC_NE_LEN(mBufPtr) \ + IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_lengths + +#define IX_ETHACC_NE_DATA(mBufPtr) \ + IX_ETHACC_NE_SHARED(mBufPtr)->ixReserved_data +#endif + +/* + * Use MBUF next pointer field to chain data. + */ +#define IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER(mbuf) (mbuf)->ix_ctrl.ix_chain + + + +#define IX_ETH_ACC_DATAPLANE_IS_Q_EMPTY(mbuf_list) ((mbuf_list.pHead) == NULL) + + +#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_HEAD(mbuf_list,mbuf_to_add) \ + do { \ + int lockVal; \ + IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ); \ + if ( (mbuf_list.pHead) != NULL ) \ + { \ + (IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add))) = (mbuf_list.pHead);\ + (mbuf_list.pHead) = (mbuf_to_add); \ + } \ + else { \ + (mbuf_list.pTail) = (mbuf_list.pHead) = (mbuf_to_add); \ + IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \ + } \ + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \ + } while(0) + + +#define IX_ETH_ACC_DATAPLANE_ADD_MBUF_TO_Q_TAIL(mbuf_list,mbuf_to_add) \ + do { \ + int lockVal; \ + IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.addToSwQ); \ + if ( (mbuf_list.pHead) == NULL ) \ + { \ + (mbuf_list.pHead) = mbuf_to_add; \ + IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \ + } \ + else { \ + IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_list.pTail)) = (mbuf_to_add); \ + IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_add)) = NULL; \ + } \ + (mbuf_list.pTail) = mbuf_to_add; \ + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \ + } while (0) + + +#define IX_ETH_ACC_DATAPLANE_REMOVE_MBUF_FROM_Q_HEAD(mbuf_list,mbuf_to_rem) \ + do { \ + int lockVal; \ + IX_ETH_ACC_DATA_PLANE_LOCK(lockVal); \ + if ( (mbuf_list.pHead) != NULL ) \ + { \ + IX_ETH_ACC_STATS_INC(ixEthAccDataStats.removeFromSwQ); \ + (mbuf_to_rem) = (mbuf_list.pHead) ; \ + (mbuf_list.pHead) = (IX_ETH_ACC_MBUF_NEXT_PKT_CHAIN_MEMBER((mbuf_to_rem)));\ + } \ + else { \ + (mbuf_to_rem) = NULL; \ + } \ + IX_ETH_ACC_DATA_PLANE_UNLOCK(lockVal); \ + } while (0) + + +/** + * @brief message handler QManager entries for NPE id => port ID conversion (NPE_B => 0, NPE_C => 1) + */ +#define IX_ETH_ACC_PORT_TO_NPE_ID(port) \ + ixEthAccPortData[(port)].npeId + +#define IX_ETH_ACC_NPE_TO_PORT_ID(npe) ((npe == 0 ? 2 : (npe == 1 ? 0 : ( npe == 2 ? 1 : -1 )))) + +#define IX_ETH_ACC_PORT_TO_TX_Q_ID(port) \ + ixEthAccPortData[(port)].ixEthAccTxData.txQueue + +#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_ID(port) \ + ixEthAccPortData[(port)].ixEthAccRxData.rxFreeQueue + +#define IX_ETH_ACC_PORT_TO_TX_Q_SOURCE(port) (port == IX_ETH_PORT_1 ? IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE : IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE)) + +#define IX_ETH_ACC_PORT_TO_RX_FREE_Q_SOURCE(port) (port == IX_ETH_PORT_1 ? IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE : (port == IX_ETH_PORT_2 ? IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE : IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE )) + +/* Flush the mbufs chain and all data pointed to by the mbuf */ + +#ifndef NDEBUG +#define IX_ETH_ACC_STATS_INC(x) (x++) +#else +#define IX_ETH_ACC_STATS_INC(x) +#endif + +#define IX_ETH_ACC_MAX_TX_FRAMES_TO_SUBMIT 128 + +void ixEthRxFrameQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId); +void ixEthRxMultiBufferQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId); +void ixEthTxFrameDoneQMCallback(IxQMgrQId qId, IxQMgrCallbackId callbackId); + +#endif /* IxEthAccDataPlane_p_H */ + + +/** + *@} + */ + diff --git a/drivers/net/npe/include/IxEthAccMac_p.h b/drivers/net/npe/include/IxEthAccMac_p.h new file mode 100644 index 0000000..93e9d98 --- /dev/null +++ b/drivers/net/npe/include/IxEthAccMac_p.h @@ -0,0 +1,248 @@ +/* + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + + +#ifndef IxEthAccMac_p_H +#define IxEthAccMac_p_H + +#include "IxOsal.h" + +#define IX_ETH_ACC_MAX_MULTICAST_ADDRESSES 256 +#define IX_ETH_ACC_NUM_PORTS 3 +#define IX_ETH_ACC_MAX_FRAME_SIZE_DEFAULT 1536 +#define IX_ETH_ACC_MAX_FRAME_SIZE_UPPER_RANGE (65536-64) +#define IX_ETH_ACC_MAX_FRAME_SIZE_LOWER_RANGE 64 + +/* + * + * MAC register definitions + * + */ +#define IX_ETH_ACC_MAC_0_BASE IX_OSAL_IXP400_ETHA_PHYS_BASE +#define IX_ETH_ACC_MAC_1_BASE IX_OSAL_IXP400_ETHB_PHYS_BASE +#define IX_ETH_ACC_MAC_2_BASE IX_OSAL_IXP400_ETH_NPEA_PHYS_BASE + +#define IX_ETH_ACC_MAC_TX_CNTRL1 0x000 +#define IX_ETH_ACC_MAC_TX_CNTRL2 0x004 +#define IX_ETH_ACC_MAC_RX_CNTRL1 0x010 +#define IX_ETH_ACC_MAC_RX_CNTRL2 0x014 +#define IX_ETH_ACC_MAC_RANDOM_SEED 0x020 +#define IX_ETH_ACC_MAC_THRESH_P_EMPTY 0x030 +#define IX_ETH_ACC_MAC_THRESH_P_FULL 0x038 +#define IX_ETH_ACC_MAC_BUF_SIZE_TX 0x040 +#define IX_ETH_ACC_MAC_TX_DEFER 0x050 +#define IX_ETH_ACC_MAC_RX_DEFER 0x054 +#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1 0x060 +#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2 0x064 +#define IX_ETH_ACC_MAC_SLOT_TIME 0x070 +#define IX_ETH_ACC_MAC_MDIO_CMD_1 0x080 +#define IX_ETH_ACC_MAC_MDIO_CMD_2 0x084 +#define IX_ETH_ACC_MAC_MDIO_CMD_3 0x088 +#define IX_ETH_ACC_MAC_MDIO_CMD_4 0x08c +#define IX_ETH_ACC_MAC_MDIO_STS_1 0x090 +#define IX_ETH_ACC_MAC_MDIO_STS_2 0x094 +#define IX_ETH_ACC_MAC_MDIO_STS_3 0x098 +#define IX_ETH_ACC_MAC_MDIO_STS_4 0x09c +#define IX_ETH_ACC_MAC_ADDR_MASK_1 0x0A0 +#define IX_ETH_ACC_MAC_ADDR_MASK_2 0x0A4 +#define IX_ETH_ACC_MAC_ADDR_MASK_3 0x0A8 +#define IX_ETH_ACC_MAC_ADDR_MASK_4 0x0AC +#define IX_ETH_ACC_MAC_ADDR_MASK_5 0x0B0 +#define IX_ETH_ACC_MAC_ADDR_MASK_6 0x0B4 +#define IX_ETH_ACC_MAC_ADDR_1 0x0C0 +#define IX_ETH_ACC_MAC_ADDR_2 0x0C4 +#define IX_ETH_ACC_MAC_ADDR_3 0x0C8 +#define IX_ETH_ACC_MAC_ADDR_4 0x0CC +#define IX_ETH_ACC_MAC_ADDR_5 0x0D0 +#define IX_ETH_ACC_MAC_ADDR_6 0x0D4 +#define IX_ETH_ACC_MAC_INT_CLK_THRESH 0x0E0 +#define IX_ETH_ACC_MAC_UNI_ADDR_1 0x0F0 +#define IX_ETH_ACC_MAC_UNI_ADDR_2 0x0F4 +#define IX_ETH_ACC_MAC_UNI_ADDR_3 0x0F8 +#define IX_ETH_ACC_MAC_UNI_ADDR_4 0x0FC +#define IX_ETH_ACC_MAC_UNI_ADDR_5 0x100 +#define IX_ETH_ACC_MAC_UNI_ADDR_6 0x104 +#define IX_ETH_ACC_MAC_CORE_CNTRL 0x1FC + + +/* + * + *Bit definitions + * + */ + +/* TX Control Register 1*/ + +#define IX_ETH_ACC_TX_CNTRL1_TX_EN BIT(0) +#define IX_ETH_ACC_TX_CNTRL1_DUPLEX BIT(1) +#define IX_ETH_ACC_TX_CNTRL1_RETRY BIT(2) +#define IX_ETH_ACC_TX_CNTRL1_PAD_EN BIT(3) +#define IX_ETH_ACC_TX_CNTRL1_FCS_EN BIT(4) +#define IX_ETH_ACC_TX_CNTRL1_2DEFER BIT(5) +#define IX_ETH_ACC_TX_CNTRL1_RMII BIT(6) + +/* TX Control Register 2 */ +#define IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK 0xf + +/* RX Control Register 1 */ +#define IX_ETH_ACC_RX_CNTRL1_RX_EN BIT(0) +#define IX_ETH_ACC_RX_CNTRL1_PADSTRIP_EN BIT(1) +#define IX_ETH_ACC_RX_CNTRL1_CRC_EN BIT(2) +#define IX_ETH_ACC_RX_CNTRL1_PAUSE_EN BIT(3) +#define IX_ETH_ACC_RX_CNTRL1_LOOP_EN BIT(4) +#define IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN BIT(5) +#define IX_ETH_ACC_RX_CNTRL1_RX_RUNT_EN BIT(6) +#define IX_ETH_ACC_RX_CNTRL1_BCAST_DIS BIT(7) + +/* RX Control Register 2 */ +#define IX_ETH_ACC_RX_CNTRL2_DEFER_EN BIT(0) + + + +/* Core Control Register */ +#define IX_ETH_ACC_CORE_RESET BIT(0) +#define IX_ETH_ACC_CORE_RX_FIFO_FLUSH BIT(1) +#define IX_ETH_ACC_CORE_TX_FIFO_FLUSH BIT(2) +#define IX_ETH_ACC_CORE_SEND_JAM BIT(3) +#define IX_ETH_ACC_CORE_MDC_EN BIT(4) + +/* 1st bit of 1st MAC octet */ +#define IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT ( 1) + + +/* + * + * Default values + * + */ + + +#define IX_ETH_ACC_TX_CNTRL1_DEFAULT (IX_ETH_ACC_TX_CNTRL1_TX_EN | \ + IX_ETH_ACC_TX_CNTRL1_RETRY | \ + IX_ETH_ACC_TX_CNTRL1_FCS_EN | \ + IX_ETH_ACC_TX_CNTRL1_2DEFER | \ + IX_ETH_ACC_TX_CNTRL1_PAD_EN) + +#define IX_ETH_ACC_TX_MAX_RETRIES_DEFAULT 0x0f + +#define IX_ETH_ACC_RX_CNTRL1_DEFAULT (IX_ETH_ACC_RX_CNTRL1_CRC_EN \ + | IX_ETH_ACC_RX_CNTRL1_RX_EN) + +#define IX_ETH_ACC_RX_CNTRL2_DEFAULT 0x0 + +/* Thresholds determined by NPE firmware FS */ +#define IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT 0x12 +#define IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT 0x30 + +/* Number of bytes that must be in the tx fifo before + transmission commences*/ +#define IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT 0x8 + +/* One-part deferral values */ +#define IX_ETH_ACC_MAC_TX_DEFER_DEFAULT 0x15 +#define IX_ETH_ACC_MAC_RX_DEFER_DEFAULT 0x16 + +/* Two-part deferral values... */ +#define IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT 0x08 +#define IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT 0x07 + +/* This value applies to MII */ +#define IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT 0x80 + +/* This value applies to RMII */ +#define IX_ETH_ACC_MAC_SLOT_TIME_RMII_DEFAULT 0xFF + +#define IX_ETH_ACC_MAC_ADDR_MASK_DEFAULT 0xFF + +#define IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT 0x1 +/*The following is a value chosen at random*/ +#define IX_ETH_ACC_RANDOM_SEED_DEFAULT 0x8 + +/*By default we must configure the MAC to generate the + MDC clock*/ +#define IX_ETH_ACC_CORE_DEFAULT (IX_ETH_ACC_CORE_MDC_EN) + +#define IXP425_ETH_ACC_MAX_PHY 2 +#define IXP425_ETH_ACC_MAX_AN_ENTRIES 20 +#define IX_ETH_ACC_MAC_RESET_DELAY 1 + +#define IX_ETH_ACC_MAC_ALL_BITS_SET 0xFF + +#define IX_ETH_ACC_MAC_MSGID_SHL 24 + +#define IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS 20 +#define IX_ETH_ACC_PORT_DISABLE_DELAY_COUNT 200 /* 4 seconds timeout */ +#define IX_ETH_ACC_PORT_DISABLE_RETRY_COUNT 3 +#define IX_ETH_ACC_MIB_STATS_DELAY_MSECS 2000 /* 2 seconds delay for ethernet stats */ + +/*Register access macros*/ +#if (CPU == SIMSPARCSOLARIS) +extern void registerWriteStub (UINT32 base, UINT32 offset, UINT32 val); +extern UINT32 registerReadStub (UINT32 base, UINT32 offset); + +#define REG_WRITE(b,o,v) registerWriteStub(b, o, v) +#define REG_READ(b,o,v) do { v = registerReadStub(b, o); } while (0) +#else +#define REG_WRITE(b,o,v) IX_OSAL_WRITE_LONG((volatile UINT32 *)(b + o), v) +#define REG_READ(b,o,v) (v = IX_OSAL_READ_LONG((volatile UINT32 *)(b + o))) + +#endif + +void ixEthAccMacUnload(void); +IxEthAccStatus ixEthAccMacMemInit(void); + +/* MAC core loopback */ +IxEthAccStatus ixEthAccPortLoopbackEnable(IxEthAccPortId portId); +IxEthAccStatus ixEthAccPortLoopbackDisable(IxEthAccPortId portId); + +/* MAC core traffic control */ +IxEthAccStatus ixEthAccPortTxEnablePriv(IxEthAccPortId portId); +IxEthAccStatus ixEthAccPortTxDisablePriv(IxEthAccPortId portId); +IxEthAccStatus ixEthAccPortRxEnablePriv(IxEthAccPortId portId); +IxEthAccStatus ixEthAccPortRxDisablePriv(IxEthAccPortId portId); +IxEthAccStatus ixEthAccPortMacResetPriv(IxEthAccPortId portId); + +/* NPE software loopback */ +IxEthAccStatus ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId); +IxEthAccStatus ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId); + +#endif /*IxEthAccMac_p_H*/ + diff --git a/drivers/net/npe/include/IxEthAccMii_p.h b/drivers/net/npe/include/IxEthAccMii_p.h new file mode 100644 index 0000000..568d4a0 --- /dev/null +++ b/drivers/net/npe/include/IxEthAccMii_p.h @@ -0,0 +1,97 @@ +/** + * @file IxEthAccMii_p.h + * + * @author Intel Corporation + * @date + * + * @brief MII Header file + * + * Design Notes: + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#ifndef IxEthAccMii_p_H +#define IxEthAccMii_p_H + +/* MII definitions - these have been verified against the LXT971 and LXT972 PHYs*/ + +#define IXP425_ETH_ACC_MII_MAX_REG 32 /* max register per phy */ + +#define IX_ETH_ACC_MII_REG_SHL 16 +#define IX_ETH_ACC_MII_ADDR_SHL 21 + +/* Definitions for MII access routines*/ + +#define IX_ETH_ACC_MII_GO BIT(31) +#define IX_ETH_ACC_MII_WRITE BIT(26) +#define IX_ETH_ACC_MII_TIMEOUT_10TH_SECS 5 +#define IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS 100 +#define IX_ETH_ACC_MII_READ_FAIL BIT(31) + +#define IX_ETH_ACC_MII_PHY_DEF_DELAY 300 /* max delay before link up, etc. */ +#define IX_ETH_ACC_MII_PHY_NO_DELAY 0x0 /* do not delay */ +#define IX_ETH_ACC_MII_PHY_NULL 0xff /* PHY is not present */ +#define IX_ETH_ACC_MII_PHY_DEF_ADDR 0x0 /* default PHY's logical address */ + +#ifndef IX_ETH_ACC_MII_MONITOR_DELAY +# define IX_ETH_ACC_MII_MONITOR_DELAY 0x5 /* in seconds */ +#endif + +/* Register definition */ + +#define IX_ETH_ACC_MII_CTRL_REG 0x0 /* Control Register */ +#define IX_ETH_ACC_MII_STAT_REG 0x1 /* Status Register */ +#define IX_ETH_ACC_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */ +#define IX_ETH_ACC_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */ +#define IX_ETH_ACC_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */ + /* Advertisement Register */ +#define IX_ETH_ACC_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */ + /* partner ability Register */ +#define IX_ETH_ACC_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */ + /* Expansion Register */ +#define IX_ETH_ACC_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */ + /* next-page transmit Register */ + +IxEthAccStatus ixEthAccMdioShow (void); +IxEthAccStatus ixEthAccMiiInit(void); +void ixEthAccMiiUnload(void); + +#endif /*IxEthAccMii_p_H*/ diff --git a/drivers/net/npe/include/IxEthAccQueueAssign_p.h b/drivers/net/npe/include/IxEthAccQueueAssign_p.h new file mode 100644 index 0000000..e5fd16e --- /dev/null +++ b/drivers/net/npe/include/IxEthAccQueueAssign_p.h @@ -0,0 +1,137 @@ +/** + * @file IxEthAccQueueAssign_p.h + * + * @author Intel Corporation + * @date 06-Mar-2002 + * + * @brief Mapping from QMgr Q's to internal assignment + * + * Design Notes: + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @addtogroup IxEthAccPri + *@{ + */ + +/* + * Os/System dependancies. + */ +#include "IxOsal.h" + +/* + * Intermodule dependancies + */ +#include "IxQMgr.h" +#include "IxQueueAssignments.h" + +/* Check range of Q's assigned to this component. */ +#if IX_ETH_ACC_RX_FRAME_ETH_Q >= (IX_QMGR_MIN_QUEUPP_QID ) | \ + IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \ + IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \ + IX_ETH_ACC_TX_FRAME_ENET0_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \ + IX_ETH_ACC_TX_FRAME_ENET1_Q >= (IX_QMGR_MIN_QUEUPP_QID) | \ + IX_ETH_ACC_TX_FRAME_DONE_ETH_Q >= (IX_QMGR_MIN_QUEUPP_QID) +#error "Not all Ethernet Access Queues are betweem 1-31, requires full functionalty Q's unless otherwise validated " +#endif + +/** +* +* @typedef IxEthAccQregInfo +* +* @brief +* +*/ +typedef struct +{ + IxQMgrQId qId; + char *qName; + IxQMgrCallback qCallback; + IxQMgrCallbackId callbackTag; + IxQMgrQSizeInWords qSize; + IxQMgrQEntrySizeInWords qWords; + BOOL qNotificationEnableAtStartup; + IxQMgrSourceId qConditionSource; + IxQMgrWMLevel AlmostEmptyThreshold; + IxQMgrWMLevel AlmostFullThreshold; + +} IxEthAccQregInfo; + +/* + * Prototypes for all QM callbacks. + */ + +/* + * Rx Callbacks + */ +IX_ETH_ACC_PUBLIC +void ixEthRxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId); + +IX_ETH_ACC_PUBLIC +void ixEthRxMultiBufferQMCallback(IxQMgrQId, IxQMgrCallbackId); + +IX_ETH_ACC_PUBLIC +void ixEthRxFreeQMCallback(IxQMgrQId, IxQMgrCallbackId); + +/* + * Tx Callback. + */ +IX_ETH_ACC_PUBLIC +void ixEthTxFrameQMCallback(IxQMgrQId, IxQMgrCallbackId); + +IX_ETH_ACC_PUBLIC +void ixEthTxFrameDoneQMCallback(IxQMgrQId, IxQMgrCallbackId ); + + +#define IX_ETH_ACC_QM_QUEUE_DISPATCH_PRIORITY (IX_QMGR_Q_PRIORITY_0) /* Highest priority */ + +/* + * Queue watermarks + */ +#define IX_ETH_ACC_RX_FRAME_ETH_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_NOT_E ) +#define IX_ETH_ACC_RX_FREE_BUFF_ENET0_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) +#define IX_ETH_ACC_RX_FREE_BUFF_ENET1_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) +#define IX_ETH_ACC_RX_FREE_BUFF_ENET2_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) +#define IX_ETH_ACC_TX_FRAME_ENET0_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) +#define IX_ETH_ACC_TX_FRAME_ENET1_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) +#define IX_ETH_ACC_TX_FRAME_ENET2_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_E ) +#define IX_ETH_ACC_TX_FRAME_DONE_ETH_Q_SOURCE (IX_QMGR_Q_SOURCE_ID_NOT_E ) diff --git a/drivers/net/npe/include/IxEthAcc_p.h b/drivers/net/npe/include/IxEthAcc_p.h new file mode 100644 index 0000000..4e0de82 --- /dev/null +++ b/drivers/net/npe/include/IxEthAcc_p.h @@ -0,0 +1,325 @@ +/** + * @file IxEthAcc_p.h + * + * @author Intel Corporation + * @date 12-Feb-2002 + * + * @brief Internal Header file for IXP425 Ethernet Access component. + * + * Design Notes: + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @addtogroup IxEthAccPri + *@{ + */ + +#ifndef IxEthAcc_p_H +#define IxEthAcc_p_H + +/* + * Os/System dependancies. + */ +#include "IxOsal.h" + +/* + * Intermodule dependancies + */ +#include "IxNpeDl.h" +#include "IxQMgr.h" + +#include "IxEthNpe.h" + +/* + * Intra module dependancies + */ + +#include "IxEthAccDataPlane_p.h" +#include "IxEthAccMac_p.h" + + +#define INLINE __inline__ + +#ifdef NDEBUG + +#define IX_ETH_ACC_PRIVATE static + +#else + +#define IX_ETH_ACC_PRIVATE + +#endif /* ndef NDEBUG */ + +#define IX_ETH_ACC_PUBLIC + + +#define IX_ETH_ACC_IS_PORT_VALID(port) ((port) < IX_ETH_ACC_NUMBER_OF_PORTS ? TRUE : FALSE ) + + + +#ifndef NDEBUG +#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);} +#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);} +#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);} +#else +#define IX_ETH_ACC_FATAL_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_FATAL,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);} +#define IX_ETH_ACC_WARNING_LOG(a,b,c,d,e,f,g) { ixOsalLog ( IX_OSAL_LOG_LVL_WARNING,IX_OSAL_LOG_DEV_STDOUT,a,b,c,d,e,f,g);} +#define IX_ETH_ACC_DEBUG_LOG(a,b,c,d,e,f,g) {} +#endif + +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccInitDataPlane(void); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrQueuesConfig(void); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccQMgrRxCallbacksRegister(IxQMgrCallback ixQMgrCallback); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccSingleEthNpeCheck(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC void ixEthAccQMgrRxQEntryGet(UINT32 *numRxQueueEntries); + +/* prototypes for the private control plane functions (used by the control interface wrapper) */ +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnablePriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDisablePriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressSetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastMacAddressGetPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinPriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressJoinAllPriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeavePriv(IxEthAccPortId portId, IxEthAccMacAddr *macAddr); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortMulticastAddressLeaveAllPriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortUnicastAddressShowPriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC void ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeSetPriv(IxEthAccPortId portId, IxEthAccDuplexMode mode); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortDuplexModeGetPriv(IxEthAccPortId portId, IxEthAccDuplexMode *mode); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingEnablePriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendPaddingDisablePriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSEnablePriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortTxFrameAppendFCSDisablePriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSEnablePriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccPortRxFrameAppendFCSDisablePriv(IxEthAccPortId portId); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccTxSchedulingDisciplineSetPriv(IxEthAccPortId portId, IxEthAccSchedulerDiscipline sched); +IX_ETH_ACC_PUBLIC IxEthAccStatus ixEthAccRxSchedulingDisciplineSetPriv(IxEthAccSchedulerDiscipline sched); + +/** + * @struct ixEthAccRxDataStats + * @brief Stats data structures for data path. - Not obtained from h/w + * + */ +typedef struct +{ + UINT32 rxFrameClientCallback; + UINT32 rxFreeRepOK; + UINT32 rxFreeRepDelayed; + UINT32 rxFreeRepFromSwQOK; + UINT32 rxFreeRepFromSwQDelayed; + UINT32 rxFreeLateNotificationEnabled; + UINT32 rxFreeLowCallback; + UINT32 rxFreeOverflow; + UINT32 rxFreeLock; + UINT32 rxDuringDisable; + UINT32 rxSwQDuringDisable; + UINT32 rxUnlearnedMacAddress; + UINT32 rxPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1]; + UINT32 rxUnexpectedError; + UINT32 rxFiltered; +} IxEthAccRxDataStats; + +/** + * @struct IxEthAccTxDataStats + * @brief Stats data structures for data path. - Not obtained from h/w + * + */ +typedef struct +{ + UINT32 txQOK; + UINT32 txQDelayed; + UINT32 txFromSwQOK; + UINT32 txFromSwQDelayed; + UINT32 txLowThreshCallback; + UINT32 txDoneClientCallback; + UINT32 txDoneClientCallbackDisable; + UINT32 txOverflow; + UINT32 txLock; + UINT32 txPriority[IX_ETH_ACC_TX_PRIORITY_7 + 1]; + UINT32 txLateNotificationEnabled; + UINT32 txDoneDuringDisable; + UINT32 txDoneSwQDuringDisable; + UINT32 txUnexpectedError; +} IxEthAccTxDataStats; + +/* port Disable state machine : list of states */ +typedef enum +{ + /* general port states */ + DISABLED = 0, + ACTIVE, + + /* particular Tx/Rx states */ + REPLENISH, + RECEIVE, + TRANSMIT, + TRANSMIT_DONE +} IxEthAccPortDisableState; + +typedef struct +{ + BOOL fullDuplex; + BOOL rxFCSAppend; + BOOL txFCSAppend; + BOOL txPADAppend; + BOOL enabled; + BOOL promiscuous; + BOOL joinAll; + IxOsalMutex ackMIBStatsLock; + IxOsalMutex ackMIBStatsResetLock; + IxOsalMutex MIBStatsGetAccessLock; + IxOsalMutex MIBStatsGetResetAccessLock; + IxOsalMutex npeLoopbackMessageLock; + IxEthAccMacAddr mcastAddrsTable[IX_ETH_ACC_MAX_MULTICAST_ADDRESSES]; + UINT32 mcastAddrIndex; + IX_OSAL_MBUF *portDisableTxMbufPtr; + IX_OSAL_MBUF *portDisableRxMbufPtr; + + volatile IxEthAccPortDisableState portDisableState; + volatile IxEthAccPortDisableState rxState; + volatile IxEthAccPortDisableState txState; + + BOOL initDone; + BOOL macInitialised; +} IxEthAccMacState; + +/** + * @struct IxEthAccRxInfo + * @brief System-wide data structures associated with the data plane. + * + */ +typedef struct +{ + IxQMgrQId higherPriorityQueue[IX_QMGR_MAX_NUM_QUEUES]; /**< higher priority queue list */ + IxEthAccSchedulerDiscipline schDiscipline; /**< Receive Xscale QoS type */ +} IxEthAccInfo; + +/** + * @struct IxEthAccRxDataInfo + * @brief Per Port data structures associated with the receive data plane. + * + */ +typedef struct +{ + IxQMgrQId rxFreeQueue; /**< rxFree Queue for this port */ + IxEthAccPortRxCallback rxCallbackFn; + UINT32 rxCallbackTag; + IxEthAccDataPlaneQList freeBufferList; + IxEthAccPortMultiBufferRxCallback rxMultiBufferCallbackFn; + UINT32 rxMultiBufferCallbackTag; + BOOL rxMultiBufferCallbackInUse; + IxEthAccRxDataStats stats; /**< Receive s/w stats */ +} IxEthAccRxDataInfo; + +/** + * @struct IxEthAccTxDataInfo + * @brief Per Port data structures associated with the transmit data plane. + * + */ +typedef struct +{ + IxEthAccPortTxDoneCallback txBufferDoneCallbackFn; + UINT32 txCallbackTag; + IxEthAccDataPlaneQList txQ[IX_ETH_ACC_NUM_TX_PRIORITIES]; /**< Transmit Q */ + IxEthAccSchedulerDiscipline schDiscipline; /**< Transmit Xscale QoS */ + IxQMgrQId txQueue; /**< txQueue for this port */ + IxEthAccTxDataStats stats; /**< Transmit s/w stats */ +} IxEthAccTxDataInfo; + + +/** + * @struct IxEthAccPortDataInfo + * @brief Per Port data structures associated with the port data plane. + * + */ +typedef struct +{ + BOOL portInitialized; + UINT32 npeId; /**< NpeId for this port */ + IxEthAccTxDataInfo ixEthAccTxData; /**< Transmit data control structures */ + IxEthAccRxDataInfo ixEthAccRxData; /**< Receive data control structures */ +} IxEthAccPortDataInfo; + +extern IxEthAccPortDataInfo ixEthAccPortData[]; +#define IX_ETH_IS_PORT_INITIALIZED(port) (ixEthAccPortData[port].portInitialized) + +extern BOOL ixEthAccServiceInit; +#define IX_ETH_ACC_IS_SERVICE_INITIALIZED() (ixEthAccServiceInit == TRUE ) + +/* + * Maximum number of frames to consume from the Rx Frame Q. + */ + +#define IX_ETH_ACC_MAX_RX_FRAME_CONSUME_PER_CALLBACK (128) + +/* + * Max number of times to load the Rx Free Q from callback. + */ +#define IX_ETH_ACC_MAX_RX_FREE_BUFFERS_LOAD (256) /* Set greater than depth of h/w Q + drain time at line rate */ + +/* + * Max number of times to read from the Tx Done Q in one sitting. + */ + +#define IX_ETH_ACC_MAX_TX_FRAME_DONE_CONSUME_PER_CALLBACK (256) + +/* + * Max number of times to take buffers from S/w queues and write them to the H/w Tx + * queues on receipt of a Tx low threshold callback + */ + +#define IX_ETH_ACC_MAX_TX_FRAME_TX_CONSUME_PER_CALLBACK (16) + + +#define IX_ETH_ACC_FLUSH_CACHE(addr,size) IX_OSAL_CACHE_FLUSH((addr),(size)) +#define IX_ETH_ACC_INVALIDATE_CACHE(addr,size) IX_OSAL_CACHE_INVALIDATE((addr),(size)) + + +#define IX_ETH_ACC_MEMSET(start,value,size) memset(start,value,size) + +#endif /* ndef IxEthAcc_p_H */ + + + diff --git a/drivers/net/npe/include/IxEthDB.h b/drivers/net/npe/include/IxEthDB.h new file mode 100644 index 0000000..1189c9a --- /dev/null +++ b/drivers/net/npe/include/IxEthDB.h @@ -0,0 +1,2373 @@ +/** @file IxEthDB.h + * + * @brief this file contains the public API of @ref IxEthDB component + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * + */ + +#ifndef IxEthDB_H +#define IxEthDB_H + +#include +#include + +/** + * @defgroup IxEthDB IXP400 Ethernet Database (IxEthDB) API + * + * @brief ethDB is a library that does provides a MAC address database learning/filtering capability + * + *@{ + */ + +#define INLINE __inline__ + +#define IX_ETH_DB_PRIVATE PRIVATE /* imported from IxTypes.h */ + +#define IX_ETH_DB_PUBLIC PUBLIC + +/** + * @brief port ID => message handler NPE id conversion (0 => NPE_B, 1 => NPE_C) + */ +#define IX_ETH_DB_PORT_ID_TO_NPE(id) (id == 0 ? 1 : (id == 1 ? 2 : (id == 2 ? 0 : -1))) + +/** + * @def IX_ETH_DB_NPE_TO_PORT_ID(npe) + * @brief message handler NPE id => port ID conversion (NPE_B => 0, NPE_C => 1) + */ +#define IX_ETH_DB_NPE_TO_PORT_ID(npe) (npe == 0 ? 2 : (npe == 1 ? 0 : (npe == 2 ? 1 : -1))) + +/* temporary define - won't work for Azusa */ +#define IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(id) (IX_ETH_DB_PORT_ID_TO_NPE(id) << 4) +#define IX_ETH_DB_NPE_LOGICAL_ID_TO_PORT_ID(id) (IX_ETH_DB_NPE_TO_PORT_ID(id >> 4)) + +/** + * @def IX_IEEE803_MAC_ADDRESS_SIZE + * @brief The size of the MAC address + */ +#define IX_IEEE803_MAC_ADDRESS_SIZE (6) + +/** + * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT + * @brief Number of QoS priorities defined by IEEE802.1Q + */ +#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8) + +/** + * @enum IxEthDBStatus + * @brief Ethernet Database API return values + */ +typedef enum /* IxEthDBStatus */ +{ + IX_ETH_DB_SUCCESS = IX_SUCCESS, /**< Success */ + IX_ETH_DB_FAIL = IX_FAIL, /**< Failure */ + IX_ETH_DB_INVALID_PORT, /**< Invalid port */ + IX_ETH_DB_PORT_UNINITIALIZED, /**< Port not initialized */ + IX_ETH_DB_MAC_UNINITIALIZED, /**< MAC not initialized */ + IX_ETH_DB_INVALID_ARG, /**< Invalid argument */ + IX_ETH_DB_NO_SUCH_ADDR, /**< Address not found for search or delete operations */ + IX_ETH_DB_NOMEM, /**< Learning database memory full */ + IX_ETH_DB_BUSY, /**< Learning database cannot complete operation, access temporarily blocked */ + IX_ETH_DB_END, /**< Database browser passed the end of the record set */ + IX_ETH_DB_INVALID_VLAN, /**< Invalid VLAN ID (valid range is 0..4094, 0 signifies no VLAN membership, used for priority tagged frames) */ + IX_ETH_DB_INVALID_PRIORITY, /**< Invalid QoS priority/traffic class (valid range for QoS priority is 0..7, valid range for traffic class depends on run-time configuration) */ + IX_ETH_DB_NO_PERMISSION, /**< No permission for attempted operation */ + IX_ETH_DB_FEATURE_UNAVAILABLE, /**< Feature not available (or not enabled) */ + IX_ETH_DB_INVALID_KEY, /**< Invalid search key */ + IX_ETH_DB_INVALID_RECORD_TYPE /**< Invalid record type */ +} IxEthDBStatus; + +/** @brief VLAN ID type, valid range is 0..4094, 0 signifying no VLAN membership */ +typedef UINT32 IxEthDBVlanId; + +/** @brief 802.1Q VLAN tag, contains 3 bits user priority, 1 bit CFI, 12 bits VLAN ID */ +typedef UINT32 IxEthDBVlanTag; + +/** @brief QoS priority/traffic class type, valid range is 0..7, 0 being the lowest */ +typedef UINT32 IxEthDBPriority; + +/** @brief Priority mapping table; 0..7 QoS priorities used to index, table contains traffic classes */ +typedef UINT8 IxEthDBPriorityTable[8]; + +/** @brief A 4096 bit array used to map the complete VLAN ID range */ +typedef UINT8 IxEthDBVlanSet[512]; + +#define IX_ETH_DB_802_1Q_VLAN_MASK (0xFFF) +#define IX_ETH_DB_802_1Q_QOS_MASK (0x7) + +#define IX_ETH_DB_802_1Q_MAX_VLAN_ID (0xFFE) + +/** + * @def IX_ETH_DB_SET_VLAN_ID + * @brief returns the given 802.1Q tag with the VLAN ID field substituted with the given VLAN ID + * + * This macro is used to change the VLAN ID in a 802.1Q tag. + * + * Example: + * + * tag = IX_ETH_DB_SET_VLAN_ID(tag, 32) + * + * inserts the VLAN ID "32" in the given tag. + */ +#define IX_ETH_DB_SET_VLAN_ID(vlanTag, vlanID) (((vlanTag) & 0xF000) | ((vlanID) & IX_ETH_DB_802_1Q_VLAN_MASK)) + +/** +* @def IX_ETH_DB_GET_VLAN_ID +* @brief returns the VLAN ID from the given 802.1Q tag +*/ +#define IX_ETH_DB_GET_VLAN_ID(vlanTag) ((vlanTag) & IX_ETH_DB_802_1Q_VLAN_MASK) + +#define IX_ETH_DB_GET_QOS_PRIORITY(vlanTag) (((vlanTag) >> 13) & IX_ETH_DB_802_1Q_QOS_MASK) + +#define IX_ETH_DB_SET_QOS_PRIORITY(vlanTag, priority) (((vlanTag) & 0x1FFF) | (((priority) & IX_ETH_DB_802_1Q_QOS_MASK) << 13)) + +#define IX_ETH_DB_CHECK_VLAN_TAG(vlanTag) { if(((vlanTag & 0xFFFF0000) != 0) || (IX_ETH_DB_GET_VLAN_ID(vlanTag) > 4094)) return IX_ETH_DB_INVALID_VLAN; } + +#define IX_ETH_DB_CHECK_VLAN_ID(vlanId) { if (vlanId > IX_ETH_DB_802_1Q_MAX_VLAN_ID) return IX_ETH_DB_INVALID_VLAN; } + +#define IX_IEEE802_1Q_VLAN_TPID (0x8100) + +typedef enum +{ + IX_ETH_DB_UNTAGGED_FRAMES = 0x1, /**< Accepts untagged frames */ + IX_ETH_DB_VLAN_TAGGED_FRAMES = 0x2, /**< Accepts tagged frames */ + IX_ETH_DB_PRIORITY_TAGGED_FRAMES = 0x4, /**< Accepts tagged frames with VLAN ID set to 0 (no VLAN membership) */ + IX_ETH_DB_ACCEPT_ALL_FRAMES = + IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES /**< Accepts all the frames */ +} IxEthDBFrameFilter; + +typedef enum +{ + IX_ETH_DB_PASS_THROUGH = 0x1, /**< Leave frame as-is */ + IX_ETH_DB_ADD_TAG = 0x2, /**< Add default port VLAN tag */ + IX_ETH_DB_REMOVE_TAG = 0x3 /**< Remove VLAN tag from frame */ +} IxEthDBTaggingAction; + +typedef enum +{ + IX_ETH_DB_FIREWALL_WHITE_LIST = 0x1, /**< Firewall operates in white-list mode (MAC address based admission) */ + IX_ETH_DB_FIREWALL_BLACK_LIST = 0x2 /**< Firewall operates in black-list mode (MAC address based blocking) */ +} IxEthDBFirewallMode; + +typedef enum +{ + IX_ETH_DB_FILTERING_RECORD = 0x01, /**< + *
Filtering record
MAC address static/dynamic type age + *
+ */ + IX_ETH_DB_FILTERING_VLAN_RECORD = 0x02, /**< + *
VLAN-enabled filtering record
MAC address static/dynamic type age 802.1Q tag + *
+ */ + IX_ETH_DB_WIFI_RECORD = 0x04, /**< + *
WiFi header conversion record
MAC address optional gateway MAC address + *
+ */ + IX_ETH_DB_FIREWALL_RECORD = 0x08, /**< + *
Firewall record
MAC address + *
+ */ + IX_ETH_DB_GATEWAY_RECORD = 0x10, /**< For internal use only */ + IX_ETH_DB_MAX_RECORD_TYPE_INDEX = 0x10, /**< For internal use only */ + IX_ETH_DB_NO_RECORD_TYPE = 0, /**< None of the registered record types */ + IX_ETH_DB_ALL_FILTERING_RECORDS = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD, /**< All the filtering records */ + IX_ETH_DB_ALL_RECORD_TYPES = IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD | + IX_ETH_DB_WIFI_RECORD | IX_ETH_DB_FIREWALL_RECORD /**< All the record types registered within EthDB */ +} IxEthDBRecordType; + +typedef enum +{ + IX_ETH_DB_LEARNING = 0x01, /**< Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records */ + IX_ETH_DB_FILTERING = 0x02, /**< Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature */ + IX_ETH_DB_VLAN_QOS = 0x04, /**< VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes */ + IX_ETH_DB_FIREWALL = 0x08, /**< Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists */ + IX_ETH_DB_SPANNING_TREE_PROTOCOL = 0x10, /**< Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes */ + IX_ETH_DB_WIFI_HEADER_CONVERSION = 0x20 /**< WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data */ +} IxEthDBFeature; + +typedef UINT32 IxEthDBProperty; /**< Property ID type */ + +typedef enum +{ + IX_ETH_DB_INTEGER_PROPERTY = 0x1, /**< 4 byte unsigned integer type */ + IX_ETH_DB_STRING_PROPERTY = 0x2, /**< NULL-terminated string type of maximum 255 characters (including the terminator) */ + IX_ETH_DB_MAC_ADDR_PROPERTY = 0x3, /**< 6 byte MAC address type */ + IX_ETH_DB_BOOL_PROPERTY = 0x4 /**< 4 byte boolean type; can contain only TRUE and FALSE values */ +} IxEthDBPropertyType; + +/* list of supported properties for the IX_ETH_DB_VLAN_QOS feature */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY (0x01) /**< Property identifying number the supported number of traffic classes */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY (0x10) /**< Rx queue assigned to traffic class 0 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY (0x11) /**< Rx queue assigned to traffic class 1 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY (0x12) /**< Rx queue assigned to traffic class 2 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY (0x13) /**< Rx queue assigned to traffic class 3 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY (0x14) /**< Rx queue assigned to traffic class 4 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY (0x15) /**< Rx queue assigned to traffic class 5 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY (0x16) /**< Rx queue assigned to traffic class 6 */ +#define IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY (0x17) /**< Rx queue assigned to traffic class 7 */ + +/* private property used by EthAcc to indicate queue configuration complete */ +#define IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (0x18) + +/** + * + * @brief The IEEE 802.3 Ethernet MAC address structure. + * + * The data should be packed with bytes xx:xx:xx:xx:xx:xx + * + * @note The data must be packed in network byte order. + */ +typedef struct +{ + UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; +} IxEthDBMacAddr; + +/** + * @ingroup IxEthDB + * + * @brief Definition of an IXP400 port. + */ +typedef UINT32 IxEthDBPortId; + +/** + * @ingroup IxEthDB + * + * @brief Port dependency map definition + */ +typedef UINT8 IxEthDBPortMap[32]; + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBInit(void) + * + * @brief Initializes the Ethernet learning/filtering database + * + * @note calling this function multiple times does not constitute an error; + * redundant calls will be ignored, returning IX_ETH_DB_SUCCESS + * + * @retval IX_ETH_DB_SUCCESS initialization was successful + * @retval IX_ETH_DB_FAIL initialization failed (OS error) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBInit(void); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBUnload(void) + * + * @brief Stops and prepares the EthDB component for unloading. + * + * @retval IX_ETH_DB_SUCCESS de-initialization was successful + * @retval IX_ETH_DB_BUSY de-initialization failed, ports must be disabled first + * @retval IX_ETH_DB_FAIL de-initialization failed (OS error) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUnload(void); + +/** + * @ingroup IxEthDB + * + * @fn void ixEthDBPortInit(IxEthDBPortId portID) + * + * @brief Initializes a port + * + * This function is called automatically by the Ethernet Access + * ixEthAccPortInit() routine for Ethernet NPE ports and should be manually + * called for any user-defined port (any port that is not one of + * the two Ethernet NPEs). + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to be initialized + * + * @see IxEthDBPortDefs.h for port definitions + * + * @note calling this function multiple times does not constitute an error; + * redundant calls will be ignored + */ +IX_ETH_DB_PUBLIC +void ixEthDBPortInit(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID) + * + * @brief Enables a port + * + * This function is called automatically from the Ethernet Access component + * ixEthAccPortEnable() routine for Ethernet NPE ports and should be manually + * called for any user-defined port (any port that is not one of + * the Ethernet NPEs). + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to enable processing on + * + * @retval IX_ETH_DB_SUCCESS if enabling is successful + * @retval IX_ETH_DB_FAIL if the enabling was not successful due to + * a message handler error + * @retval IX_ETH_DB_MAC_UNINITIALIZED the MAC address of this port was + * not initialized (only for Ethernet NPEs) + * @retval IX_ETH_DB_INVALID_PORT if portID is invalid + * + * @pre ixEthDBPortAddressSet needs to be called prior to enabling the port events + * for Ethernet NPEs + * + * @see ixEthDBPortAddressSet + * + * @see IxEthDBPortDefs.h for port definitions + * + * @note calling this function multiple times does not constitute an error; + * redundant calls will be ignored + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID) + * + * @brief Disables processing on a port + * + * This function is called automatically from the Ethernet Access component + * ixEthAccPortDisable() routine for Ethernet NPE ports and should be manually + * called for any user-defined port (any port that is not one of + * the Ethernet NPEs). + * + * @note Calling ixEthAccPortDisable() will disable the respective Ethernet NPE. + * After Ethernet NPEs are disabled they are stopped therefore + * when re-enabled they need to be reset, downloaded with microcode and started. + * For learning to restart working the user needs to call again + * ixEthAccPortUnicastMacAddressSet or ixEthDBUnicastAddressSet + * with the respective port MAC address. + * Residual MAC addresses learnt before the port was disabled are deleted as soon + * as the port is disabled. This only applies to dynamic (learnt) entries, static + * entries do not dissapear when the port is disabled. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to disable processing on + * + * @retval IX_ETH_DB_SUCCESS if disabling is successful + * @retval IX_ETH_DB_FAIL if the disabling was not successful due to + * a message handler error + * @retval IX_ETH_DB_INVALID_PORT if portID is invalid + * + * @note calling this function multiple times after the first time completed successfully + * does not constitute an error; redundant calls will be ignored and return IX_ETH_DB_SUCCESS +*/ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Sets the port MAC address + * + * This function is to be called from the Ethernet Access component top-level + * ixEthDBUnicastAddressSet(). Event processing cannot be enabled for a port + * until its MAC address has been set. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port whose MAC address is set + * @param macAddr @ref IxEthDBMacAddr [in] - port MAC address + * + * @retval IX_ETH_DB_SUCCESS MAC address was set successfully + * @retval IX_ETH_DB_FAIL MAC address was not set due to a message handler failure + * @retval IX_ETH_DB_INVALID_PORT if the port is not an Ethernet NPE + * + * @see IxEthDBPortDefs.h for port definitions + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize) + * + * @brief Set the maximum frame size supported on the given port ID + * + * This functions set the maximum frame size supported on a specific port ID + * + * - Reentrant - yes + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to configure + * @param maximumFrameSize UINT32 [in] - maximum frame size to configure + * + * @retval IX_ETH_DB_SUCCESS the port is configured + * @retval IX_ETH_DB_PORT_UNINITIALIZED the port has not been initialized + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_INVALID_ARG size parameter is out of range + * @retval IX_ETH_DB_NO_PERMISSION selected port is not an Ethernet NPE + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note + * This maximum frame size is used to filter the frames based on their + * destination addresses and the capabilities of the destination port. + * The mximum value that can be set for a NPE port is 16320. + * (IX_ETHNPE_ACC_FRAME_LENGTH_MAX) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Populate the Ethernet learning/filtering database with a static MAC address + * + * Populates the Ethernet learning/filtering database with a static MAC address. The entry will not be subject to aging. + * If there is an entry (static or dynamic) with the corresponding MAC address on any port this entry will take precedence. + * Any other entry with the same MAC address will be removed. + * + * - Reentrant - yes + * - ISR Callable - yes + * + * @param portID @ref IxEthDBPortId [in] - port ID to add the static address to + * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add + * + * @retval IX_ETH_DB_SUCCESS the add was successful + * @retval IX_ETH_DB_FAIL failed to populate the database entry + * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringStaticEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Populate the Ethernet learning/filtering database with a dynamic MAC address + * + * Populates the Ethernet learning/filtering database with a dynamic MAC address. This entry will be subject to normal + * aging function, if aging is enabled on its port. + * If there is an entry (static or dynamic) with the same MAC address on any port this entry will take precedence. + * Any other entry with the same MAC address will be removed. + * + * - Reentrant - yes + * - ISR Callable - yes + * + * @param portID @ref IxEthDBPortId [in] - port ID to add the dynamic address to + * @param macAddr @ref IxEthDBMacAddr [in] - static MAC address to add + * + * @retval IX_ETH_DB_SUCCESS the add was successful + * @retval IX_ETH_DB_FAIL failed to populate the database entry + * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDynamicEntryProvision(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr) + * + * @brief Removes a MAC address entry from the Ethernet learning/filtering database + * + * @param macAddr IxEthDBMacAddr [in] - MAC address to remove + * + * - Reentrant - yes + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS the removal was successful + * @retval IX_ETH_DB_NO_SUCH_ADDR failed to remove the address (not in the database) + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_BUSY failed due to a temporary busy condition (i.e. lack of CPU cycles), try again later + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringEntryDelete(IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Search the Ethernet learning/filtering database for the given MAC address and port ID + * + * This functions searches the database for a specific port ID and MAC address. Both the port ID + * and the MAC address have to match in order for the record to be reported as found. + * + * - Reentrant - yes + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to search for + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for + * + * @retval IX_ETH_DB_SUCCESS the record exists in the database + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringPortSearch(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) + * + * @brief Search the Ethernet learning/filtering database for a MAC address and return the port ID + * + * Searches the database for a MAC address. The function returns the portID for the + * MAC address record, if found. If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR. + * The portID is only valid if the function finds a match. + * + * - Reentrant - yes + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID the address belongs to (populated only on a successful search) + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to search for + * + * @retval IX_ETH_DB_SUCCESS the record exists in the database + * @retval IX_ETH_DB_NO_SUCH_ADDR the record was not found in the database + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDatabaseSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr) + * + * @brief Search the filtering database for a MAC address, return the port ID and reset the record age + * + * Searches the database for a MAC address. The function returns the portID for the + * MAC address record and resets the entry age to 0, if found. + * If no match is found the function returns IX_ETH_DB_NO_SUCH_ADDR. + * The portID is only valid if the function finds a match. + * + * - Reentrant - yes + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS the MAC address was found + * @retval IX_ETH_DB_NO_SUCH_ADDR the MAC address was not found + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or portID pointer argument(s) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringPortUpdatingSearch(IxEthDBPortId *portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @def IX_ETH_DB_MAINTENANCE_TIME + * + * @brief The @ref ixEthDBDatabaseMaintenance must be called by the user at a frequency of + * IX_ETH_DB_MAINTENANCE_TIME + * + */ +#define IX_ETH_DB_MAINTENANCE_TIME (1 * 60) /* 1 Minute */ + +/** + * @ingroup IxEthDB + * + * @def IX_ETH_DB_LEARNING_ENTRY_AGE_TIME + * + * @brief The define specifies the filtering database age entry time. Static entries older than + * IX_ETH_DB_LEARNING_ENTRY_AGE_TIME +/- IX_ETH_DB_MAINTENANCE_TIME shall be removed. + * + */ +#define IX_ETH_DB_LEARNING_ENTRY_AGE_TIME (15 * 60 ) /* 15 Mins */ + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID) + * + * @brief Disable the aging function for a specific port + * + * @param portID @ref IxEthDBPortId [in] - port ID to disable aging on + * + * - Reentrant - yes + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS aging disabled successfully + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortAgingDisable(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID) + * + * @brief Enable the aging function for a specific port + * + * Enables the aging of dynamic MAC address entries stored in the learning/filtering database + * + * @note The aging function relies on the @ref ixEthDBDatabaseMaintenance being called with a period of + * @ref IX_ETH_DB_MAINTENANCE_TIME seconds. + * + * - Reentrant - yes + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to enable aging on + * + * @retval IX_ETH_DB_SUCCESS aging enabled successfully + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE learning feature is disabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortAgingEnable(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn void ixEthDBDatabaseMaintenance(void) + * + * @brief Performs a maintenance operation on the Ethernet learning/filtering database + * + * In order to perform a database maintenance this function must be called every + * @ref IX_ETH_DB_MAINTENANCE_TIME seconds. It should be called regardless of whether learning is + * enabled or not. + * + * - Reentrant - no + * - ISR Callable - no + * + * @note this function call will be ignored if the learning feature is disabled + */ +IX_ETH_DB_PUBLIC +void ixEthDBDatabaseMaintenance(void); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID) + * + * @brief This function displays the Mac Ethernet MAC address filtering tables. + * + * It displays the MAC address, port ID, entry type (dynamic/static),and age for + * the given port ID. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to display the MAC address entries + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized + * @retval IX_ETH_DB_FAIL record browser failed due to an internal busy or lock condition + * + * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead + * + * @see ixEthDBFilteringDatabaseShowRecords + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDatabaseShow(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn void ixEthDBFilteringDatabaseShowAll(void) + * + * @brief Displays the MAC address recorded in the filtering database for all registered + * ports (see IxEthDBPortDefs.h), grouped by port ID. + * + * - Reentrant - no + * - ISR Callable - no + * + * @retval void + * + * @note this function is deprecated and kept for compatibility reasons; use @ref ixEthDBFilteringDatabaseShowRecords instead + * + * @see ixEthDBFilteringDatabaseShowRecords + */ +IX_ETH_DB_PUBLIC +void ixEthDBFilteringDatabaseShowAll(void); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter) + * + * @brief This function displays per port database records, given a record type filter + * + * The supported record type filters are: + * + * - IX_ETH_DB_FILTERING_RECORD - displays the non-VLAN filtering records (MAC address, age, static/dynamic) + * - IX_ETH_DB_FILTERING_VLAN_RECORD - displays the VLAN filtering records (MAC address, age, static/dynamic, VLAN ID, CFI, QoS class) + * - IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD - displays the previous two types of records + * - IX_ETH_DB_WIFI_RECORD - displays the WiFi header conversion records (MAC address, optional gateway MAC address) and WiFi header conversion parameters (BBSID, Duration/ID) + * - IX_ETH_DB_FIREWALL_RECORD - displays the firewall MAC address table and firewall operating mode (white list/black list) + * - IX_ETH_DB_ALL_RECORD_TYPES - displays all the record types + * - IX_ETH_DB_NO_RECORD_TYPE - displays only the port status (no records are displayed) + * + * Additionally, the status of each port will be displayed, containg the following information: type, capabilities, enabled status, + * aging enabled status, group membership and maximum frame size. + * + * The port ID can either be an actual port or IX_ETH_DB_ALL_PORTS, in which case the requested information + * will be displayed for all the ports (grouped by port) + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID ID of the port to display information on (use IX_ETH_DB_ALL_PORTS for all the ports) + * @param recordFilter record type filter + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is invalid + * @retval IX_ETH_DB_PORT_UNINITIALIZED port ID is not initialized + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFilteringDatabaseShowRecords(IxEthDBPortId portID, IxEthDBRecordType recordFilter); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) + * + * @brief Sets the dependency port map for a port + * + * @param portID ID of the port to set the dependency map to + * @param dependencyPortMap new dependency map (as bitmap, each bit set indicates a port being included) + * + * This function is used to share filtering information between ports. + * By adding a port into another port's dependency map the target port + * filtering data will import the filtering data from the port it depends on. + * Any changes to filtering data for a port - such as adding, updating or removing records - + * will trigger updates in the filtering information for all the ports depending on + * on the updated port. + * + * For example, if ports 2 and 3 are set in the port 0 dependency map the filtering + * information for port 0 will also include the filtering information from ports 2 and 3. + * Adding a record to port 2 will also trigger an update not only on port 2 but also on + * port 0. + * + * The dependency map is a 256 bit array where each bit corresponds to a port corresponding to the + * bit offset (bit 0 - port 0, bit 1 - port 1 etc). Setting a bit to 1 indicates that the corresponding + * port is the port map. For example, a dependency port map of 0x14 consists in the ports with IDs 2 and 4. + * Note that the last bit (offset 255) is reserved and should never be set (it will be automatically + * cleared by the function). + * + * By default, each port has a dependency port map consisting only of itself, i.e. + * + * @verbatim + IxEthDBPortMap portMap; + + // clear all ports from port map + memset(portMap, 0, sizeof (portMap)); + + // include portID in port map + portMap[portID / 8] = 1 << (portID % 8); + @endverbatim + * + * - Reentrant - no + * - ISR Callable - no + * + * @note Setting dependency maps is useful for NPE ports, which benefit from automatic updates + * of filtering information. Setting dependency maps for user-defined ports is not an error + * but will have no actual effect. + * + * @note Including a port in its own dependency map is not compulsory, however note that + * in this case updating the port will not trigger an update on the port itself, which + * might not be the intended behavior + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid dependencyPortMap pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortDependencyMapSet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap) + * + * @brief Retrieves the dependency port map for a port + * + * @param portID ID of the port to set the dependency map to + * @param dependencyPortMap location where the port dependency map is to be copied + * + * This function will copy the port dependency map to a user specified location. + * + * - Reentrant - no + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid dependencyPortMap pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Filtering is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortDependencyMapGet(IxEthDBPortId portID, IxEthDBPortMap dependencyPortMap); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag) + * + * @brief Sets the default 802.1Q VLAN tag for a given port + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to set the default VLAN tag to + * @param vlanTag @ref IxEthDBVlanTag [in] - default 802.1Q VLAN tag + * + * The tag format has 16 bits and it is defined in the IEEE802.1Q specification. + * This tag will be used for tagging untagged frames (if enabled) and classifying + * unexpedited traffic into an internal traffic class (using the user priority field). + * + * + *
802.1Q tag format
3 bits 1 bit 12 bits + *
user priority CFI VID + *
+ * + * User Priority : Defines user priority, giving eight (2^3) priority levels. IEEE 802.1P defines + * the operation for these 3 user priority bits + * + * CFI : Canonical Format Indicator is always set to zero for Ethernet switches. CFI is used for + * compatibility reason between Ethernet type network and Token Ring type network. If a frame received + * at an Ethernet port has a CFI set to 1, then that frame should not be forwarded as it is to an untagged port. + * + * VID : VLAN ID is the identification of the VLAN, which is basically used by the standard 802.1Q. + * It has 12 bits and allow the id entification of 4096 (2^12) VLANs. Of the 4096 possible VIDs, a VID of 0 + * is used to identify priority frames and value 4095 (FFF) is reserved, so the maximum possible VLAN + * configurations are 4,094. + * + * - Reentrant - no + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_ETH_DB_INVALID_VLAN vlanTag argument does not parse to a valid 802.1Q VLAN tag + * + * @note a VLAN ID value of 0 indicates that the port is not part of any VLAN + * @note the value of the cannonical frame indicator (CFI) field is ignored, the + * field being used only in frame tagging operations + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag) + * + * @brief Retrieves the default 802.1Q port VLAN tag for a given port (see also @ref ixEthDBPortVlanTagSet) + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the default VLAN tag from + * @param vlanTag @ref IxEthDBVlanTag [out] - location to write the default port 802.1Q VLAN tag to + * + * - Reentrant - no + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid vlanTag pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag) + * + * @brief Sets the 802.1Q VLAN tag for a database record + * + * @param macAddr MAC address + * @param vlanTag 802.1Q VLAN tag + * + * This function is used together with @ref ixEthDBVlanTagGet to provide MAC-based VLAN classification support. + * Please note that the bridging application must contain specific code to make use of this feature (see below). + * + * VLAN tags can be set only in IX_ETH_DB_FILTERING_RECORD or IX_ETH_DB_FILTERING_VLAN_RECORD type records. + * If to an IX_ETH_DB_FILTERING_RECORD type record is added a VLAN tag the record type is automatically + * changed to IX_ETH_DB_FILTERING_VLAN_RECORD. Once this has occurred the record type will never + * revert to a non-VLAN type (unless deleted and re-added). + * + * Record types used for different purposes (such as IX_ETH_DB_WIFI_RECORD) will be ignored by + * this function. + * + * After using this function to associate a VLAN ID with a MAC address the VLAN ID can be extracted knowing the + * MAC address using @ref ixEthDBVlanTagGet. This mechanism can be used to implement MAC-based VLAN classification + * if a bridging application searches for the VLAN tag when receiving a frame based on the source MAC address + * (contained in the ixp_ne_src_mac field of the buffer header). + * If found in the database, the application can instruct the NPE to tag the frame by writing the VLAN tag + * in the ixp_ne_vlan_tci field of the buffer header. This way the NPE will inspect the Egress tagging + * rule associated with the given VLAN ID on the Tx port and tag the frame if Egress tagging on the VLAN is + * allowed. Additionally, Egress tagging can be forced by setting the ixp_ne_tx_flags.tag_over and + * ixp_ne_tx_flags.tag_mode flags in the buffer header. + * + * - Reentrant - no + * - ISR Callable - no + * + * @note this function will not add a filtering record, it can only be used to update an existing one + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer + * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found + * @retval IX_ETH_DB_INVALID_VLAN vlanTag argument does not parse to a valid 802.1Q VLAN tag + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag); + +/** + * @ingroup IxEthDB + * + * @fn ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag) + * + * @brief Retrieves the 802.1Q VLAN tag from a database record given the record MAC address + * + * @param macAddr MAC address + * @param vlanTag location to write the record 802.1Q VLAN tag to + * + * @note VLAN tags can be retrieved only from IX_ETH_DB_FILTERING_VLAN_RECORD type records + * + * This function is used together with ixEthDBVlanTagSet to provide MAC-based VLAN classification support. + * Please note that the bridging application must contain specific code to make use of this feature (see @ref ixEthDBVlanTagSet). + * + * - Reentrant - no + * - ISR Callable - no + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or vlanTag pointer + * @retval IX_ETH_DB_NO_SUCH_ADDR a filtering record with the specified MAC address was not found + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID) + * + * @brief Adds a VLAN ID to a port's VLAN membership table + * + * Adding a VLAN ID to a port's VLAN membership table will cause frames tagged with the specified + * VLAN ID to be accepted by the frame filter, if Ingress VLAN membership filtering is enabled. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to add the VLAN ID membership to + * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be added to the port membership table + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note A port's default VLAN ID is always in its own membership table, hence there + * is no need to explicitly add it using this function (although it is not an error + * to do so) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) + * + * @brief Adds a VLAN ID range to a port's VLAN membership table + * + * All the VLAN IDs in the specified range will be added to the port VLAN + * membership table, including the range start and end VLAN IDs. Tagged frames with + * VLAN IDs in the specified range will be accepted by the frame filter, if Ingress VLAN + * membership filtering is enabled. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to add the VLAN membership range into + * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range + * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case this + * function will behave as @ref ixEthDBPortVlanMembershipAdd + * + * @note A port's default VLAN ID is always in its own membership table, hence there is no need + * to explicitly add it using this function (although it is not an error to do so) + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID) + * + * @brief Removes a VLAN ID from a port's VLAN membership table + * + * Frames tagged with a VLAN ID which is not in a port's VLAN membership table + * will be discarded by the frame filter, if Ingress membership filtering is enabled. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN ID membership from + * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be removed from the port membership table + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_INVALID_VLAN vlanID is not a valid VLAN ID + * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID + * from the port membership table (vlanID was set to the default port VLAN ID) + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note A port's default VLAN ID cannot be removed from the port's membership + * table; attempting it will return IX_ETH_DB_NO_PERMISSION + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax) + * + * @brief Removes a VLAN ID range from a port's VLAN membership table + * + * All the VLAN IDs in the specified range will be removed from the port VLAN + * membership table, including the range start and end VLAN IDs. Tagged frames + * with VLAN IDs in the range will be discarded by the frame filter, if Ingress + * membership filtering is enabled. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to remove the VLAN membership range from + * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN ID range + * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN ID range + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN the specified VLAN IDs are invalid or do not constitute a range + * @retval IX_ETH_DB_NO_PERMISSION attempted to remove the default VLAN ID + * from the port membership table (both vlanIDMin and vlanIDMax were set to the default port VLAN ID) + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note Is is valid to use the same VLAN ID for both vlanIDMin and vlanIDMax, in which case + * function will behave as @ref ixEthDBPortVlanMembershipRemove + * + * @note If the given range overlaps the default port VLAN ID this function + * will remove all the VLAN IDs in the range except for the port VLAN ID from its + * own membership table. This situation will be silently dealt with (no error message + * will be returned) as long as the range contains more than one value (i.e. at least + * one other value, apart from the default port VLAN ID). If the function is called + * with the vlanIDMin and vlanIDMax parameters both set to the port default VLAN ID, the + * function will infer that an attempt was specifically made to remove the default port + * VLAN ID from the port membership table, in which case the return value will be + * IX_ETH_DB_NO_PERMISSION. + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) + * + * @brief Sets a port's VLAN membership table + * + * Sets a port's VLAN membership table from a complete VLAN table containing all the possible + * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit + * indicates whether the VLAN at that bit index is in the port's membership list (if set) or + * not (unset). + * + * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no + * other bit must be set if bit 0 is set. + * + * The bit at index 4095 is reserved and should never be set (it will be ignored if set). + * + * The bit referencing the same VLAN ID as the default port VLAN ID should always be set, as + * the membership list must contain at least the default port VLAN ID. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to set the VLAN membership table to + * @param vlanSet @ref IxEthDBVlanSet [in] - pointer to the VLAN membership table + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) + * + * @brief Retrieves a port's VLAN membership table + * + * Retrieves the complete VLAN membership table from a port, containing all the possible + * 4096 VLAN IDs. The table format is an array containing 4096 bits (512 bytes), where each bit + * indicates whether the VLAN at that bit index is in the port's membership list (if set) or + * not (unset). + * + * The bit at index 0, indicating VLAN ID 0, indicates no VLAN membership and therefore no + * other bit will be set if bit 0 is set. + * + * The bit at index 4095 is reserved and will not be set (it will be ignored if set). + * + * The bit referencing the same VLAN ID as the default port VLAN ID will always be set, as + * the membership list must contain at least the default port VLAN ID. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the VLAN membership table from + * @param vlanSet @ref IxEthDBVlanSet [out] - pointer a location where the VLAN membership table will be + * written to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter) + * + * @brief Sets a port's acceptable frame type filter + * + * The acceptable frame type is one (or a combination) of the following values: + * - IX_ETH_DB_ACCEPT_ALL_FRAMES - accepts all the frames + * - IX_ETH_DB_UNTAGGED_FRAMES - accepts untagged frames + * - IX_ETH_DB_VLAN_TAGGED_FRAMES - accepts tagged frames + * - IX_ETH_DB_PRIORITY_TAGGED_FRAMES - accepts tagged frames with VLAN ID set to 0 (no VLAN membership) + * + * Except for using the exact values given above only the following combinations are valid: + * - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES + * - IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_PRIORITY_TAGGED_FRAMES + * + * Please note that IX_ETH_DB_UNTAGGED_FRAMES | IX_ETH_DB_VLAN_TAGGED_FRAMES is equivalent + * to IX_ETH_DB_ACCEPT_ALL_FRAMES. + * + * - Reentrant - no + * - ISR Callable - no + * + * @note by default the acceptable frame type filter is set to IX_ETH_DB_ACCEPT_ALL_FRAMES + * + * @note setting the acceptable frame type to PRIORITY_TAGGED_FRAMES is internally + * accomplished by changing the frame filter to VLAN_TAGGED_FRAMES and setting the + * VLAN membership list to include only VLAN ID 0; the membership list will need + * to be restored manually to an appropriate value if the acceptable frame type + * filter is changed back to ACCEPT_ALL_FRAMES or VLAN_TAGGED_FRAMES; failure to do so + * will filter all VLAN traffic bar frames tagged with VLAN ID 0 + * + * @param portID @ref IxEthDBPortId [in] - port ID to set the acceptable frame type filter to + * @param frameFilter @ref IxEthDBFrameFilter [in] - acceptable frame type filter + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid frame type filter + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter) + * + * @brief Retrieves a port's acceptable frame type filter + * + * For a description of the acceptable frame types see @ref ixEthDBAcceptableFrameTypeSet + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID to retrieve the acceptable frame type filter from + * @param frameFilter @ref IxEthDBFrameFilter [out] - location to store the acceptable frame type filter + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid frameFilter pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) + * + * @brief Sets a port's priority mapping table + * + * The priority mapping table is an 8x2 table mapping a QoS (user) priority into an internal + * traffic class. There are 8 valid QoS priorities (0..7, 0 being the lowest) which can be + * mapped into one of the 4 available traffic classes (0..3, 0 being the lowest). + * If a custom priority mapping table is not specified using this function the following + * default priority table will be used (as per IEEE 802.1Q and IEEE 802.1D): + * + * + *
QoS traffic classes
QoS priority Default traffic class Traffic type + *
0 1 Best effort, default class for unexpedited traffic + *
1 0 Background traffic + *
2 0 Spare bandwidth + *
3 1 Excellent effort + *
4 2 Controlled load + *
5 2 Video traffic + *
6 3 Voice traffic + *
7 3 Network control + *
+ * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - port ID of the port to set the priority mapping table to + * @param priorityTable @ref IxEthDBPriorityTable [in] - location of the user priority table + * + * @note The provided table will be copied into internal data structures in EthDB and + * can be deallocated by the called after this function has completed its execution, if + * so desired + * + * @warning The number of available traffic classes differs depending on the NPE images + * and queue configuration. Check IxEthDBQoS.h for up-to-date information on the availability of + * traffic classes. Note that specifiying a traffic class in the priority map which exceeds + * the system availability will produce an IX_ETH_DB_INVALID_PRIORITY return error code and no + * priority will be remapped. + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid priorityTable pointer + * @retval IX_ETH_DB_INVALID_PRIORITY at least one priority value exceeds + * the current number of available traffic classes + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable) + * + * @brief Retrieves a port's priority mapping table + * + * The priority mapping table for the given port will be copied in the location + * specified by the caller using "priorityTable" + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID ID @ref IxEthDBPortId [in] - of the port to retrieve the priority mapping table from + * @param priorityTable @ref IxEthDBPriorityTable [out] - pointer to a user specified location where the table will be copied to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid priorityTable pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass) + * + * @brief Sets one QoS/user priority => traffic class mapping in a port's priority mapping table + * + * This function establishes a mapping between a user (QoS) priority and an internal traffic class. + * The mapping will be saved in the port's priority mapping table. Use this function when not all + * the QoS priorities need remapping (see also @ref ixEthDBPriorityMappingTableSet) + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to + * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest) + * @param trafficClass @ref IxEthDBPriority [in] - internal traffic class, between 0 and 3 (0 being the lowest) + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_PRIORITY userPriority out of range or + * trafficClass is beyond the number of currently available traffic classes + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass) + * + * @brief Retrieves one QoS/user priority => traffic class mapping in a port's priority mapping table + * + * This function retrieves the internal traffic class associated with a QoS (user) priority from a given + * port's priority mapping table. Use this function when not all the QoS priority mappings are + * required (see also @ref ixEthDBPriorityMappingTableGet) + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to set the mapping to + * @param userPriority @ref IxEthDBPriority [in] - user (QoS) priority, between 0 and 7 (0 being the lowest) + * @param trafficClass @ref IxEthDBPriority [out] - location to write the corresponding internal traffic class to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_PRIORITY invalid userPriority value (out of range) + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_ETH_DB_INVALID_ARG invalid trafficClass pointer argument + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled) + * + * @brief Enables or disables Egress VLAN tagging for a port and a given VLAN + * + * This function enables or disables Egress VLAN tagging for the given port and VLAN ID. + * If the VLAN tagging for a certain VLAN ID is enabled then all the frames to be + * transmitted on the given port tagged with the same VLAN ID will be transmitted in a tagged format. + * If tagging is not enabled for the given VLAN ID, the VLAN tag from the frames matching + * this VLAN ID will be removed (the frames will be untagged). + * + * VLAN ID 4095 is reserved and should never be used with this function. + * VLAN ID 0 has the special meaning of "No VLAN membership" and it is used in this + * context to allow the port to send priority-tagged frames or not. + * + * By default, no Egress VLAN tagging is enabled on any port. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on + * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID to be matched against outgoing frames + * @param enabled BOOL [in] - TRUE to enable Egress VLAN tagging on the port and given VLAN, and + * FALSE to disable Egress VLAN tagging + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range) + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled) + * + * @brief Retrieves the Egress VLAN tagging enabling status for a port and VLAN ID + * + * @param portID [in] - ID of the port to extract the Egress VLAN ID tagging status from + * @param vlanID VLAN [in] - ID whose tagging status is to be extracted + * @param enabled [in] - user-specifed location where the status is copied to; following + * the successfull execution of this function the value will be TRUE if Egress VLAN + * tagging is enabled for the given port and VLAN ID, and FALSE otherwise + * + * - Reentrant - no + * - ISR Callable - no + * + * @see ixEthDBEgressVlanEntryTaggingEnabledGet + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range) + * @retval IX_ETH_DB_INVALID_ARG invalid enabled argument pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled) + * + * @brief Enables or disables Egress VLAN tagging for a port and given VLAN range + * + * This function is very similar to @ref ixEthDBEgressVlanEntryTaggingEnabledSet with the + * difference that it can manipulate the Egress tagging status on multiple VLAN IDs, + * defined by a contiguous range. Note that both limits in the range are explicitly + * included in the execution of this function. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the VLAN ID Egress tagging on + * @param vlanIDMin @ref IxEthDBVlanId [in] - start of the VLAN range to be matched against outgoing frames + * @param vlanIDMax @ref IxEthDBVlanId [in] - end of the VLAN range to be matched against outgoing frames + * @param enabled BOOL [in] - TRUE to enable Egress VLAN tagging on the port and given VLAN range, + * and FALSE to disable Egress VLAN tagging + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_VLAN invalid VLAN ID (out of range), or do not constitute a range + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_ETH_DB_NO_PERMISSION attempted to explicitly remove the default port VLAN ID from the tagging table + * @retval IX_FAIL unknown OS or NPE communication error + * + * @note Specifically removing the default port VLAN ID from the Egress tagging table by setting both vlanIDMin and vlanIDMax + * to the VLAN ID portion of the PVID is not allowed by this function and will return IX_ETH_DB_NO_PERMISSION. + * However, this can be circumvented, should the user specifically desire this, by either using a + * larger range (vlanIDMin < vlanIDMax) or by using ixEthDBEgressVlanEntryTaggingEnabledSet. + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) + * + * @brief Sets the complete Egress VLAN tagging table for a port + * + * This function is used to set the VLAN tagging/untagging per VLAN ID for a given port + * covering the entire VLAN ID range (0..4094). The vlanSet parameter is a 4096 + * bit array, each bit indicating the Egress behavior for the corresponding VLAN ID. + * If a bit is set then outgoing frames with the corresponding VLAN ID will be transmitted + * with the VLAN tag, otherwise the frame will be transmitted without the VLAN tag. + * + * Bit 0 has a special significance, indicating tagging or tag removal for priority-tagged + * frames. + * + * Bit 4095 is reserved and should never be set (it will be ignored if set). + * + * - Reentrant - no + * - ISR Callable - no + * + * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is set + * @param vlanSet @ref IxEthDBVlanSet [in] - 4096 bit array controlling per-VLAN tagging and untagging + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + * + * @warning This function will automatically add the default port VLAN ID to the Egress tagging table + * every time it is called. The user should manually call ixEthDBEgressVlanEntryTaggingEnabledSet to + * prevent tagging on the default port VLAN ID if the default behavior is not intended. + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet) + * + * @brief Retrieves the complete Egress VLAN tagging table from a port + * + * This function copies the 4096 bit table controlling the Egress VLAN tagging into a user specified + * area. Each bit in the array indicates whether tagging for the corresponding VLAN (the bit position + * in the array) is enabled (the bit is set) or not (the bit is unset). + * + * Bit 4095 is reserved and should not be set (it will be ignored if set). + * + * @see ixEthDBEgressVlanTaggingEnabledSet + * + * @param portID @ref IxEthDBPortId [in] - ID of the port whose Egress VLAN tagging behavior is retrieved + * @param vlanSet @ref IxEthDBVlanSet [out] - user location to copy the Egress tagging table into; should have + * room to store 4096 bits (512 bytes) + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid vlanSet pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction) + * + * @brief Sets the Ingress VLAN tagging behavior for a port + * + * A port's Ingress tagging behavior is controlled by the taggingAction parameter, + * which can take one of the following values: + * + * - IX_ETH_DB_PASS_THROUGH - leaves the frame unchanged (does not add or remove the VLAN tag) + * - IX_ETH_DB_ADD_TAG - adds the VLAN tag if not present, using the default port VID + * - IX_ETH_DB_REMOVE_TAG - removes the VLAN tag if present + * + * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set + * @param taggingAction @ref IxEthDBTaggingAction [in] - tagging behavior for the port + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid taggingAction argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction) + * + * @brief Retrieves the Ingress VLAN tagging behavior from a port (see @ref ixEthDBIngressVlanTaggingEnabledSet) + * + * @param portID @ref IxEthDBPortId [in] - ID of the port whose Ingress VLAN tagging behavior is set + * @param taggingAction @ref IxEthDBTaggingAction [out] - location where the tagging behavior for the port is written to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid taggingAction pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable) + * + * @brief Enables or disables port ID extraction + * + * This feature can be used in the situation when a multi-port device (e.g. a switch) + * is connected to an IXP4xx port and the device can provide incoming frame port + * identification by tagging the TPID field in the Ethernet frame. Enabling + * port extraction will instruct the NPE to copy the TPID field from the frame and + * place it in the ixp_ne_src_port of the ixp_buf header. In addition, + * the NPE restores the TPID field to 0. + * + * If the frame is not tagged the NPE will fill the ixp_ne_src_port with the + * port ID of the MII interface the frame was received from. + * + * The TPID field is the least significant byte of the type/length field, which is + * normally set to 0x8100 for 802.1Q-tagged frames. + * + * This feature is disabled by default. + * + * @param portID ID of the port to configure port ID extraction on + * @param enable TRUE to enable port ID extraction and FALSE to disable it + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE VLAN/QoS feature is not available or not enabled for the port + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet) + * + * @brief Retrieves the feature capability set for a port + * + * This function retrieves the feature capability set for a port or the common capabilities shared between all + * the ports, writing the feature capability set in a user specified location. + * + * The feature capability set will consist of a set formed by OR-ing one or more of the following values: + * - IX_ETH_DB_LEARNING - Learning feature; enables EthDB to learn MAC address (filtering) records, including 802.1Q enabled records + * - IX_ETH_DB_FILTERING - Filtering feature; enables EthDB to communicate with the NPEs for downloading filtering information in the NPEs; depends on the learning feature + * - IX_ETH_DB_VLAN_QOS - VLAN/QoS feature; enables EthDB to configure NPEs to operate in VLAN/QoS aware modes + * - IX_ETH_DB_FIREWALL - Firewall feature; enables EthDB to configure NPEs to operate in firewall mode, using white/black address lists + * - IX_ETH_DB_SPANNING_TREE_PROTOCOL - Spanning tree protocol feature; enables EthDB to configure the NPEs as STP nodes + * - IX_ETH_DB_WIFI_HEADER_CONVERSION - WiFi 802.3 to 802.11 header conversion feature; enables EthDB to handle WiFi conversion data + * + * Note that EthDB provides only the LEARNING feature for non-NPE ports. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to retrieve the capability set for + * (use IX_ETH_DB_ALL_PORTS to retrieve the common capabilities shared between all the ports) + * @param featureSet @ref IxEthDBFeature [out] - location where the capability set will be written to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid featureSet pointer + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeatureCapabilityGet(IxEthDBPortId portID, IxEthDBFeature *featureSet); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled) + * + * @brief Enables or disables one or more EthDB features + * + * Selects one or more features (see @ref ixEthDBFeatureCapabilityGet for a description of the supported + * features) to be enabled or disabled on the selected port (or all the ports). + * + * Note that some features are mutually incompatible: + * - IX_ETH_DB_FILTERING is incompatible with IX_ETH_DB_WIFI_HEADER_CONVERSION + * + * Also note that some features require other features to be enabled: + * - IX_ETH_DB_FILTERING requires IX_ETH_DB_LEARNING + * + * This function will either enable the entire selected feature set for the selected port (or all the ports), + * in which case it will return IX_ETH_DB_SUCCESS, or in case of error it will not enable any feature at all + * and return an appropriate error message. + * + * The following features are enabled by default (for ports with the respective capability), + * for compatibility reasons with previous versions of CSR: + * - IX_ETH_DB_LEARNING + * - IX_ETH_DB_FILTERING + * + * All other features are disabled by default and require manual enabling using ixEthDBFeatureEnable. + * + * Default settings for VLAN, QoS, Firewall and WiFi header conversion features: + * + * VLAN + * + * When the VLAN/QoS feature is enabled for a port for the first time the default VLAN behavior + * of the port is set to be as permissive (it will accept all the frames) and + * non-interferential (it will not change any frames) as possible: + * - the port VLAN ID (VID) is set to 0 + * - the Ingress acceptable frame filter is set to accept all frames + * - the VLAN port membership is set to the complete VLAN range (0 - 4094) + * - the Ingress tagging mode is set to pass-through (will not change frames) + * - the Egress tagging mode is to send tagged frames in the entire VLAN range (0 - 4094) + * + * Note that further disabling and re-enabling the VLAN feature for a given port will not reset the port VLAN behavior + * to the settings listed above. Any VLAN settings made by the user are kept. + * + * QoS + * + * The following default priority mapping table will be used (as per IEEE 802.1Q and IEEE 802.1D): + * + * + *
QoS traffic classes
QoS priority Default traffic class Traffic type + *
0 1 Best effort, default class for unexpedited traffic + *
1 0 Background traffic + *
2 0 Spare bandwidth + *
3 1 Excellent effort + *
4 2 Controlled load + *
5 2 Video traffic + *
6 3 Voice traffic + *
7 3 Network control + *
+ * + * Firewall + * + * The port firewall is configured by default in black-list mode, and the firewall address table is empty. + * This means the firewall will not filter any frames until the feature is configured and the firewall table is + * downloaded to the NPE. + * + * Spanning Tree + * + * The port is set to STP unblocked mode, therefore it will accept all frames until re-configured. + * + * WiFi header conversion + * + * The WiFi header conversion database is empty, therefore no actual header conversion will take place until this + * feature is configured and the conversion table downloaded to the NPE. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port to enable or disable the features on (use IX_ETH_DB_ALL_PORTS for all the ports) + * @param feature @ref IxEthDBFeature [in] - feature or feature set to enable or disable + * @param enabled BOOL [in] - TRUE to enable the feature and FALSE to disable it + * + * @note Certain features, from a functional point of view, cannot be disabled as such at NPE level; + * when such features are set to disabled using the EthDB API they will be configured in such + * a way to determine a behavior equivalent to the feature being disabled. As well as this, disabled + * features cannot be configured or accessed via the EthDB API (except for getting their status). + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_NO_PERMISSION attempted to enable mutually exclusive features, + * or a feature that depends on another feature which is not present or enabled + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE at least one of the features selected is unavailable + * @retval IX_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeatureEnable(IxEthDBPortId portID, IxEthDBFeature feature, BOOL enabled); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled) + * + * @brief Retrieves the availability and status of a feature set + * + * This function returns the availability and status for a feature set. + * Note that if more than one feature is selected (e.g. IX_ETH_DB_LEARNING | IX_ETH_DB_FILTERING) + * the "present" and "enabled" return values will be set to TRUE only if all the features in the + * feature set are present and enabled (not only some). + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param feature @ref IxEthDBFeature [in] - identifier of the feature to retrieve the status for + * @param present BOOL [out] - location where a boolean flag indicating whether this feature is present will be written to + * @param enabled BOOL [out] - location where a boolean flag indicating whether this feature is enabled will be written to + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG either present or enabled pointer argument is invalid + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeatureStatusGet(IxEthDBPortId portID, IxEthDBFeature feature, BOOL *present, BOOL *enabled); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value) + * + * @brief Retrieves the value of a feature property + * + * The EthDB features usually contain feature-specific properties describing or + * controlling how the feature operates. While essential properties (e.g. the + * firewall operating mode) have their own API, secondary properties can be + * retrieved using this function. + * + * Properties can be read-only or read-write. ixEthDBFeaturePropertyGet operates with + * both types of features. + * + * Properties have types associated with them. A descriptor indicating the property + * type is returned in the type argument for convenience. + * + * The currently supported properties and their corresponding features are as follows: + * + * + *
Properties for IX_ETH_DB_VLAN_QOS
Property identifier Property type Property value Read-Only + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_COUNT_PROPERTY IX_ETH_DB_INTEGER_PROPERTY number of internal traffic classes Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_0_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 0 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_1_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 1 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_2_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 2 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_3_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 3 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_4_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 4 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_5_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 5 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_6_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 6 Yes + *
IX_ETH_DB_QOS_TRAFFIC_CLASS_7_RX_QUEUE_PROPERTY IX_ETH_DB_INTEGER_PROPERTY queue assignment for traffic class 7 Yes + *
+ * + * @see ixEthDBFeaturePropertySet + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is retrieved + * @param property @ref IxEthDBProperty [in] - property identifier + * @param type @ref IxEthDBPropertyType [out] - location where the property type will be stored + * @param value void [out] - location where the property value will be stored + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, type or value pointer arguments + * @retval IX_ETH_DB_FAIL incorrect property value or unknown error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeaturePropertyGet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, IxEthDBPropertyType *type, void *value); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value) + * + * @brief Sets the value of a feature property + * + * Unlike @ref ixEthDBFeaturePropertyGet, this function operates only with read-write properties + * + * The currently supported properties and their corresponding features are as follows: + * + * - IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE (for IX_ETH_DB_VLAN_QOS): freezes the availability of traffic classes + * to the number of traffic classes currently in use + * + * Note that this function creates deep copies of the property values; once the function is invoked the client + * can free or reuse the memory area containing the original property value. + * + * Copy behavior for different property types is defined as follows: + * + * - IX_ETH_DB_INTEGER_PROPERTY - 4 bytes are copied from the source location + * - IX_ETH_DB_STRING_PROPERTY - the source string will be copied up to the NULL '\0' string terminator, maximum of 255 characters + * - IX_ETH_DB_MAC_ADDR_PROPERTY - 6 bytes are copied from the source location + * - IX_ETH_DB_BOOL_PROPERTY - 4 bytes are copied from the source location; the only allowed values are TRUE (1L) and false (0L) + * + * @see ixEthDBFeaturePropertySet + * + * @warning IX_ETH_DB_QOS_QUEUE_CONFIGURATION_COMPLETE is provided for EthAcc internal use; + * do not attempt to set this property directly + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param feature @ref IxEthDBFeature [in] - EthDB feature for which the property is set + * @param property @ref IxEthDBProperty [in] - property identifier + * @param value void [in] - location where the property value is to be copied from + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG invalid property identifier, value pointer, or invalid property value + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFeaturePropertySet(IxEthDBPortId portID, IxEthDBFeature feature, IxEthDBProperty property, void *value); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType) + * + * @brief Deletes a set of record types from the Ethernet Database + * + * This function deletes all the records of certain types (specified in the recordType filter) + * associated with a port. Additionally, the IX_ETH_DB_ALL_PORTS value can be used as port ID + * to indicate that the specified record types should be deleted for all the ports. + * + * The record type filter can be an ORed combination of the following types: + * + * Record types + * - IX_ETH_DB_FILTERING_RECORD + * + *
Filtering record
MAC address static/dynamic type age
+ * + * - IX_ETH_DB_FILTERING_VLAN_RECORD + * + *
VLAN-enabled filtering record
MAC address static/dynamic type age 802.1Q tag
+ * + * - IX_ETH_DB_WIFI_RECORD + * + *
WiFi header conversion record
MAC address optional gateway MAC address
+ * + * - IX_ETH_DB_FIREWALL_RECORD + * + *
Firewall record
MAC address
+ * - IX_ETH_DB_ALL_RECORD_TYPES + * + * Any combination of the above types is valid e.g. + * + * (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_FILTERING_VLAN_RECORD | IX_ETH_DB_FIREWALL_RECORD), + * + * although some might be redundant (it is not an error to do so) e.g. + * + * (IX_ETH_DB_FILTERING_RECORD | IX_ETH_DB_ALL_RECORD_TYPES) + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param recordType @ref IxEthDBRecordType [in] - record type filter + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG invalid recordType filter + * + * @note If the record type filter contains any unrecognized value (hence the + * IX_ETH_DB_INVALID_ARG error value is returned) no actual records will be deleted. + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBDatabaseClear(IxEthDBPortId portID, IxEthDBRecordType recordType); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Adds an "Access Point to Station" record to the database, for 802.3 => 802.11 frame + * header conversion + * + * Frame header conversion is controlled by the set of MAC addresses + * added using @ref ixEthDBWiFiStationEntryAdd and @ref ixEthDBWiFiAccessPointEntryAdd. + * Conversion arguments are added using @ref ixEthDBWiFiFrameControlSet, + * @ref ixEthDBWiFiDurationIDSet and @ref ixEthDBWiFiBBSIDSet. + * + * Note that adding the same MAC address twice will not return an error + * (but will not accomplish anything either), while re-adding a record previously added + * as an "Access Point to Access Point" will migrate the record to the "Access Point + * to Station" type. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NOMEM maximum number of records reached + * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiStationEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr) + * + * @brief Adds an "Access Point to Access Point" record to the database + * + * @see ixEthDBWiFiStationEntryAdd + * + * Note that adding the same MAC address twice will simply overwrite the previously + * defined gateway MAC address value in the same record, if the record was previously of the + * "Access Point to Access Point" type. + * + * Re-adding a MAC address as "Access Point to Access Point", which was previously added as + * "Access Point to Station" will migrate the record type to "Access Point to Access Point" and + * record the gateway MAC address. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to add + * @param gatewayMacAddr @ref IxEthDBMacAddr [in] - MAC address of the gateway Access Point + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG macAddr is an invalid pointer + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or gatewayMacAddr pointer argument + * @retval IX_ETH_DB_NOMEM maximum number of records reached + * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiAccessPointEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr, IxEthDBMacAddr *gatewayMacAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Removes a WiFi station record + * + * This function removes both types of WiFi records ("Access Point to Station" and + * "Access Point to Access Point"). + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to remove + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port is not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NO_SUCH_ADDR specified address was not found in the database + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID) + * + * @brief Downloads the MAC address table for 802.3 => 802.11 frame header + * conversion to the NPE + * + * Note that the frame conversion MAC address table must be individually downloaded + * to each NPE for which the frame header conversion feature is enabled (i.e. it + * is not possible to specify IX_ETH_DB_ALL_PORTS). + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiConversionTableDownload(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl) + * + * @brief Sets the GlobalFrameControl field + * + * The GlobalFrameControl field is a 2-byte value inserted in the Frame Control + * field for all 802.3 to 802.11 frame header conversions + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param frameControl UINT16 [in] - GlobalFrameControl value + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiFrameControlSet(IxEthDBPortId portID, UINT16 frameControl); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID) + * + * @brief Sets the GlobalDurationID field + * + * The GlobalDurationID field is a 2-byte value inserted in the Duration/ID + * field for all 802.3 to 802.11 frame header conversions + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param durationID UINT16 [in] - GlobalDurationID field + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiDurationIDSet(IxEthDBPortId portID, UINT16 durationID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid) + * + * @brief Sets the BBSID field + * + * The BBSID field is a 6-byte value which + * identifies the infrastructure of the service set managed + * by the Access Point having the IXP400 as its processor. The value + * is written in the BBSID field of the 802.11 frame header. + * The BBSID value is the MAC address of the Access Point. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param bbsid @ref IxEthDBMacAddr [in] - pointer to 6 bytes containing the BSSID + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid bbsid pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE WiFi feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBWiFiBBSIDSet(IxEthDBPortId portID, IxEthDBMacAddr *bbsid); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked) + * + * @brief Sets the STP blocked/unblocked state for a port + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param blocked BOOL [in] - TRUE to set the port as STP blocked, FALSE to set it as unblocked + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBSpanningTreeBlockingStateSet(IxEthDBPortId portID, BOOL blocked); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked) + * + * @brief Retrieves the STP blocked/unblocked state for a port + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param blocked BOOL * [in] - set to TRUE if the port is STP blocked, FALSE otherwise + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid blocked pointer argument + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Spanning Tree Protocol feature not enabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBSpanningTreeBlockingStateGet(IxEthDBPortId portID, BOOL *blocked); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode) + * + * @brief Sets the firewall mode to use white or black listing + * + * When enabled, the NPE MAC address based firewall support operates in two modes: + * + * - white-list mode (MAC address based admission) + * - mode set to IX_ETH_DB_FIREWALL_WHITE_LIST + * - only packets originating from MAC addresses contained in the firewall address list + * are allowed on the Rx path + * - black-list mode (MAC address based blocking) + * - mode set to IX_ETH_DB_FIREWALL_BLACK_LIST + * - packets originating from MAC addresses contained in the firewall address list + * are discarded + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param mode @ref IxEthDBFirewallMode [in] - firewall mode (IX_ETH_DB_FIREWALL_WHITE_LIST or IX_ETH_DB_FIREWALL_BLACK_LIST) + * + * @note by default the firewall operates in black-list mode with an empty address + * list, hence it doesn't filter any packets + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled + * @retval IX_ETH_DB_INVALID_ARGUMENT mode argument is not a valid firewall configuration mode + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error +*/ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallModeSet(IxEthDBPortId portID, IxEthDBFirewallMode mode); + +/** + * @ingroup IxEthDB + * + * @fn ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable) + * + * @brief Enables or disables invalid MAC address filtering + * + * According to IEEE802 it is illegal for a source address to be a multicast + * or broadcast address. If this feature is enabled the NPE inspects the source + * MAC addresses of incoming frames and discards them if invalid addresses are + * detected. + * + * By default this service is enabled, if the firewall feature is supported by the + * NPE image. + * + * @param portID ID of the port + * @param enable TRUE to enable invalid MAC address filtering and FALSE to disable it + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallInvalidAddressFilterEnable(IxEthDBPortId portID, BOOL enable); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Adds a MAC address to the firewall address list + * + * Note that adding the same MAC address twice will not return an error + * but will not actually accomplish anything. + * + * The firewall MAC address list has a limited number of entries; once + * the maximum number of entries has been reached this function will failed + * to add more addresses, returning IX_ETH_DB_NOMEM. + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be added + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NOMEM maximum number of records reached + * @retval IX_ETH_DB_BUSY lock condition or transaction in progress, try again later + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallEntryAdd(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr) + * + * @brief Removes a MAC address from the firewall address list + * + * @param portID @ref IxEthDBPortId [in] - ID of the port + * @param macAddr @ref IxEthDBMacAddr [in] - MAC address to be removed + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NO_SUCH_ADDR address not found + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallEntryRemove(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID) + * + * @brief Downloads the MAC firewall table to a port + * + * @param portID ID of the port + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID is not a valid port identifier + * @retval IX_ETH_DB_PORT_UNINITIALIZED port not initialized + * @retval IX_ETH_DB_FEATURE_UNAVAILABLE Firewall feature not enabled + * @retval IX_ETH_DB_FAIL unknown OS or NPE communication error + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBFirewallTableDownload(IxEthDBPortId portID); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field) + * + * @brief Adds a user-defined field to a database record + * + * This function associates a user-defined field to a database record. + * The user-defined field is passed as a (void *) parameter, hence it can be used + * for any purpose (such as identifying a structure). Retrieving the user-defined field from + * a record is done using @ref ixEthDBUserFieldGet. Note that EthDB never uses the user-defined + * field for any internal operation and it is not aware of the significance of its contents. The + * field is only stored as a pointer. + * + * The database record is identified using a combination of the given parameters, depending on the record type. + * All the record types require the record MAC address. + * + * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address + * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID + * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID + * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID + * + * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking). + * The user-defined field can be cleared using a NULL field parameter. + * + * @param recordType @ref IxEthDBRecordType [in] - type of record (can be IX_ETH_DB_FILTERING_RECORD, + * IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD or IX_ETH_DB_FIREWALL_RECORD) + * @param portID @ref IxEthDBPortId [in] - ID of the port (required only for WIFI and FIREWALL records) + * @param macAddr @ref IxEthDBMacAddr * [in] - MAC address of the record + * @param vlanID @ref IxEthDBVlanId [in] - VLAN ID of the record (required only for FILTERING_VLAN records) + * @param field void * [in] - user defined field + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr pointer argument + * @retval IX_ETH_DB_NO_SUCH_ADDR record not found + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUserFieldSet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void *field); + +/** + * @ingroup IxEthDB + * + * @fn IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portID, IxEthDBVlanId vlanID, void **field) + * + * @brief Retrieves a user-defined field from a database record + * + * The database record is identified using a combination of the given parameters, depending on the record type. + * All the record types require the record MAC address. + * + * - IX_ETH_DB_FILTERING_RECORD requires only the MAC address + * - IX_ETH_DB_VLAN_FILTERING_RECORD requires the MAC address and the VLAN ID + * - IX_ETH_DB_WIFI_RECORD requires the MAC address and the portID + * - IX_ETH_DB_FIREWALL_RECORD requires the MAC address and the portID + * + * Please note that if a parameter is not required it is completely ignored (it does not undergo parameter checking). + * + * If no user-defined field was registered with the specified record then NULL will be written + * at the location specified by field. + * + * @param recordType type of record (can be IX_ETH_DB_FILTERING_RECORD, IX_ETH_DB_FILTERING_VLAN_RECORD, IX_ETH_DB_WIFI_RECORD + * or IX_ETH_DB_FIREWALL_RECORD) + * @param portID ID of the port (required only for WIFI and FIREWALL records) + * @param macAddr MAC address of the record + * @param vlanID VLAN ID of the record (required only for FILTERING_VLAN records) + * @param field location to write the user defined field into + * + * @retval IX_ETH_DB_SUCCESS operation completed successfully + * @retval IX_ETH_DB_INVALID_PORT portID was required but it is not a valid port identifier + * @retval IX_ETH_DB_INVALID_ARG invalid macAddr or field pointer arguments + * @retval IX_ETH_DB_NO_SUCH_ADDR record not found + */ +IX_ETH_DB_PUBLIC +IxEthDBStatus ixEthDBUserFieldGet(IxEthDBRecordType recordType, IxEthDBMacAddr *macAddr, IxEthDBPortId portId, IxEthDBVlanId vlanID, void **field); + +/** + * @} + */ + +#endif /* IxEthDB_H */ diff --git a/drivers/net/npe/include/IxEthDBLocks_p.h b/drivers/net/npe/include/IxEthDBLocks_p.h new file mode 100644 index 0000000..1d8b24f --- /dev/null +++ b/drivers/net/npe/include/IxEthDBLocks_p.h @@ -0,0 +1,122 @@ +/** + * @file IxEthAccDBLocks_p.h + * + * @brief Definition of transaction lock stacks and lock utility macros + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#ifndef IxEthAccDBLocks_p_H +#define IxEthAccDBLocks_p_H + +#include "IxOsPrintf.h" + +/* Lock and lock stacks */ +typedef struct +{ + IxOsalFastMutex* locks[MAX_LOCKS]; + UINT32 stackPointer, basePointer; +} LockStack; + +#define TRY_LOCK(mutex) \ + { \ + if (ixOsalFastMutexTryLock(mutex) != IX_SUCCESS) \ + { \ + return IX_ETH_DB_BUSY; \ + } \ + } + + +#define UNLOCK(mutex) { ixOsalFastMutexUnlock(mutex); } + +#define INIT_STACK(stack) \ + { \ + (stack)->basePointer = 0; \ + (stack)->stackPointer = 0; \ + } + +#define PUSH_LOCK(stack, lock) \ + { \ + if ((stack)->stackPointer == MAX_LOCKS) \ + { \ + ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on push, heavy chaining?\n"); \ + UNROLL_STACK(stack); \ + \ + return IX_ETH_DB_NOMEM; \ + } \ + \ + if (ixOsalFastMutexTryLock(lock) == IX_SUCCESS) \ + { \ + (stack)->locks[(stack)->stackPointer++] = (lock); \ + } \ + else \ + { \ + UNROLL_STACK(stack); \ + \ + return IX_ETH_DB_BUSY; \ + } \ + } + +#define POP_LOCK(stack) \ + { \ + ixOsalFastMutexUnlock((stack)->locks[--(stack)->stackPointer]); \ + } + +#define UNROLL_STACK(stack) \ + { \ + while ((stack)->stackPointer > (stack)->basePointer) \ + { \ + POP_LOCK(stack); \ + } \ + } + +#define SHIFT_STACK(stack) \ + { \ + if ((stack)->basePointer == MAX_LOCKS - 1) \ + { \ + ERROR_LOG("Ethernet DB: maximum number of elements in a lock stack has been exceeded on shift, heavy chaining?\n"); \ + UNROLL_STACK(stack); \ + \ + return IX_ETH_DB_BUSY; \ + } \ + \ + ixOsalFastMutexUnlock((stack)->locks[(stack)->basePointer++]); \ + } + +#endif /* IxEthAccDBLocks_p_H */ diff --git a/drivers/net/npe/include/IxEthDBLog_p.h b/drivers/net/npe/include/IxEthDBLog_p.h new file mode 100644 index 0000000..1d6b0bb --- /dev/null +++ b/drivers/net/npe/include/IxEthDBLog_p.h @@ -0,0 +1,227 @@ +/** + * @file IxEthDBLog_p.h + * + * @brief definitions of log macros and log configuration + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#include + +#ifdef IX_UNIT_TEST +#define NULL_PRINT_ROUTINE(format, arg...) /* nothing */ +#else +#define NULL_PRINT_ROUTINE if(0) printf +#endif + +/*************************************************** + * Globals * + ***************************************************/ +/* safe to permanently leave these on */ +#define HAS_ERROR_LOG +#define HAS_ERROR_IRQ_LOG +#define HAS_WARNING_LOG + +/*************************************************** + * Log Configuration * + ***************************************************/ + +/* debug output can be turned on unless specifically + declared as a non-debug build */ +#ifndef NDEBUG + +#undef HAS_EVENTS_TRACE +#undef HAS_EVENTS_VERBOSE_TRACE + +#undef HAS_SUPPORT_TRACE +#undef HAS_SUPPORT_VERBOSE_TRACE + +#undef HAS_NPE_TRACE +#undef HAS_NPE_VERBOSE_TRACE +#undef HAS_DUMP_NPE_TREE + +#undef HAS_UPDATE_TRACE +#undef HAS_UPDATE_VERBOSE_TRACE + +#endif /* NDEBUG */ + + +/*************************************************** + * Log Macros * + ***************************************************/ + +/************** Globals ******************/ + +#ifdef HAS_ERROR_LOG + + #define ERROR_LOG printf + +#else + + #define ERROR_LOG NULL_PRINT_ROUTINE + +#endif + +#ifdef HAS_ERROR_IRQ_LOG + + #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) + +#else + + #define ERROR_IRQ_LOG(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ + +#endif + +#ifdef HAS_WARNING_LOG + + #define WARNING_LOG printf + +#else + + #define WARNING_LOG NULL_PRINT_ROUTINE + +#endif + +/************** Events *******************/ + +#ifdef HAS_EVENTS_TRACE + + #define IX_ETH_DB_EVENTS_TRACE printf + #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) + + #ifdef HAS_EVENTS_VERBOSE_TRACE + + #define IX_ETH_DB_EVENTS_VERBOSE_TRACE printf + + #else + + #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE + + #endif /* HAS_EVENTS_VERBOSE_TRACE */ + +#else + + #define IX_ETH_DB_EVENTS_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_EVENTS_VERBOSE_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_IRQ_EVENTS_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ + +#endif /* HAS_EVENTS_TRACE */ + +/************** Support *******************/ + +#ifdef HAS_SUPPORT_TRACE + + #define IX_ETH_DB_SUPPORT_TRACE printf + #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) + + #ifdef HAS_SUPPORT_VERBOSE_TRACE + + #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE printf + + #else + + #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE + + #endif /* HAS_SUPPORT_VERBOSE_TRACE */ + +#else + + #define IX_ETH_DB_SUPPORT_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_SUPPORT_VERBOSE_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_SUPPORT_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ + +#endif /* HAS_SUPPORT_TRACE */ + +/************** NPE Adaptor *******************/ + +#ifdef HAS_NPE_TRACE + + #define IX_ETH_DB_NPE_TRACE printf + #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) ixOsalLog(IX_OSAL_LOG_LVL_MESSAGE, IX_OSAL_LOG_DEV_STDOUT, format, arg1, arg2, arg3, arg4, arg5, arg6) + + #ifdef HAS_NPE_VERBOSE_TRACE + + #define IX_ETH_DB_NPE_VERBOSE_TRACE printf + + #else + + #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE + + #endif /* HAS_NPE_VERBOSE_TRACE */ + +#else + + #define IX_ETH_DB_NPE_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_NPE_VERBOSE_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_NPE_IRQ_TRACE(format, arg1, arg2, arg3, arg4, arg5, arg6) /* nothing */ + +#endif /* HAS_NPE_TRACE */ + +#ifdef HAS_DUMP_NPE_TREE + +#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) ixEthELTDumpTree(eltBaseAddress, eltSize) + +#else + +#define IX_ETH_DB_NPE_DUMP_ELT(eltBaseAddress, eltSize) /* nothing */ + +#endif /* HAS_DUMP_NPE_TREE */ + +/************** Port Update *******************/ + +#ifdef HAS_UPDATE_TRACE + + #define IX_ETH_DB_UPDATE_TRACE printf + + #ifdef HAS_UPDATE_VERBOSE_TRACE + + #define IX_ETH_DB_UPDATE_VERBOSE_TRACE printf + + #else + + #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE + + #endif + +#else /* HAS_UPDATE_VERBOSE_TRACE */ + + #define IX_ETH_DB_UPDATE_TRACE NULL_PRINT_ROUTINE + #define IX_ETH_DB_UPDATE_VERBOSE_TRACE NULL_PRINT_ROUTINE + +#endif /* HAS_UPDATE_TRACE */ diff --git a/drivers/net/npe/include/IxEthDBMessages_p.h b/drivers/net/npe/include/IxEthDBMessages_p.h new file mode 100644 index 0000000..ff18160 --- /dev/null +++ b/drivers/net/npe/include/IxEthDBMessages_p.h @@ -0,0 +1,258 @@ +/** + * @file IxEthDBMessages_p.h + * + * @brief Definitions of NPE messages + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#ifndef IxEthDBMessages_p_H +#define IxEthDBMessages_p_H + +#include +#include +#include "IxEthDB_p.h" + +/* events watched by the Eth event processor */ +#define IX_ETH_DB_MIN_EVENT_ID (IX_ETHNPE_EDB_GETMACADDRESSDATABASE) +#define IX_ETH_DB_MAX_EVENT_ID (IX_ETHNPE_PC_SETAPMACTABLE) + +/* macros to fill and extract data from NPE messages - place any endian conversions here */ +#define RESET_ELT_MESSAGE(message) { memset((void *) &(message), 0, sizeof((message))); } +#define NPE_MSG_ID(msg) ((msg).data[0] >> 24) + +#define FILL_SETPORTVLANTABLEENTRY_MSG(message, portID, setOffset, vlanMembershipSet, ttiSet) \ + do { \ + message.data[0] = (IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY << 24) | (portID << 16) | (setOffset * 2); \ + message.data[1] = (vlanMembershipSet << 8) | ttiSet; \ + } while (0); + +#define FILL_SETPORTVLANTABLERANGE_MSG(message, portID, offset, length, zone) \ + do { \ + message.data[0] = IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE << 24 | portID << 16 | offset << 9 | length << 1; \ + message.data[1] = (UINT32) zone; \ + } while (0); + +#define FILL_SETDEFAULTRXVID_MSG(message, portID, tpid, vlanTag) \ + do { \ + message.data[0] = (IX_ETHNPE_VLAN_SETDEFAULTRXVID << 24) \ + | (portID << 16); \ + \ + message.data[1] = (tpid << 16) | vlanTag; \ + } while (0); + +#define FILL_SETRXTAGMODE_MSG(message, portID, filterMode, tagMode) \ + do { \ + message.data[0] = IX_ETHNPE_VLAN_SETRXTAGMODE << 24 \ + | portID << 16 \ + | filterMode << 2 \ + | tagMode; \ + \ + message.data[1] = 0; \ + } while (0); + +#define FILL_SETRXQOSENTRY(message, portID, classIndex, trafficClass, aqmQueue) \ + do { \ + message.data[0] = IX_ETHNPE_VLAN_SETRXQOSENTRY << 24 \ + | portID << 16 \ + | classIndex; \ + \ + message.data[1] = trafficClass << 24 \ + | 0x1 << 23 \ + | aqmQueue << 16 \ + | aqmQueue << 4; \ + } while (0); + +#define FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable) \ + do { \ + message.data[0] = IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE << 24 \ + | portID << 16 \ + | (enable ? 0x1 : 0x0); \ + \ + message.data[1] = 0; \ + } while (0); + + +#define FILL_SETBLOCKINGSTATE_MSG(message, portID, blocked) \ + do { \ + message.data[0] = IX_ETHNPE_STP_SETBLOCKINGSTATE << 24 \ + | portID << 16 \ + | (blocked ? 0x1 : 0x0); \ + \ + message.data[1] = 0; \ + } while (0); + +#define FILL_SETBBSID_MSG(message, portID, bbsid) \ + do { \ + message.data[0] = IX_ETHNPE_PC_SETBBSID << 24 \ + | portID << 16 \ + | bbsid->macAddress[0] << 8 \ + | bbsid->macAddress[1]; \ + \ + message.data[1] = bbsid->macAddress[2] << 24 \ + | bbsid->macAddress[3] << 16 \ + | bbsid->macAddress[4] << 8 \ + | bbsid->macAddress[5]; \ + } while (0); + +#define FILL_SETFRAMECONTROLDURATIONID(message, portID, frameControlDurationID) \ + do { \ + message.data[0] = (IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID << 24) | (portID << 16); \ + message.data[1] = frameControlDurationID; \ + } while (0); + +#define FILL_SETAPMACTABLE_MSG(message, zone) \ + do { \ + message.data[0] = IX_ETHNPE_PC_SETAPMACTABLE << 24 \ + | 0 << 8 /* always use index 0 */ \ + | 64; /* 32 entries, 8 bytes each, 4 bytes in a word */ \ + message.data[1] = (UINT32) zone; \ + } while (0); + +#define FILL_SETFIREWALLMODE_MSG(message, portID, epDelta, mode, address) \ + do { \ + message.data[0] = IX_ETHNPE_FW_SETFIREWALLMODE << 24 \ + | portID << 16 \ + | (epDelta & 0xFF) << 8 \ + | mode; \ + \ + message.data[1] = (UINT32) address; \ + } while (0); + +#define FILL_SETMACADDRESSDATABASE_MSG(message, portID, epDelta, blockCount, address) \ + do { \ + message.data[0] = IX_ETHNPE_EDB_SETMACADDRESSSDATABASE << 24 \ + | (epDelta & 0xFF) << 8 \ + | (blockCount & 0xFF); \ + \ + message.data[1] = (UINT32) address; \ + } while (0); + +#define FILL_GETMACADDRESSDATABASE(message, npeId, zone) \ + do { \ + message.data[0] = IX_ETHNPE_EDB_GETMACADDRESSDATABASE << 24; \ + message.data[1] = (UINT32) zone; \ + } while (0); + +#define FILL_SETMAXFRAMELENGTHS_MSG(message, portID, maxRxFrameSize, maxTxFrameSize) \ + do { \ + message.data[0] = IX_ETHNPE_SETMAXFRAMELENGTHS << 24 \ + | portID << 16 \ + | ((maxRxFrameSize + 63) / 64) << 8 /* max Rx 64-byte blocks */ \ + | (maxTxFrameSize + 63) / 64; /* max Tx 64-byte blocks */ \ + \ + message.data[1] = maxRxFrameSize << 16 | maxTxFrameSize; \ + } while (0); + +#define FILL_SETPORTADDRESS_MSG(message, portID, macAddress) \ + do { \ + message.data[0] = IX_ETHNPE_EDB_SETPORTADDRESS << 24 \ + | portID << 16 \ + | macAddress[0] << 8 \ + | macAddress[1]; \ + \ + message.data[1] = macAddress[2] << 24 \ + | macAddress[3] << 16 \ + | macAddress[4] << 8 \ + | macAddress[5]; \ + } while (0); + +/* access to a MAC node in the NPE tree */ +#define NPE_NODE_BYTE(eltNodeAddr, offset) (((UINT8 *) (eltNodeAddr))[offset]) + +/* browsing of the implicit linear binary tree structure of the NPE tree */ +#define LEFT_CHILD_OFFSET(offset) ((offset) << 1) +#define RIGHT_CHILD_OFFSET(offset) (((offset) << 1) + 1) + +#define IX_EDB_FLAGS_ACTIVE (0x2) +#define IX_EDB_FLAGS_VALID (0x1) +#define IX_EDB_FLAGS_RESERVED (0xfc) +#define IX_EDB_FLAGS_INACTIVE_VALID (0x1) + +#define IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET (6) +#define IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET (7) +#define IX_EDB_NPE_NODE_WIFI_INDEX_OFFSET (6) +#define IX_EDB_NPE_NODE_WIFI_FLAGS_OFFSET (7) +#define IX_EDB_NPE_NODE_FW_FLAGS_OFFSET (1) +#define IX_EDB_NPE_NODE_FW_RESERVED_OFFSET (6) +#define IX_EDB_NPE_NODE_FW_ADDR_OFFSET (2) + +#define IX_EDB_NPE_NODE_VALID(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_VALID) != 0) +#define IX_EDB_NPE_NODE_ACTIVE(address) ((NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_FLAGS_OFFSET) & IX_EDB_FLAGS_ACTIVE) != 0) +#define IX_EDB_NPE_NODE_PORT_ID(address) (NPE_NODE_BYTE(address, IX_EDB_NPE_NODE_ELT_PORT_ID_OFFSET)) + +/* macros to send messages to the NPEs */ +#define IX_ETHDB_ASYNC_SEND_NPE_MSG(npeId, msg, result) \ + do { \ + result = ixNpeMhMessageSend(npeId, msg, IX_NPEMH_SEND_RETRIES_DEFAULT); \ + \ + if (result != IX_SUCCESS) \ + { \ + ERROR_LOG("DB: Failed to send NPE message\n"); \ + } \ + } while (0); + +#define IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result) \ + do { \ + result = ixNpeMhMessageWithResponseSend(npeId, msg, msg.data[0] >> 24, ixEthDBNpeMsgAck, IX_NPEMH_SEND_RETRIES_DEFAULT); \ + \ + if (result == IX_SUCCESS) \ + { \ + result = ixOsalMutexLock(&ixEthDBPortInfo[IX_ETH_DB_NPE_TO_PORT_ID(npeId)].npeAckLock, IX_ETH_DB_NPE_TIMEOUT); \ + \ + if (result != IX_SUCCESS) \ + { \ + ERROR_LOG("DB: NPE failed to respond within %dms\n", IX_ETH_DB_NPE_TIMEOUT); \ + } \ + } \ + else \ + { \ + ERROR_LOG("DB: Failed to send NPE message\n"); \ + } \ + } while (0); + +#ifndef IX_NDEBUG +#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100) +extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistory[IX_ETH_DB_NPE_MSG_HISTORY_DEPTH][2]; +extern IX_ETH_DB_PUBLIC UINT32 npeMsgHistoryLen; +#endif + +#define IX_ETHDB_SEND_NPE_MSG(npeId, msg, result) { LOG_NPE_MSG(msg); IX_ETHDB_SYNC_SEND_NPE_MSG(npeId, msg, result); } + +#endif /* IxEthDBMessages_p_H */ diff --git a/drivers/net/npe/include/IxEthDBPortDefs.h b/drivers/net/npe/include/IxEthDBPortDefs.h new file mode 100644 index 0000000..c3acbdd --- /dev/null +++ b/drivers/net/npe/include/IxEthDBPortDefs.h @@ -0,0 +1,163 @@ +/** + * @file IxEthDBPortDefs.h + * + * @brief Public definition of the ports and port capabilities + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @defgroup IxEthDBPortDefs IXP400 Ethernet Database Port Definitions (IxEthDBPortDefs) + * + * @brief IXP400 Public definition of the ports and port capabilities + * + * @{ + */ + +#ifndef IxEthDBPortDefs_H +#define IxEthDBPortDefs_H + +/** + * @brief Port types - currently only Ethernet NPEs are recognized as specific types + * All other (user-defined) ports must be specified as IX_ETH_GENERIC + */ +typedef enum +{ + IX_ETH_GENERIC = 0, /**< generic ethernet port */ + IX_ETH_NPE /**< specific Ethernet NPE */ +} IxEthDBPortType; + +/** + * @brief Port capabilities - used by ixEthAccDatabaseMaintenance to decide whether it + * should manually age entries or not depending on the port capabilities. + * + * Ethernet NPEs have aging capabilities, meaning that they will age the entries + * automatically (by themselves).*/ +typedef enum +{ + IX_ETH_NO_CAPABILITIES = 0, /**< no aging capabilities */ + IX_ETH_ENTRY_AGING = 0x1 /**< aging capabilities present */ +} IxEthDBPortCapability; + +/** + * @brief Port Definition - a structure contains the Port type and capabilities + */ +typedef struct +{ + IxEthDBPortType type; + IxEthDBPortCapability capabilities; +} IxEthDBPortDefinition; + +/** + * @brief Port definitions structure, indexed on the port ID + * @warning Ports 0 and 1 are used by the Ethernet access component therefore + * it is essential to be left untouched. Port 2 here (WAN) is given as + * an example port. The NPE firmware also assumes the NPE B to be + * the port 0 and NPE C to be the port 1. + * + * @note that only 32 ports (0..31) are supported by EthDB + */ +static const IxEthDBPortDefinition ixEthDBPortDefinitions[] = +{ + /* id type capabilities */ + { /* 0 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE B */ + { /* 1 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE C */ + { /* 2 */ IX_ETH_NPE, IX_ETH_NO_CAPABILITIES }, /* Ethernet NPE A */ + { /* 3 */ IX_ETH_GENERIC, IX_ETH_NO_CAPABILITIES }, /* WAN port */ +}; + +/** + * @def IX_ETH_DB_NUMBER_OF_PORTS + * @brief number of supported ports + */ +#define IX_ETH_DB_NUMBER_OF_PORTS (sizeof (ixEthDBPortDefinitions) / sizeof (ixEthDBPortDefinitions[0])) + +/** + * @def IX_ETH_DB_UNKNOWN_PORT + * @brief definition of an unknown port + */ +#define IX_ETH_DB_UNKNOWN_PORT (0xff) + +/** + * @def IX_ETH_DB_ALL_PORTS + * @brief Special port ID indicating all the ports + * @note This port ID can be used only by a subset of the EthDB API; each + * function specifically mentions whether this is a valid parameter as the port ID + */ +#define IX_ETH_DB_ALL_PORTS (IX_ETH_DB_NUMBER_OF_PORTS + 1) + +/** + * @def IX_ETH_DB_PORTS_ASSERTION + * @brief catch invalid port definitions (<2) with a + * compile-time assertion resulting in a duplicate case error. + */ +#define IX_ETH_DB_PORTS_ASSERTION { switch(0) { case 0 : ; case 1 : ; case IX_ETH_DB_NUMBER_OF_PORTS : ; }} + +/** + * @def IX_ETH_DB_CHECK_PORT(portID) + * @brief safety checks to verify whether the port is invalid or uninitialized + */ +#define IX_ETH_DB_CHECK_PORT(portID) \ +{ \ + if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ + { \ + return IX_ETH_DB_INVALID_PORT; \ + } \ + \ + if (!ixEthDBPortInfo[(portID)].enabled) \ + { \ + return IX_ETH_DB_PORT_UNINITIALIZED; \ + } \ +} + +/** + * @def IX_ETH_DB_CHECK_PORT_ALL(portID) + * @brief safety checks to verify whether the port is invalid or uninitialized; + * tolerates the use of IX_ETH_DB_ALL_PORTS + */ +#define IX_ETH_DB_CHECK_PORT_ALL(portID) \ +{ \ + if ((portID) != IX_ETH_DB_ALL_PORTS) \ + IX_ETH_DB_CHECK_PORT(portID) \ +} + +#endif /* IxEthDBPortDefs_H */ +/** + *@} + */ diff --git a/drivers/net/npe/include/IxEthDBQoS.h b/drivers/net/npe/include/IxEthDBQoS.h new file mode 100644 index 0000000..6d34889 --- /dev/null +++ b/drivers/net/npe/include/IxEthDBQoS.h @@ -0,0 +1,154 @@ +/** + * @file IxEthDBQoS.h + * + * @brief Public definitions for QoS traffic classes + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @defgroup IxEthDBPortDefs IXP400 Ethernet QoS definitions + * + * @brief IXP00 Public definitions for QoS traffic classes + * + * @{ + */ + +#ifndef IxEthDBQoS_H +#define IxEthDBQoS_H + +/** + * @def IX_ETH_DB_QUEUE_UNAVAILABLE + * @brief alias to indicate a queue (traffic class) is not available + */ +#define IX_ETH_DB_QUEUE_UNAVAILABLE (0) + +#ifndef IX_IEEE802_1Q_QOS_PRIORITY_COUNT +/** + * @def IX_IEEE802_1Q_QOS_PRIORITY_COUNT + * @brief number of QoS priorities, according to IEEE 802.1Q + */ +#define IX_IEEE802_1Q_QOS_PRIORITY_COUNT (8) +#endif + +/** + * @brief array containing all the supported traffic class configurations + */ +static const +UINT8 ixEthDBQueueAssignments[][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] = +{ + { 4, 5, 6, 7, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, + { 15, 16, 17, 18, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, + { 11, 23, 26, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE, IX_ETH_DB_QUEUE_UNAVAILABLE }, + { 4, 5, 6, 7, 8, 9, 10, 11 } + /* add here all other cases of queue configuration structures and update ixEthDBTrafficClassDefinitions to use them */ +}; + +/** + * @brief value used to index the NPE A functionality ID in the traffic class definition table + */ +#define IX_ETH_DB_NPE_A_FUNCTIONALITY_ID_INDEX (0) + +/** + * @brief value used to index the traffic class count in the traffic class definition table + */ +#define IX_ETH_DB_TRAFFIC_CLASS_COUNT_INDEX (1) + +/** + * @brief value used to index the queue assignment index in the traffic class definition table + */ +#define IX_ETH_DB_QUEUE_ASSIGNMENT_INDEX (2) + +/** + * @brief traffic class definitions + * + * This array contains the default traffic class definition configuration, + * as well as any special cases dictated by the functionality ID of NPE A. + * + * The default case should not be removed (otherwise the Ethernet + * components will assert a fatal failure on initialization). + */ +static const +UINT8 ixEthDBTrafficClassDefinitions[][3] = +{ + /* NPE A functionality ID | traffic class count | queue assignment index (points to the queue enumeration in ixEthDBQueueAssignments) */ + { 0x00, 4, 0 }, /* default case - DO NOT REMOVE */ + { 0x04, 4, 1 }, /* NPE A image ID 0.4.0.0 */ + { 0x09, 3, 2 }, /* NPE A image ID 0.9.0.0 */ + { 0x80, 8, 3 }, /* NPE A image ID 10.80.02.0 */ + { 0x81, 8, 3 }, /* NPE A image ID 10.81.02.0 */ + { 0x82, 8, 3 } /* NPE A image ID 10.82.02.0 */ +}; + +/** + * @brief IEEE 802.1Q recommended QoS Priority => traffic class maps + * + * @verbatim + Number of available traffic classes + 1 2 3 4 5 6 7 8 + QoS Priority + 0 0 0 0 1 1 1 1 2 + 1 0 0 0 0 0 0 0 0 + 2 0 0 0 0 0 0 0 1 + 3 0 0 0 1 1 2 2 3 + 4 0 1 1 2 2 3 3 4 + 5 0 1 1 2 3 4 4 5 + 6 0 1 2 3 4 5 5 6 + 7 0 1 2 3 4 5 6 7 + + @endverbatim + */ +static const +UINT8 ixEthIEEE802_1QUserPriorityToTrafficClassMapping[IX_IEEE802_1Q_QOS_PRIORITY_COUNT][IX_IEEE802_1Q_QOS_PRIORITY_COUNT] = + { + { 0, 0, 0, 0, 0, 0, 0, 0 }, /* 1 traffic class available */ + { 0, 0, 0, 0, 1, 1, 1, 1 }, /* 2 traffic classes available */ + { 0, 0, 0, 0, 1, 1, 2, 2 }, /* 3 traffic classes available */ + { 1, 0, 0, 1, 2, 2, 3, 3 }, /* 4 traffic classes available */ + { 1, 0, 0, 1, 2, 3, 4, 4 }, /* 5 traffic classes available */ + { 1, 0, 0, 2, 3, 4, 5, 5 }, /* 6 traffic classes available */ + { 1, 0, 0, 2, 3, 4, 5, 6 }, /* 7 traffic classes available */ + { 2, 0, 1, 3, 4, 5, 6, 7 } /* 8 traffic classes available */ + }; + +#endif /* IxEthDBQoS_H */ + +/** + *@} + */ diff --git a/drivers/net/npe/include/IxEthDB_p.h b/drivers/net/npe/include/IxEthDB_p.h new file mode 100644 index 0000000..ccec7ea --- /dev/null +++ b/drivers/net/npe/include/IxEthDB_p.h @@ -0,0 +1,710 @@ +/** + * @file IxEthDB_p.h + * + * @brief Private MAC learning API + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#ifndef IxEthDB_p_H +#define IxEthDB_p_H + +#include +#include +#include +#include +#include + +#include "IxEthDBMessages_p.h" +#include "IxEthDBLog_p.h" + +#if (CPU==SIMSPARCSOLARIS) + +/* when running unit tests intLock() won't protect the event queue so we lock it manually */ +#define TEST_FIXTURE_LOCK_EVENT_QUEUE { ixOsalMutexLock(&eventQueueLock, IX_OSAL_WAIT_FOREVER); } +#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE { ixOsalMutexUnlock(&eventQueueLock); } + +#else + +#define TEST_FIXTURE_LOCK_EVENT_QUEUE /* nothing */ +#define TEST_FIXTURE_UNLOCK_EVENT_QUEUE /* nothing */ + +#endif /* #if(CPU==SIMSPARCSOLARIS) */ + +#ifndef IX_UNIT_TEST + +#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER /* nothing */ +#define TEST_FIXTURE_MARK_OVERFLOW_EVENT /* nothing */ + +#else + +extern int dbAccessCounter; +extern int overflowEvent; + +#define TEST_FIXTURE_INCREMENT_DB_CORE_ACCESS_COUNTER { dbAccessCounter++; } +#define TEST_FIXTURE_MARK_OVERFLOW_EVENT { overflowEvent = 1; } + +#endif + +/* code readability markers */ +#define __mempool__ /* memory pool marker */ +#define __lock__ /* hash write locking marker */ +#define __smartpointer__ /* smart pointer marker - warning: use only clone() when duplicating! */ +#define __alignment__ /* marker for data used only as alignment zones */ + +/* constants */ +#define IX_ETH_DB_NPE_TIMEOUT (100) /* NPE response timeout, in ms */ + +/** + * number of hash table buckets + * it should be at least 8x the predicted number of entries for performance + * each bucket needs 8 bytes + */ +#define NUM_BUCKETS (8192) + +/** + * number of hash table buckets to preload when incrementing bucket iterator + * = two cache lines + */ +#define IX_ETHDB_CACHE_LINE_AHEAD (2) + +#define IX_ETHDB_BUCKETPTR_AHEAD ((IX_ETHDB_CACHE_LINE_AHEAD * IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) + +#define IX_ETHDB_BUCKET_INDEX_MASK (((IX_OSAL_CACHE_LINE_SIZE)/sizeof(void *)) - 1) + +/* locks */ +#define MAX_LOCKS (20) /**< maximum number of locks used simultaneously, do not tamper with */ + +/* learning tree constants */ +#define INITIAL_ELT_SIZE (8) /**< initial byte size of tree (empty unused root size) */ +#define MAX_ELT_SIZE (512) /**< maximum number of entries (includes unused root) */ +#define MAX_GW_SIZE (32) /**< maximum number of gateway entries (including unused root) */ +#define MAX_FW_SIZE (32) /**< maximum number of firewall entries (including unused root) */ +#define ELT_ENTRY_SIZE (8) /**< entry size, in bytes */ +#define ELT_ROOT_OFFSET (ELT_ENTRY_SIZE) /**< tree root offset, in bytes - node preceeding root is unused */ +#define FULL_ELT_BYTE_SIZE (MAX_ELT_SIZE * ELT_ENTRY_SIZE) /**< full size of tree, in bytes, including unused root */ +#define FULL_GW_BYTE_SIZE (MAX_GW_SIZE * ELT_ENTRY_SIZE) /**< full size of gateway list, in bytes, including unused root */ +#define FULL_FW_BYTE_SIZE (MAX_FW_SIZE * ELT_ENTRY_SIZE) /**< full size of firewall table, in bytes, including unused root */ + +/* maximum size of the VLAN table: + * 4096 bits (one per VLAN) + * 8 bits in one byte + * interleaved VLAN membership and VLAN TTI (*2) */ +#define FULL_VLAN_BYTE_SIZE (4096 / 8 * 2) + +/* upper 9 bits used as set index, lower 3 bits as byte index */ +#define VLAN_SET_OFFSET(vlanID) ((vlanID) >> 3) +#define VLAN_SET_MASK(vlanID) (0x7 - ((vlanID) & 0x7)) + +/* Update zone definitions */ +#define NPE_TREE_MEM_SIZE (4096) /* ((511 entries + 1 unused root) * 8 bytes/entry) */ + +/* check the above value, we rely on 4k */ +#if NPE_TREE_MEM_SIZE != 4096 + #error NPE_TREE_MEM_SIZE is not defined to 4096 bytes! +#endif + +/* Size Filtering limits (Jumbo frame filtering) */ +#define IX_ETHDB_MAX_FRAME_SIZE 65535 /* other ports than NPE ports */ +#define IX_ETHDB_MIN_FRAME_SIZE 1 /* other ports than NPE ports */ +#define IX_ETHDB_MAX_NPE_FRAME_SIZE 16320 /* NPE ports firmware limit */ +#define IX_ETHDB_MIN_NPE_FRAME_SIZE 1 /* NPE ports firmware limit */ +#define IX_ETHDB_DEFAULT_FRAME_SIZE 1522 + +/* memory management pool sizes */ + +/* + * Note: + * + * NODE_POOL_SIZE controls the maximum number of elements in the database at any one time. + * It should be large enough to cover all the search trees of all the ports simultaneously. + * + * MAC_POOL_SIZE should be higher than NODE_POOL_SIZE by at least the total number of MAC addresses + * possible to be held at any time in all the ports. + * + * TREE_POOL_SIZE should follow the same guideline as for MAC_POOL_SIZE. + * + * The database structure described here (2000/4000/4000) is enough for two NPEs holding at most 511 + * entries each plus one PCI NIC holding at most 900 entries. + */ + +#define NODE_POOL_SIZE (2000) /**< number of HashNode objects - also master number of elements in the database; each entry has 16 bytes */ +#define MAC_POOL_SIZE (4000) /**< number of MacDescriptor objects; each entry has 28 bytes */ +#define TREE_POOL_SIZE (4000) /**< number of MacTreeNode objects; each entry has 16 bytes */ + +/* retry policies */ +#define BUSY_RETRY_ENABLED (TRUE) /**< if set to TRUE the API will retry automatically calls returning BUSY */ +#define FOREVER_RETRY (TRUE) /**< if set to TRUE the API will retry forever BUSY calls */ +#define MAX_RETRIES (400) /**< upper retry limit - used only when FOREVER_RETRY is FALSE */ +#define BUSY_RETRY_YIELD (5) /**< ticks to yield for every failed retry */ + +/* event management */ +#define EVENT_QUEUE_SIZE (500) /**< size of the sink collecting events from the Message Handler FIFO */ +#define EVENT_PROCESSING_LIMIT (100) /**< batch processing control size (how many events are extracted from the queue at once) */ + +/* MAC descriptors */ +#define STATIC_ENTRY (TRUE) +#define DYNAMIC_ENTRY (FALSE) + +/* age reset on next maintenance - incrementing by 1 will reset to 0 */ +#define AGE_RESET (0xFFFFFFFF) + +/* dependency maps */ +#define EMPTY_DEPENDENCY_MAP (0) + +/* trees */ +#define RIGHT (1) +#define LEFT (-1) + +/* macros */ +#define IX_ETH_DB_CHECK_PORT_EXISTS(portID) \ +{ \ + if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ + { \ + return IX_ETH_DB_INVALID_PORT; \ + } \ +} + +#define IX_ETH_DB_CHECK_PORT_INITIALIZED(portID) \ +{ \ + if ((portID) >= IX_ETH_DB_NUMBER_OF_PORTS) \ + { \ + return IX_ETH_DB_INVALID_PORT; \ + } \ + else \ + { \ + if (!ixEthDBPortInfo[portID].initialized) \ + { \ + return IX_ETH_DB_PORT_UNINITIALIZED; \ + } \ + } \ +} + +/* single NPE check */ +#define IX_ETH_DB_CHECK_SINGLE_NPE(portID) \ + if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS) \ + { \ + WARNING_LOG("EthDB: port ID %d is unavailable\n",(UINT32) portID); \ + \ + return IX_ETH_DB_INVALID_PORT; \ + } + +/* feature check */ +#define IX_ETH_DB_CHECK_FEATURE(portID, feature) \ + if ((ixEthDBPortInfo[portID].featureStatus & feature) == 0) \ + { \ + return IX_ETH_DB_FEATURE_UNAVAILABLE; \ + } + +/* busy retrying */ +#define BUSY_RETRY(functionCall) \ + { \ + UINT32 retries = 0; \ + IxEthDBStatus br_result; \ + \ + while ((br_result = functionCall) == IX_ETH_DB_BUSY \ + && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \ + \ + if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (br_result == IX_ETH_DB_FAIL)) \ + {\ + ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY failed at %s:%d\n", __FILE__, __LINE__); \ + }\ + } + +#define BUSY_RETRY_WITH_RESULT(functionCall, brwr_result) \ + { \ + UINT32 retries = 0; \ + \ + while ((brwr_result = functionCall) == IX_ETH_DB_BUSY \ + && BUSY_RETRY_ENABLED && (FOREVER_RETRY || ++retries < MAX_RETRIES)) { ixOsalSleep(BUSY_RETRY_YIELD); }; \ + \ + if ((!FOREVER_RETRY && retries == MAX_RETRIES) || (brwr_result == IX_ETH_DB_FAIL)) \ + {\ + ERROR_LOG("Ethernet Learning Database Error: BUSY_RETRY_WITH_RESULT failed at %s:%d\n", __FILE__, __LINE__); \ + }\ + } + +/* iterators */ +#define IS_ITERATOR_VALID(iteratorPtr) ((iteratorPtr)->node != NULL) + +/* dependency port maps */ + +/* Warning: if port indexing starts from 1 replace (portID) with (portID - 1) in DEPENDENCY_MAP (and make sure IX_ETH_DB_NUMBER_OF_PORTS is big enough) */ + +/* gives an empty dependency map */ +#define SET_EMPTY_DEPENDENCY_MAP(map) { int i = 0; for (; i < 32 ; i++) map[i] = 0; } + +#define IS_EMPTY_DEPENDENCY_MAP(result, map) { int i = 0 ; result = TRUE; for (; i < 32 ; i++) if (map[i] != 0) { result = FALSE; break; }} + +/** + * gives a map consisting only of 'portID' + */ +#define SET_DEPENDENCY_MAP(map, portID) {SET_EMPTY_DEPENDENCY_MAP(map); map[portID >> 3] = 1 << (portID & 0x7);} + +/** + * gives a map resulting from joining map1 and map2 + */ +#define JOIN_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] | map2[i]; } + +/** + * gives the map resulting from joining portID and map + */ +#define JOIN_PORT_TO_MAP(map, portID) { map[portID >> 3] |= 1 << (portID & 0x7); } + +/** + * gives the map resulting from excluding portID from map + */ +#define EXCLUDE_PORT_FROM_MAP(map, portID) { map[portID >> 3] &= ~(1 << (portID & 0x7); } + +/** + * returns TRUE if map1 is a subset of map2 and FALSE otherwise + */ +#define IS_MAP_SUBSET(result, map1, map2) { int i = 0; result = TRUE; for (; i < 32 ; i++) if ((map1[i] | map2[i]) != map2[i]) result = FALSE; } + +/** + * returns TRUE is portID is part of map and FALSE otherwise + */ +#define IS_PORT_INCLUDED(portID, map) ((map[portID >> 3] & (1 << (portID & 0x7))) != 0) + +/** + * returns the difference between map1 and map2 (ports included in map1 and not included in map2) + */ +#define DIFF_MAPS(map, map1, map2) { int i = 0; for (; i < 32 ; i++) map[i] = map1[i] ^ (map1[i] & map2[i]); } + +/** + * returns TRUE if the maps collide (have at least one port in common) and FALSE otherwise + */ +#define MAPS_COLLIDE(result, map1, map2) { int i = 0; result = FALSE; for (; i < 32 ; i++) if ((map1[i] & map2[i]) != 0) result = TRUE; } + +/* size (number of ports) of a dependency map */ +#define GET_MAP_SIZE(map, size) { int i = 0, b = 0; size = 0; for (; i < 32 ; i++) { char y = map[i]; for (; b < 8 && (y >>= 1); b++) size += (y & 1); }} + +/* copy map2 into map1 */ +#define COPY_DEPENDENCY_MAP(map1, map2) { memcpy (map1, map2, sizeof (map1)); } + +/* definition of a port map size/port number which cannot be reached (we support at most 32 ports) */ +#define MAX_PORT_SIZE (0xFF) +#define MAX_PORT_NUMBER (0xFF) + +#define IX_ETH_DB_CHECK_REFERENCE(ptr) { if ((ptr) == NULL) { return IX_ETH_DB_INVALID_ARG; } } +#define IX_ETH_DB_CHECK_MAP(portID, map) { if (!IS_PORT_INCLUDED(portID, map)) { return IX_ETH_DB_INVALID_ARG; } } + +/* event queue macros */ +#define EVENT_QUEUE_WRAP(offset) ((offset) >= EVENT_QUEUE_SIZE ? (offset) - EVENT_QUEUE_SIZE : (offset)) + +#define CAN_ENQUEUE(eventQueuePtr) ((eventQueuePtr)->length < EVENT_QUEUE_SIZE) + +#define QUEUE_HEAD(eventQueuePtr) (&(eventQueuePtr)->queue[EVENT_QUEUE_WRAP((eventQueuePtr)->base + (eventQueuePtr)->length)]) + +#define QUEUE_TAIL(eventQueuePtr) (&(eventQueuePtr)->queue[(eventQueuePtr)->base]) + +#define PUSH_UPDATE_QUEUE(eventQueuePtr) { (eventQueuePtr)->length++; } + +#define SHIFT_UPDATE_QUEUE(eventQueuePtr) \ + { \ + (eventQueuePtr)->base = EVENT_QUEUE_WRAP((eventQueuePtr)->base + 1); \ + (eventQueuePtr)->length--; \ + } + +#define RESET_QUEUE(eventQueuePtr) \ + { \ + (eventQueuePtr)->base = 0; \ + (eventQueuePtr)->length = 0; \ + } + +/* node stack macros - used to browse a tree without using a recursive function */ +#define NODE_STACK_INIT(stack) { (stack)->nodeCount = 0; } +#define NODE_STACK_PUSH(stack, node, offset) { (stack)->nodes[(stack)->nodeCount] = (node); (stack)->offsets[(stack)->nodeCount++] = (offset); } +#define NODE_STACK_POP(stack, node, offset) { (node) = (stack)->nodes[--(stack)->nodeCount]; offset = (stack)->offsets[(stack)->nodeCount]; } +#define NODE_STACK_NONEMPTY(stack) ((stack)->nodeCount != 0) + +#ifndef IX_NDEBUG +#define IX_ETH_DB_NPE_MSG_HISTORY_DEPTH (100) +#define LOG_NPE_MSG(msg) \ + do { \ + UINT32 npeMsgHistoryIndex = (npeMsgHistoryLen++) % IX_ETH_DB_NPE_MSG_HISTORY_DEPTH; \ + npeMsgHistory[npeMsgHistoryIndex][0] = msg.data[0]; \ + npeMsgHistory[npeMsgHistoryIndex][1] = msg.data[1]; \ + } while (0); +#else +#define LOG_NPE_MSG() /* nothing */ +#endif + +/* ----------- Data -------------- */ + +/* typedefs */ + +typedef UINT32 (*HashFunction)(void *entity); +typedef BOOL (*MatchFunction)(void *reference, void *entry); +typedef void (*FreeFunction)(void *entry); + +/** + * basic component of a hash table + */ +typedef struct HashNode_t +{ + void *data; /**< specific data */ + struct HashNode_t *next; /**< used for bucket chaining */ + + __mempool__ struct HashNode_t *nextFree; /**< memory pool management */ + + __lock__ IxOsalFastMutex lock; /**< node lock */ +} HashNode; + +/** + * @brief hash table iterator definition + * + * an iterator is an object which can be used + * to browse a hash table + */ +typedef struct +{ + UINT32 bucketIndex; /**< index of the currently iterated bucket */ + HashNode *previousNode; /**< reference to the previously iterated node within the current bucket */ + HashNode *node; /**< reference to the currently iterated node */ +} HashIterator; + +/** + * definition of a MAC descriptor (a database record) + */ + +typedef enum +{ + IX_ETH_DB_WIFI_AP_TO_STA = 0x0, + IX_ETH_DB_WIFI_AP_TO_AP = 0x1 +} IxEthDBWiFiRecordType; + +typedef union +{ + struct + { + UINT32 age; + BOOL staticEntry; /**< TRUE if this address is static (doesn't age) */ + } filteringData; + + struct + { + UINT32 age; + BOOL staticEntry; + UINT32 ieee802_1qTag; + } filteringVlanData; + + struct + { + IxEthDBWiFiRecordType type; /**< AP_TO_AP (0x1) or AP_TO_STA (0x0) */ + UINT32 gwAddressIndex; /**< used only when linearizing the entries for NPE usage */ + UINT8 gwMacAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; + + __alignment__ UINT8 reserved2[2]; + } wifiData; +} IxEthDBRecordData; + +typedef struct MacDescriptor_t +{ + UINT8 macAddress[IX_IEEE803_MAC_ADDRESS_SIZE]; + + __alignment__ UINT8 reserved1[2]; + + UINT32 portID; + IxEthDBRecordType type; + IxEthDBRecordData recordData; + + /* used for internal operations, such as NPE linearization */ + void *internal; + + /* custom user data */ + void *user; + + __mempool__ struct MacDescriptor_t *nextFree; /**< memory pool management */ + __smartpointer__ UINT32 refCount; /**< smart pointer reference counter */ +} MacDescriptor; + +/** + * hash table definition + */ +typedef struct +{ + HashNode *hashBuckets[NUM_BUCKETS]; + UINT32 numBuckets; + + __lock__ IxOsalFastMutex bucketLocks[NUM_BUCKETS]; + + HashFunction entryHashFunction; + MatchFunction *matchFunctions; + FreeFunction freeFunction; +} HashTable; + +typedef enum +{ + IX_ETH_DB_MAC_KEY = 1, + IX_ETH_DB_MAC_PORT_KEY = 2, + IX_ETH_DB_MAC_VLAN_KEY = 3, + IX_ETH_DB_MAX_KEY_INDEX = 3 +} IxEthDBSearchKeyType; + +typedef struct MacTreeNode_t +{ + __smartpointer__ MacDescriptor *descriptor; + struct MacTreeNode_t *left, *right; + + __mempool__ struct MacTreeNode_t *nextFree; +} MacTreeNode; + +typedef IxEthDBStatus (*IxEthDBPortUpdateHandler)(IxEthDBPortId portID, IxEthDBRecordType type); + +typedef void (*IxEthDBNoteWriteFn)(void *address, MacTreeNode *node); + +typedef struct +{ + BOOL updateEnabled; /**< TRUE if updates are enabled for port */ + BOOL userControlled; /**< TRUE if the user has manually used ixEthDBPortUpdateEnableSet */ + BOOL treeInitialized; /**< TRUE if the NPE has received an initial tree */ + IxEthDBPortUpdateHandler updateHandler; /**< port update handler routine */ + void *npeUpdateZone; /**< port update memory zone */ + void *npeGwUpdateZone; /**< port update memory zone for gateways */ + void *vlanUpdateZone; /**< port update memory zone for VLAN tables */ + MacTreeNode *searchTree; /**< internal search tree, in MacTreeNode representation */ + BOOL searchTreePendingWrite; /**< TRUE if searchTree holds a tree pending write to the port */ +} PortUpdateMethod; + +typedef struct +{ + IxEthDBPortId portID; /**< port ID */ + BOOL enabled; /**< TRUE if the port is enabled */ + BOOL agingEnabled; /**< TRUE if aging on this port is enabled */ + BOOL initialized; + IxEthDBPortMap dependencyPortMap; /**< dependency port map for this port */ + PortUpdateMethod updateMethod; /**< update method structure */ + BOOL macAddressUploaded; /**< TRUE if the MAC address was uploaded into the port */ + UINT32 maxRxFrameSize; /**< maximum Rx frame size for this port */ + UINT32 maxTxFrameSize; /**< maximum Rx frame size for this port */ + + UINT8 bbsid[6]; + __alignment__ UINT8 reserved[2]; + UINT32 frameControlDurationID; /**< Frame Control - Duration/ID WiFi control */ + + IxEthDBVlanTag vlanTag; /**< default VLAN tag for port */ + IxEthDBPriorityTable priorityTable; /**< QoS <=> internal priority mapping */ + IxEthDBVlanSet vlanMembership; + IxEthDBVlanSet transmitTaggingInfo; + IxEthDBFrameFilter frameFilter; + IxEthDBTaggingAction taggingAction; + + UINT32 npeFrameFilter; + UINT32 npeTaggingAction; + + IxEthDBFirewallMode firewallMode; + BOOL srcAddressFilterEnabled; + + BOOL stpBlocked; + + IxEthDBFeature featureCapability; + IxEthDBFeature featureStatus; + + UINT32 ixEthDBTrafficClassAQMAssignments[IX_IEEE802_1Q_QOS_PRIORITY_COUNT]; + + UINT32 ixEthDBTrafficClassCount; + + UINT32 ixEthDBTrafficClassAvailable; + + + + __lock__ IxOsalMutex npeAckLock; +} PortInfo; + +/* list of port information structures indexed on port Ids */ +extern IX_ETH_DB_PUBLIC PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS]; + +typedef enum +{ + IX_ETH_DB_ADD_FILTERING_RECORD = 0xFF0001, + IX_ETH_DB_REMOVE_FILTERING_RECORD = 0xFF0002 +} PortEventType; + +typedef struct +{ + UINT32 eventType; + IxEthDBPortId portID; + IxEthDBMacAddr macAddr; + BOOL staticEntry; +} PortEvent; + +typedef struct +{ + PortEvent queue[EVENT_QUEUE_SIZE]; + UINT32 base; + UINT32 length; +} PortEventQueue; + +typedef struct +{ + IxEthDBPortId portID; /**< originating port */ + MacDescriptor *macDescriptors[MAX_ELT_SIZE]; /**< addresses to be synced into db */ + UINT32 addressCount; /**< number of addresses */ +} TreeSyncInfo; + +typedef struct +{ + MacTreeNode *nodes[MAX_ELT_SIZE]; + UINT32 offsets[MAX_ELT_SIZE]; + UINT32 nodeCount; +} MacTreeNodeStack; + +/* Prototypes */ + +/* ----------- Memory management -------------- */ + +IX_ETH_DB_PUBLIC void ixEthDBInitMemoryPools(void); + +IX_ETH_DB_PUBLIC HashNode* ixEthDBAllocHashNode(void); +IX_ETH_DB_PUBLIC void ixEthDBFreeHashNode(HashNode *); + +IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBAllocMacDescriptor(void); +IX_ETH_DB_PUBLIC __smartpointer__ MacDescriptor* ixEthDBCloneMacDescriptor(MacDescriptor *macDescriptor); +IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacDescriptor(MacDescriptor *); + +IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBAllocMacTreeNode(void); +IX_ETH_DB_PUBLIC __smartpointer__ MacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *); +IX_ETH_DB_PUBLIC __smartpointer__ void ixEthDBFreeMacTreeNode(MacTreeNode *); + +IX_ETH_DB_PUBLIC void ixEthDBPoolFreeMacTreeNode(MacTreeNode *); +IX_ETH_DB_PUBLIC UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree); +IX_ETH_DB_PUBLIC int ixEthDBShowMemoryStatus(void); + +/* Hash Table */ +IX_ETH_DB_PUBLIC void ixEthDBInitHash(HashTable *hashTable, UINT32 numBuckets, HashFunction entryHashFunction, MatchFunction *matchFunctions, FreeFunction freeFunction); + +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAddHashEntry(HashTable *hashTable, void *entry); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveHashEntry(HashTable *hashTable, int keyType, void *reference); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSearchHashEntry(HashTable *hashTable, int keyType, void *reference, HashNode **searchResult); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeekHashEntry(HashTable *hashTable, int keyType, void *reference); +IX_ETH_DB_PUBLIC void ixEthDBReleaseHashNode(HashNode *node); + +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInitHashIterator(HashTable *hashTable, HashIterator *iterator); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBIncrementHashIterator(HashTable *hashTable, HashIterator *iterator); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemoveEntryAtHashIterator(HashTable *hashTable, HashIterator *iterator); +IX_ETH_DB_PUBLIC void ixEthDBReleaseHashIterator(HashIterator *iterator); + +/* API Support */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr); +IX_ETH_DB_PUBLIC void ixEthDBMaximumFrameSizeAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); + +/* DB Core functions */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBInit(void); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBAdd(MacDescriptor *newRecordTemplate, IxEthDBPortMap updateTrigger); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBRemove(MacDescriptor *templateRecord, IxEthDBPortMap updateTrigger); +IX_ETH_DB_PUBLIC HashNode* ixEthDBSearch(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPeek(IxEthDBMacAddr *macAddress, IxEthDBRecordType typeFilter); + +/* Learning support */ +IX_ETH_DB_PUBLIC UINT32 ixEthDBAddressCompare(UINT8 *mac1, UINT8 *mac2); +IX_ETH_DB_PUBLIC BOOL ixEthDBAddressMatch(void *reference, void *entry); +IX_ETH_DB_PUBLIC UINT32 ixEthDBEntryXORHash(void *macDescriptor); +IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyXORHash(void *macAddress); + +/* Port updates */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBNPEUpdateHandler(IxEthDBPortId portID, IxEthDBRecordType type); +IX_ETH_DB_PUBLIC void ixEthDBUpdatePortLearningTrees(IxEthDBPortMap triggerPorts); +IX_ETH_DB_PUBLIC void ixEthDBNPEAccessRequest(IxEthDBPortId portID); +IX_ETH_DB_PUBLIC void ixEthDBUpdateLock(void); +IX_ETH_DB_PUBLIC void ixEthDBUpdateUnlock(void); +IX_ETH_DB_PUBLIC MacTreeNode* ixEthDBQuery(MacTreeNode *searchTree, IxEthDBPortMap query, IxEthDBRecordType recordFilter, UINT32 maximumEntries); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFirewallUpdate(IxEthDBPortId portID, void *address, UINT32 epDelta); + +/* Init/unload */ +IX_ETH_DB_PUBLIC void ixEthDBPortSetAckCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBEventProcessorInit(void); +IX_ETH_DB_PUBLIC void ixEthDBPortInit(IxEthDBPortId portID); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID); +IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasInit(void); +IX_ETH_DB_PUBLIC UINT32 ixEthDBMatchMethodsRegister(MatchFunction *matchFunctions); +IX_ETH_DB_PUBLIC UINT32 ixEthDBRecordSerializeMethodsRegister(void); +IX_ETH_DB_PUBLIC UINT32 ixEthDBUpdateTypeRegister(BOOL *typeArray); +IX_ETH_DB_PUBLIC void ixEthDBNPEUpdateAreasUnload(void); +IX_ETH_DB_PUBLIC void ixEthDBFeatureCapabilityScan(void); +IX_ETH_DB_PUBLIC UINT32 ixEthDBKeyTypeRegister(UINT32 *keyType); + +/* Event processing */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBDefaultEventCallbackEnable(IxEthDBPortId portID, BOOL enable); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerAddPortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID, BOOL staticEntry); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBTriggerRemovePortUpdate(IxEthDBMacAddr *macAddr, IxEthDBPortId portID); +IX_ETH_DB_PUBLIC void ixEthDBNPEEventCallback(IxNpeMhNpeId npeID, IxNpeMhMessage msg); + +/* NPE adaptor */ +IX_ETH_DB_PUBLIC void ixEthDBGetMacDatabaseCbk(IxNpeMhNpeId npeID, IxNpeMhMessage msg); +IX_ETH_DB_PUBLIC void ixEthDBNpeMsgAck(IxNpeMhNpeId npeID, IxNpeMhMessage msg); +IX_ETH_DB_PUBLIC void ixEthDBNPESyncScan(IxEthDBPortId portID, void *eltBaseAddress, UINT32 eltSize); +IX_ETH_DB_PUBLIC void ixEthDBNPETreeWrite(IxEthDBRecordType type, UINT32 totalSize, void *baseAddress, MacTreeNode *tree, UINT32 *blocks, UINT32 *startIndex); +IX_ETH_DB_PUBLIC void ixEthDBNPEGatewayNodeWrite(void *address, MacTreeNode *node); + +/* Other public API functions */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStartLearningFunction(void); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBStopLearningFunction(void); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortUpdateEnableSet(IxEthDBPortId portID, BOOL enableUpdate); + +/* Maximum Tx/Rx public functions */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize); +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize); + +/* VLAN-related */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet); + +/* Record search */ +IX_ETH_DB_PUBLIC BOOL ixEthDBAddressRecordMatch(void *untypedReference, void *untypedEntry); +IX_ETH_DB_PUBLIC BOOL ixEthDBVlanRecordMatch(void *untypedReference, void *untypedEntry); +IX_ETH_DB_PUBLIC BOOL ixEthDBPortRecordMatch(void *untypedReference, void *untypedEntry); +IX_ETH_DB_PUBLIC BOOL ixEthDBNullMatch(void *reference, void *entry); +IX_ETH_DB_PUBLIC HashNode* ixEthDBPortSearch(IxEthDBMacAddr *macAddress, IxEthDBPortId portID, IxEthDBRecordType typeFilter); +IX_ETH_DB_PUBLIC HashNode* ixEthDBVlanSearch(IxEthDBMacAddr *macAddress, IxEthDBVlanId vlanID, IxEthDBRecordType typeFilter); + +/* Utilities */ +IX_ETH_DB_PUBLIC const char* mac2string(const unsigned char *mac); +IX_ETH_DB_PUBLIC void showHashInfo(void); +IX_ETH_DB_PUBLIC int ixEthDBAnalyzeHash(void); +IX_ETH_DB_PUBLIC const char* errorString(IxEthDBStatus error); +IX_ETH_DB_PUBLIC int numHashElements(void); +IX_ETH_DB_PUBLIC void zapHashtable(void); +IX_ETH_DB_PUBLIC BOOL ixEthDBCheckSingleBitValue(UINT32 value); + +/* Single Eth NPE Check */ +IX_ETH_DB_PUBLIC IxEthDBStatus ixEthDBSingleEthNpeCheck(IxEthDBPortId portId); + +#endif /* IxEthDB_p_H */ + diff --git a/drivers/net/npe/include/IxEthMii.h b/drivers/net/npe/include/IxEthMii.h new file mode 100644 index 0000000..397253a --- /dev/null +++ b/drivers/net/npe/include/IxEthMii.h @@ -0,0 +1,270 @@ +/** + * @file IxEthMii.h + * + * @brief this file contains the public API of @ref IxEthMii component + * + * Design notes : + * The main intent of this API is to inplement MII high level fonctionalitoes + * to support the codelets provided with the IXP400 software releases. It + * superceedes previous interfaces provided with @ref IxEThAcc component. + * + * This API has been tested with the PHYs provided with the + * IXP400 development platforms. It may not work for specific Ethernet PHYs + * used on specific boards. + * + * This source code detects and interface the LXT972, LXT973 and KS6995 + * Ethernet PHYs. + * + * This source code should be considered as an example which may need + * to be adapted for different hardware implementations. + * + * It is strongly recommended to use public domain and GPL utilities + * like libmii, mii-diag for MII interface support. + * + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#ifndef IxEthMii_H +#define IxEthMii_H + +#include + +/** + * @defgroup IxEthMii IXP400 Ethernet Phy Access (IxEthMii) API + * + * @brief ethMii is a library that does provides access to the + * Ethernet PHYs + * + *@{ + */ + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount) + * + * @brief Scan the MDIO bus for PHYs + * This function scans PHY addresses 0 through 31, and sets phyPresent[n] to + * TRUE if a phy is discovered at address n. + * + * - Reentrant - no + * - ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyPresent BOOL [in] - boolean array of IXP425_ETH_ACC_MII_MAX_ADDR entries + * @param maxPhyCount UINT32 [in] - number of PHYs to search for (the scan will stop when + * the indicated number of PHYs is found). + * + * @return IX_STATUS + * - IX_ETH_ACC_SUCCESS + * - IX_ETH_ACC_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IX_STATUS ixEthMiiPhyScan(BOOL phyPresent[], UINT32 maxPhyCount); + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyConfig(UINT32 phyAddr, + BOOL speed100, + BOOL fullDuplex, + BOOL autonegotiate) + * + * + * @brief Configure a PHY + * Configure a PHY's speed, duplex and autonegotiation status + * + * - Reentrant - no + * - ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT32 [in] + * @param speed100 BOOL [in] - set to TRUE for 100Mbit/s operation, FALSE for 10Mbit/s + * @param fullDuplex BOOL [in] - set to TRUE for Full Duplex, FALSE for Half Duplex + * @param autonegotiate BOOL [in] - set to TRUE to enable autonegotiation + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IX_STATUS ixEthMiiPhyConfig(UINT32 phyAddr, + BOOL speed100, + BOOL fullDuplex, + BOOL autonegotiate); + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyLoopbackEnable(UINT32 phyAddr) + * + * + * @brief Enable PHY Loopback in a specific Eth MII port + * + * @note When PHY Loopback is enabled, frames sent out to the PHY from the + * IXP400 will be looped back to the IXP400. They will not be transmitted out + * on the wire. + * + * - Reentrant - no + * - ISR Callable - no + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + *
+ */ +PUBLIC IX_STATUS +ixEthMiiPhyLoopbackEnable (UINT32 phyAddr); + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyLoopbackDisable(UINT32 phyAddr) + * + * + * @brief Disable PHY Loopback in a specific Eth MII port + * + * - Reentrant - no + * - ISR Callable - no + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + *
+ */ +PUBLIC IX_STATUS +ixEthMiiPhyLoopbackDisable (UINT32 phyAddr); + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyReset(UINT32 phyAddr) + * + * @brief Reset a PHY + * Reset a PHY + * + * - Reentrant - no + * - ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IX_STATUS ixEthMiiPhyReset(UINT32 phyAddr); + + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiLinkStatus(UINT32 phyAddr, + BOOL *linkUp, + BOOL *speed100, + BOOL *fullDuplex, + BOOL *autoneg) + * + * @brief Retrieve the current status of a PHY + * Retrieve the link, speed, duplex and autonegotiation status of a PHY + * + * - Reentrant - no + * - ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * @param linkUp BOOL [out] - set to TRUE if the link is up + * @param speed100 BOOL [out] - set to TRUE indicates 100Mbit/s, FALSE indicates 10Mbit/s + * @param fullDuplex BOOL [out] - set to TRUE indicates Full Duplex, FALSE indicates Half Duplex + * @param autoneg BOOL [out] - set to TRUE indicates autonegotiation is enabled, FALSE indicates autonegotiation is disabled + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IX_STATUS ixEthMiiLinkStatus(UINT32 phyAddr, + BOOL *linkUp, + BOOL *speed100, + BOOL *fullDuplex, + BOOL *autoneg); + +/** + * @ingroup IxEthMii + * + * @fn ixEthMiiPhyShow (UINT32 phyAddr) + * + * + * @brief Display information on a specified PHY + * Display link status, speed, duplex and Auto Negotiation status + * + * - Reentrant - no + * - ISR Callable - no + * + * @pre The MAC on Ethernet Port 2 (NPE C) must be initialised, and generating the MDIO clock. + * + * @param phyAddr UINT32 [in] - the address of the Ethernet PHY (0-31) + * + * @return IX_STATUS + * - IX_SUCCESS + * - IX_FAIL : invalid arguments. + * + *
+ */ +PUBLIC IX_STATUS ixEthMiiPhyShow (UINT32 phyAddr); + +#endif /* ndef IxEthMii_H */ +/** + *@} + */ diff --git a/drivers/net/npe/include/IxEthMii_p.h b/drivers/net/npe/include/IxEthMii_p.h new file mode 100644 index 0000000..104b65c --- /dev/null +++ b/drivers/net/npe/include/IxEthMii_p.h @@ -0,0 +1,185 @@ +/** + * @file IxEthMii_p.h + * + * @author Intel Corporation + * @date + * + * @brief MII Header file + * + * Design Notes: + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +#ifndef IxEthMii_p_H +#define IxEthMii_p_H + + +/* MII definitions - these have been verified against the LXT971 and + LXT972 PHYs*/ + +#define IX_ETH_MII_MAX_REG_NUM 0x20 /* max number of registers */ + +#define IX_ETH_MII_CTRL_REG 0x0 /* Control Register */ +#define IX_ETH_MII_STAT_REG 0x1 /* Status Register */ +#define IX_ETH_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */ +#define IX_ETH_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */ +#define IX_ETH_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */ + /* Advertisement Register */ +#define IX_ETH_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */ + /* partner ability Register */ +#define IX_ETH_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */ + /* Expansion Register */ +#define IX_ETH_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */ + /* next-page transmit Register */ + +#define IX_ETH_MII_STAT2_REG 0x11 /* Status Register 2*/ + + +/* MII control register bit */ + +#define IX_ETH_MII_CR_COLL_TEST 0x0080 /* collision test */ +#define IX_ETH_MII_CR_FDX 0x0100 /* FDX =1, half duplex =0 */ +#define IX_ETH_MII_CR_RESTART 0x0200 /* restart auto negotiation */ +#define IX_ETH_MII_CR_ISOLATE 0x0400 /* isolate PHY from MII */ +#define IX_ETH_MII_CR_POWER_DOWN 0x0800 /* power down */ +#define IX_ETH_MII_CR_AUTO_EN 0x1000 /* auto-negotiation enable */ +#define IX_ETH_MII_CR_100 0x2000 /* 0 = 10mb, 1 = 100mb */ +#define IX_ETH_MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ +#define IX_ETH_MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ +#define IX_ETH_MII_CR_NORM_EN 0x0000 /* just enable the PHY */ +#define IX_ETH_MII_CR_DEF_0_MASK 0xca7f /* they must return zero */ +#define IX_ETH_MII_CR_RES_MASK 0x007f /* reserved bits, return zero */ + +/* MII Status register bit definitions */ + +#define IX_ETH_MII_SR_LINK_STATUS 0x0004 /* link Status -- 1 = link */ +#define IX_ETH_MII_SR_AUTO_SEL 0x0008 /* auto speed select capable */ +#define IX_ETH_MII_SR_REMOTE_FAULT 0x0010 /* Remote fault detect */ +#define IX_ETH_MII_SR_AUTO_NEG 0x0020 /* auto negotiation complete */ +#define IX_ETH_MII_SR_10T_HALF_DPX 0x0800 /* 10BaseT HD capable */ +#define IX_ETH_MII_SR_10T_FULL_DPX 0x1000 /* 10BaseT FD capable */ +#define IX_ETH_MII_SR_TX_HALF_DPX 0x2000 /* TX HD capable */ +#define IX_ETH_MII_SR_TX_FULL_DPX 0x4000 /* TX FD capable */ +#define IX_ETH_MII_SR_T4 0x8000 /* T4 capable */ +#define IX_ETH_MII_SR_ABIL_MASK 0xff80 /* abilities mask */ +#define IX_ETH_MII_SR_EXT_CAP 0x0001 /* extended capabilities */ + + +/* LXT971/2 Status 2 register bit definitions */ +#define IX_ETH_MII_SR2_100 0x4000 +#define IX_ETH_MII_SR2_TX 0x2000 +#define IX_ETH_MII_SR2_RX 0x1000 +#define IX_ETH_MII_SR2_COL 0x0800 +#define IX_ETH_MII_SR2_LINK 0x0400 +#define IX_ETH_MII_SR2_FD 0x0200 +#define IX_ETH_MII_SR2_AUTO 0x0100 +#define IX_ETH_MII_SR2_AUTO_CMPLT 0x0080 +#define IX_ETH_MII_SR2_POLARITY 0x0020 +#define IX_ETH_MII_SR2_PAUSE 0x0010 +#define IX_ETH_MII_SR2_ERROR 0x0008 + +/* MII Link Code word bit definitions */ + +#define IX_ETH_MII_BP_FAULT 0x2000 /* remote fault */ +#define IX_ETH_MII_BP_ACK 0x4000 /* acknowledge */ +#define IX_ETH_MII_BP_NP 0x8000 /* nexp page is supported */ + +/* MII Next Page bit definitions */ + +#define IX_ETH_MII_NP_TOGGLE 0x0800 /* toggle bit */ +#define IX_ETH_MII_NP_ACK2 0x1000 /* acknowledge two */ +#define IX_ETH_MII_NP_MSG 0x2000 /* message page */ +#define IX_ETH_MII_NP_ACK1 0x4000 /* acknowledge one */ +#define IX_ETH_MII_NP_NP 0x8000 /* nexp page will follow */ + +/* MII Expansion Register bit definitions */ + +#define IX_ETH_MII_EXP_FAULT 0x0010 /* parallel detection fault */ +#define IX_ETH_MII_EXP_PRTN_NP 0x0008 /* link partner next-page able */ +#define IX_ETH_MII_EXP_LOC_NP 0x0004 /* local PHY next-page able */ +#define IX_ETH_MII_EXP_PR 0x0002 /* full page received */ +#define IX_ETH_MII_EXP_PRT_AN 0x0001 /* link partner auto neg able */ + +/* technology ability field bit definitions */ + +#define IX_ETH_MII_TECH_10BASE_T 0x0020 /* 10Base-T */ +#define IX_ETH_MII_TECH_10BASE_FD 0x0040 /* 10Base-T Full Duplex */ +#define IX_ETH_MII_TECH_100BASE_TX 0x0080 /* 100Base-TX */ +#define IX_ETH_MII_TECH_100BASE_TX_FD 0x0100 /* 100Base-TX Full Duplex */ + +#define IX_ETH_MII_TECH_100BASE_T4 0x0200 /* 100Base-T4 */ +#define IX_ETH_MII_ADS_TECH_MASK 0x1fe0 /* technology abilities mask */ +#define IX_ETH_MII_TECH_MASK IX_ETH_MII_ADS_TECH_MASK +#define IX_ETH_MII_ADS_SEL_MASK 0x001f /* selector field mask */ + +#define IX_ETH_MII_AN_FAIL 0x10 /* auto-negotiation fail */ +#define IX_ETH_MII_STAT_FAIL 0x20 /* errors in the status register */ +#define IX_ETH_MII_PHY_NO_ABLE 0x40 /* the PHY lacks some abilities */ + +/* Definitions for MII access routines*/ + +#define IX_ETH_MII_GO BIT(31) +#define IX_ETH_MII_WRITE BIT(26) +#define IX_ETH_MII_TIMEOUT_10TH_SECS (5) +#define IX_ETH_MII_10TH_SEC_IN_MILLIS (100) +#define IX_ETH_MII_READ_FAIL BIT(31) + +/* When we reset the PHY we delay for 2 seconds to allow the reset to + complete*/ +#define IX_ETH_MII_RESET_DELAY_MS (2000) +#define IX_ETH_MII_RESET_POLL_MS (50) + +#define IX_ETH_MII_REG_SHL 16 +#define IX_ETH_MII_ADDR_SHL 21 + +/* supported PHYs */ +#define IX_ETH_MII_LXT971_PHY_ID 0x001378E0 +#define IX_ETH_MII_LXT972_PHY_ID 0x001378E2 +#define IX_ETH_MII_LXT973_PHY_ID 0x00137A10 +#define IX_ETH_MII_LXT973A3_PHY_ID 0x00137A11 +#define IX_ETH_MII_KS8995_PHY_ID 0x00221450 +#define IX_ETH_MII_LXT9785_PHY_ID 0x001378FF + + +#define IX_ETH_MII_INVALID_PHY_ID 0x00000000 +#define IX_ETH_MII_UNKNOWN_PHY_ID 0xffffffff + +#endif /*IxEthAccMii_p_H*/ diff --git a/drivers/net/npe/include/IxEthNpe.h b/drivers/net/npe/include/IxEthNpe.h new file mode 100644 index 0000000..21bdedc --- /dev/null +++ b/drivers/net/npe/include/IxEthNpe.h @@ -0,0 +1,695 @@ +#ifndef __doxygen_HIDE /* This file is not part of the API */ + +/** + * @file IxEthNpe.h + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/** + * @defgroup IxEthNpe IXP400 Ethernet NPE (IxEthNpe) API + * + * @brief Contains the API for Ethernet NPE. + * + * All messages given to NPE, get back an acknowledgment. The acknowledgment + * is identical to the message sent to the NPE (except for NPE_GETSTATUS message). + * + * @{ + */ + + +/*-------------------------------------------------------------------------- + * APB Message IDs - XScale->NPE + *------------------------------------------------------------------------*/ + +/** + * @def IX_ETHNPE_NPE_GETSTATUS + * + * @brief Request from the XScale client for the NPE to return the firmware + * version of the currently executing image. + * + * Acknowledgment message id is same as the request message id. + * NPE returns the firmware version ID to XScale. + */ +#define IX_ETHNPE_NPE_GETSTATUS 0x00 + +/** + * @def IX_ETHNPE_EDB_SETPORTADDRESS + * + * @brief Request from the XScale client for the NPE to set the Ethernet + * port's port ID and MAC address. + */ +#define IX_ETHNPE_EDB_SETPORTADDRESS 0x01 + +/** + * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE + * + * @brief Request from XScale client to the NPE requesting upload of + * Ethernet Filtering Database or Header Conversion Database from NPE's + * data memory to XScale accessible SDRAM. + */ +#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE 0x02 + +/** + * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE + * + * @brief Request from XScale client to the NPE requesting download of + * Ethernet Filtering Database or Header Conversion Database from SDRAM + * to the NPE's datamemory. + */ +#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE 0x03 + +/** + * @def IX_ETHNPE_GETSTATS + * + * @brief Request from the XScale client for the current MAC port statistics + * data to be written to the (empty) statistics structure and the specified + * location in externa memory. + */ +#define IX_ETHNPE_GETSTATS 0x04 + +/** + * @def IX_ETHNPE_RESETSTATS + * + * @brief Request from the XScale client to the NPE to reset all of its internal + * MAC port statistics state variables. + * + * As a side effect, this message entails an implicit request that the NPE + * write the current MAC port statistics into the MAC statistics structure + * at the specified location in external memory. + */ +#define IX_ETHNPE_RESETSTATS 0x05 + +/** + * @def IX_ETHNPE_SETMAXFRAMELENGTHS + * + * @brief Request from the XScale client to the NPE to configure maximum framelengths + * and block sizes in receive and transmit direction. + */ +#define IX_ETHNPE_SETMAXFRAMELENGTHS 0x06 + +/** + * @def IX_ETHNPE_VLAN_SETRXTAGMODE + * + * @brief Request from the XScale client to the NPE to configure VLAN frame type + * filtering and VLAN the tagging mode for the receiver. + */ +#define IX_ETHNPE_VLAN_SETRXTAGMODE 0x07 + +/** + * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID + * + * @brief Request from the XScale client to the NPE to set receiver's default + * VLAN tag (PVID)and internal traffic class. + */ +#define IX_ETHNPE_VLAN_SETDEFAULTRXVID 0x08 + +/** + * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY + * + * @brief Request from the XScale client to the NPE to configure VLAN Port + * membership and Tx tagging for 8 consecutive VLANID's. + */ +#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY 0x09 + +/** + * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE + * + * @brief Request from the XScale client to the NPE to configure VLAN Port + * membership and Tx tagging for a range of VLANID's. + */ +#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE 0x0A + +/** + * @def IX_ETHNPE_VLAN_SETRXQOSENTRY + * + * @brief Request from the XScale client to the NPE to map a user priority + * to QoS class and an AQM queue number. + */ +#define IX_ETHNPE_VLAN_SETRXQOSENTRY 0x0B + +/** + * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE + * + * @brief Request from the XScale client to the NPE to enable or disable + * portID extraction from VLAN-tagged frames for the specified port. + */ +#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE 0x0C + +/** + * @def IX_ETHNPE_STP_SETBLOCKINGSTATE + * + * @brief Request from the XScale client to the NPE to block or unblock + * forwarding for spanning tree BPDUs. + */ +#define IX_ETHNPE_STP_SETBLOCKINGSTATE 0x0D + +/** + * @def IX_ETHNPE_FW_SETFIREWALLMODE + * + * @brief Request from the XScale client to the NPE to configure firewall + * services modes of operation and/or download Ethernet Firewall Database from + * SDRAM to NPE. + */ +#define IX_ETHNPE_FW_SETFIREWALLMODE 0x0E + +/** + * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID + * + * @brief Request from the XScale client to the NPE to set global frame control + * and duration/ID field for the 802.3 to 802.11 protocol header conversion + * service. + */ +#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID 0x0F + +/** + * @def IX_ETHNPE_PC_SETBBSID + * + * @brief Request from the XScale client to the NPE to set global BBSID field + * value for the 802.3 to 802.11 protocol header conversion service. + */ +#define IX_ETHNPE_PC_SETBBSID 0x10 + +/** + * @def IX_ETHNPE_PC_SETAPMACTABLE + * + * @brief Request from the XScale client to the NPE to update a block/section/ + * range of the AP MAC Address Table. + */ +#define IX_ETHNPE_PC_SETAPMACTABLE 0x11 + +/** + * @def IX_ETHNPE_SETLOOPBACK_MODE + * + * @brief Turn on or off the NPE frame loopback. + */ +#define IX_ETHNPE_SETLOOPBACK_MODE (0x12) + +/*-------------------------------------------------------------------------- + * APB Message IDs - NPE->XScale + *------------------------------------------------------------------------*/ + +/** + * @def IX_ETHNPE_NPE_GETSTATUS_ACK + * + * @brief Acknowledgment to IX_ETHNPE_NPE_GETSTATUS message. NPE firmware version + * id is returned in the message. + */ +#define IX_ETHNPE_NPE_GETSTATUS_ACK 0x00 + +/** + * @def IX_ETHNPE_EDB_SETPORTADDRESS_ACK + * + * @brief Acknowledgment to IX_ETHNPE_EDB_SETPORTADDRESS message. + */ +#define IX_ETHNPE_EDB_SETPORTADDRESS_ACK 0x01 + +/** + * @def IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_EDB_GETMACADDRESSDATABASE message + */ +#define IX_ETHNPE_EDB_GETMACADDRESSDATABASE_ACK 0x02 + +/** + * @def IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_EDB_SETMACADDRESSSDATABASE message. + */ +#define IX_ETHNPE_EDB_SETMACADDRESSSDATABASE_ACK 0x03 + +/** + * @def IX_ETHNPE_GETSTATS_ACK + * + * @brief Acknowledgment to IX_ETHNPE_GETSTATS message. + */ +#define IX_ETHNPE_GETSTATS_ACK 0x04 + +/** + * @def IX_ETHNPE_RESETSTATS_ACK + * + * @brief Acknowledgment to IX_ETHNPE_RESETSTATS message. + */ +#define IX_ETHNPE_RESETSTATS_ACK 0x05 + +/** + * @def IX_ETHNPE_SETMAXFRAMELENGTHS_ACK + * + * @brief Acknowledgment to IX_ETHNPE_SETMAXFRAMELENGTHS message. + */ +#define IX_ETHNPE_SETMAXFRAMELENGTHS_ACK 0x06 + +/** + * @def IX_ETHNPE_VLAN_SETRXTAGMODE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXTAGMODE message. + */ +#define IX_ETHNPE_VLAN_SETRXTAGMODE_ACK 0x07 + +/** + * @def IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETDEFAULTRXVID message. + */ +#define IX_ETHNPE_VLAN_SETDEFAULTRXVID_ACK 0x08 + +/** + * @def IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY message. + */ +#define IX_ETHNPE_VLAN_SETPORTVLANTABLEENTRY_ACK 0x09 + +/** + * @def IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE message. + */ +#define IX_ETHNPE_VLAN_SETPORTVLANTABLERANGE_ACK 0x0A + +/** + * @def IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETRXQOSENTRY message. + */ +#define IX_ETHNPE_VLAN_SETRXQOSENTRY_ACK 0x0B + +/** + * @def IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE message. + */ +#define IX_ETHNPE_VLAN_SETPORTIDEXTRACTIONMODE_ACK 0x0C + +/** + * @def IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_STP_SETBLOCKINGSTATE message. + */ +#define IX_ETHNPE_STP_SETBLOCKINGSTATE_ACK 0x0D + +/** + * @def IX_ETHNPE_FW_SETFIREWALLMODE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_FW_SETFIREWALLMODE message. + */ +#define IX_ETHNPE_FW_SETFIREWALLMODE_ACK 0x0E + +/** + * @def IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK + * + * @brief Acknowledgment to IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID message. + */ +#define IX_ETHNPE_PC_SETFRAMECONTROLDURATIONID_ACK 0x0F + +/** + * @def IX_ETHNPE_PC_SETBBSID_ACK + * + * @brief Acknowledgment to IX_ETHNPE_PC_SETBBSID message. + */ +#define IX_ETHNPE_PC_SETBBSID_ACK 0x10 + +/** + * @def IX_ETHNPE_PC_SETAPMACTABLE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_PC_SETAPMACTABLE message. + */ +#define IX_ETHNPE_PC_SETAPMACTABLE_ACK 0x11 + +/** + * @def IX_ETHNPE_SETLOOPBACK_MODE_ACK + * + * @brief Acknowledgment to IX_ETHNPE_SETLOOPBACK_MODE message. + */ +#define IX_ETHNPE_SETLOOPBACK_MODE_ACK (0x12) + +/*-------------------------------------------------------------------------- + * Queue Manager Queue entry bit field boundary definitions + *------------------------------------------------------------------------*/ + +/** + * @def MASK(hi,lo) + * + * @brief Macro for mask + */ +#define MASK(hi,lo) (((1 << (1 + ((hi) - (lo)))) - 1) << (lo)) + +/** + * @def BITS(x,hi,lo) + * + * @brief Macro for bits + */ +#define BITS(x,hi,lo) (((x) & MASK(hi,lo)) >> (lo)) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK + * + * @brief QMgr Queue LENGTH field mask + */ +#define IX_ETHNPE_QM_Q_RXENET_LENGTH_MASK 0x3fff + +/** + * @def IX_ETHNPE_QM_Q_FIELD_FLAG_R + * + * @brief QMgr Queue FLAG field right boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_FLAG_R 20 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_FLAG_MASK + * + * @brief QMgr Queue FLAG field mask + * + * Multicast bit : BIT(4) + * Broadcast bit : BIT(5) + * IP bit : BIT(6) (linux only) + * + */ +#ifdef __vxworks +#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x30 +#else +#define IX_ETHNPE_QM_Q_FIELD_FLAG_MASK 0x70 +#endif + + +/** + * @def IX_ETHNPE_QM_Q_FIELD_NPEID_L + * + * @brief QMgr Queue NPE ID field left boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_NPEID_L 1 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_NPEID_R + * + * @brief QMgr Queue NPE ID field right boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_NPEID_R 0 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_L + * + * @brief QMgr Queue Priority field left boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_PRIOR_L 2 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_PRIOR_R + * + * @brief QMgr Queue Priority field right boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_PRIOR_R 0 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_ADDR_L + * + * @brief QMgr Queue Address field left boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_ADDR_L 31 + +/** + * @def IX_ETHNPE_QM_Q_FIELD_ADDR_R + * + * @brief QMgr Queue Address field right boundary + */ +#define IX_ETHNPE_QM_Q_FIELD_ADDR_R 5 + +/*-------------------------------------------------------------------------- + * Queue Manager Queue entry bit field masks + *------------------------------------------------------------------------*/ + +/** + * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK + * + * @brief Macro to mask the Address field of the FreeEnet Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ + IX_ETHNPE_QM_Q_FIELD_ADDR_R) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_NPEID_MASK + * + * @brief Macro to mask the NPE ID field of the RxEnet Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_RXENET_NPEID_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ + IX_ETHNPE_QM_Q_FIELD_NPEID_R) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_ADDR_MASK + * + * @brief Macro to mask the Mbuf Address field of the RxEnet Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_RXENET_ADDR_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ + IX_ETHNPE_QM_Q_FIELD_ADDR_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK + * + * @brief Macro to mask the Priority field of the TxEnet Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_TXENET_PRIOR_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \ + IX_ETHNPE_QM_Q_FIELD_PRIOR_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENET_ADDR_MASK + * + * @brief Macro to mask the Mbuf Address field of the TxEnet Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_TXENET_ADDR_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ + IX_ETHNPE_QM_Q_FIELD_ADDR_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK + * + * @brief Macro to mask the NPE ID field of the TxEnetDone Queue Manager Entry + */ +#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ + IX_ETHNPE_QM_Q_FIELD_NPEID_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK + * + * @brief Macro to mask the Mbuf Address field of the TxEnetDone Queue Manager + * Entry + */ +#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK \ + MASK (IX_ETHNPE_QM_Q_FIELD_ADDR_L, \ + IX_ETHNPE_QM_Q_FIELD_ADDR_R) + +/*-------------------------------------------------------------------------- + * Queue Manager Queue entry bit field value extraction macros + *------------------------------------------------------------------------*/ + +/** + * @def IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x) + * + * @brief Extraction macro for Address field of FreeNet Queue Manager Entry + * + * Pointer to an mbuf buffer descriptor + */ +#define IX_ETHNPE_QM_Q_FREEENET_ADDR_VAL(x) \ + ((x) & IX_ETHNPE_QM_Q_FREEENET_ADDR_MASK) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x) + * + * @brief Extraction macro for NPE ID field of RxEnet Queue Manager Entry + * + * Set to 0 for entries originating from the Eth0 NPE; + * Set to 1 for entries originating from the Eth1 NPE. + */ +#define IX_ETHNPE_QM_Q_RXENET_NPEID_VAL(x) \ + BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ + IX_ETHNPE_QM_Q_FIELD_NPEID_R) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x) + * + * @brief Extraction macro for Port ID field of RxEnet Queue Manager Entry + * + * 0-5: Assignable (by the XScale client) to any of the physical ports. + * 6: It is reserved + * 7: Indication that the NPE did not find the associated frame's destination MAC address within + * its internal filtering database. + */ +#define IX_ETHNPE_QM_Q_RXENET_PORTID_VAL(x) \ + BITS (x, IX_ETHNPE_QM_Q_FIELD_PORTID_L, \ + IX_ETHNPE_QM_Q_Field_PortID_R) + +/** + * @def IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x) + * + * @brief Extraction macro for Address field of RxEnet Queue Manager Entry + * + * Pointer to an mbuf buffer descriptor + */ +#define IX_ETHNPE_QM_Q_RXENET_ADDR_VAL(x) \ + ((x) & IX_ETHNPE_QM_Q_RXENET_ADDR_MASK) + +/** + * @def IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x) + * + * @brief Extraction macro for Priority field of TxEnet Queue Manager Entry + * + * Priority of the packet (as described in IEEE 802.1D). This field is + * cleared upon return from the Ethernet NPE to the TxEnetDone queue. + */ +#define IX_ETHNPE_QM_Q_TXENET_PRIOR_VAL(x) \ + BITS (x, IX_ETHNPE_QM_Q_FIELD_PRIOR_L, \ + IX_ETHNPE_QM_Q_FIELD_PRIOR_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x) + * + * @brief Extraction macro for Address field of Queue Manager TxEnet Queue + * Manager Entry + * + * Pointer to an mbuf buffer descriptor + */ +#define IX_ETHNPE_QM_Q_TXENET_ADDR_VAL(x) \ + ((x) & IX_ETHNPE_QM_Q_TXENET_ADDR_MASK) + +/** + * @def IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x) + * + * @brief Extraction macro for NPE ID field of TxEnetDone Queue Manager Entry + * + * Set to 0 for entries originating from the Eth0 NPE; set to 1 for en-tries + * originating from the Eth1 NPE. + */ +#define IX_ETHNPE_QM_Q_TXENETDONE_NPEID_VAL(x) \ + BITS (x, IX_ETHNPE_QM_Q_FIELD_NPEID_L, \ + IX_ETHNPE_QM_Q_FIELD_NPEID_R) + +/** + * @def IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x) + * + * @brief Extraction macro for Address field of TxEnetDone Queue Manager Entry + * + * Pointer to an mbuf buffer descriptor + */ +#define IX_ETHNPE_QM_Q_TXENETDONE_ADDR_VAL(x) \ + ((x) & IX_ETHNPE_QM_Q_TXENETDONE_ADDR_MASK) + + +/*-------------------------------------------------------------------------- + * NPE limits + *------------------------------------------------------------------------*/ + +/** + * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN + * + * @brief Macro to check the minimum length of a rx free buffer + */ +#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MIN (64) + +/** + * @def IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK + * + * @brief Mask to apply to the mbuf length before submitting it to the NPE + * (the NPE handles only rx free mbufs which are multiple of 64) + * + * @sa IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK + */ +#define IX_ETHNPE_ACC_RXFREE_BUFFER_LENGTH_MASK (~63) + +/** + * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size) + * + * @brief Round up to get the size necessary to receive without chaining + * the frames which are (size) bytes (the NPE operates by multiple of 64) + * e.g. To receive 1514 bytes frames, the size of the buffers in replenish + * has to be at least (1514+63)&(~63) = 1536 bytes. + * + */ +#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_UP(size) (((size) + 63) & ~63) + +/** + * @def IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size) + * + * @brief Round down to apply to the mbuf length before submitting + * it to the NPE. (the NPE operates by multiple of 64) + * + */ +#define IX_ETHNPE_ACC_RXFREE_BUFFER_ROUND_DOWN(size) ((size) & ~63) + +/** + * @def IX_ETHNPE_ACC_FRAME_LENGTH_MAX + * + * @brief maximum mbuf length supported by the NPE + * + * @sa IX_ETHNPE_ACC_FRAME_LENGTH_MAX + */ +#define IX_ETHNPE_ACC_FRAME_LENGTH_MAX (16320) + +/** + * @def IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT + * + * @brief default mbuf length supported by the NPE + * + * @sa IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT + */ +#define IX_ETHNPE_ACC_FRAME_LENGTH_DEFAULT (1522) + +/** + * @def IX_ETHNPE_ACC_LENGTH_OFFSET + * + * @brief Offset of the cluster length field in the word shared with the NPEs + */ +#define IX_ETHNPE_ACC_LENGTH_OFFSET 16 + +/** + * @def IX_ETHNPE_ACC_PKTLENGTH_MASK + * + * @brief Mask of the cluster length field in the word shared with the NPEs + */ +#define IX_ETHNPE_ACC_PKTLENGTH_MASK 0x3fff + + +/** + *@} + */ + +#endif /* __doxygen_HIDE */ diff --git a/drivers/net/npe/include/IxFeatureCtrl.h b/drivers/net/npe/include/IxFeatureCtrl.h new file mode 100644 index 0000000..dabc38e --- /dev/null +++ b/drivers/net/npe/include/IxFeatureCtrl.h @@ -0,0 +1,742 @@ +/** + * @file IxFeatureCtrl.h + * + * @date 30-Jan-2003 + + * @brief This file contains the public API of the IXP400 Feature Control + * component. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ +/* ------------------------------------------------------ + Doxygen group definitions + ------------------------------------------------------ */ +/** + * @defgroup IxFeatureCtrlAPI IXP400 Feature Control (IxFeatureCtrl) API + * + * @brief The Public API for the IXP400 Feature Control. + * + * @{ + */ + +#ifndef IXFEATURECTRL_H +#define IXFEATURECTRL_H + +/* + * User defined include files + */ +#include "IxOsal.h" + +/* + * #defines and macros + */ + +/************************************************************* + * The following are IxFeatureCtrlComponentCheck return values. + ************************************************************/ + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_COMPONENT_DISABLED + * + * @brief Hardware Component is disabled/unavailable. + * Return status by ixFeatureCtrlComponentCheck() + */ +#define IX_FEATURE_CTRL_COMPONENT_DISABLED 0 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_COMPONENT_ENABLED + * + * @brief Hardware Component is available. + * Return status by ixFeatureCtrlComponentCheck() + */ +#define IX_FEATURE_CTRL_COMPONENT_ENABLED 1 + +/*********************************************************************************** + * Product ID in XScale CP15 - Register 0 + * - It contains information on the maximum XScale Core Frequency and + * Silicon Stepping. + * - XScale Core Frequency Id indicates only the maximum XScale frequency + * achievable and not the running XScale frequency (maybe stepped down). + * - The register is read by using ixFeatureCtrlProductIdRead. + * - Usage example: + * productId = ixFeatureCtrlProductIdRead(); + * if( (productId & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) == + * IX_FEATURE_CTRL_SILICON_TYPE_A0 ) + * if( (productId & IX_FEATURE_CTRL_XSCALE_FREQ_MASK) == + * IX_FEATURE_CTRL_XSCALE_FREQ_533 ) + * + * 31 28 27 24 23 20 19 16 15 12 11 9 8 4 3 0 + * -------------------------------------------------------------------------------- + * | 0x6 | 0x9 | 0x0 | 0x5 | 0x4 | Device ID | XScale Core Freq Id | Si Stepping Id | + * -------------------------------------------------------------------------------- + * + * Maximum Achievable XScale Core Frequency Id : 533MHz - 0x1C + * 400MHz - 0x1D + * 266MHz - 0x1F + * + * THE CORE FREQUENCY ID IS NOT APPLICABLE TO IXP46X <\b> + * + * The above is applicable to IXP42X only. CP15 in IXP46X does not contain any + * Frequency ID. + * + * Si Stepping Id : A - 0x0 + * B - 0x1 + * + * XScale Core freq Id - Device ID [11:9] : IXP42X - 0x0 + * IXP46X - 0x1 + *************************************************************************************/ + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_SILICON_TYPE_A0 + * + * @brief This is the value of A0 Silicon in product ID. + */ +#define IX_FEATURE_CTRL_SILICON_TYPE_A0 0 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_SILICON_TYPE_B0 + * + * @brief This is the value of B0 Silicon in product ID. + */ +#define IX_FEATURE_CTRL_SILICON_TYPE_B0 1 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_SILICON_STEPPING_MASK + * + * @brief This is the mask of silicon stepping in product ID. + */ +#define IX_FEATURE_CTRL_SILICON_STEPPING_MASK 0xF + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_DEVICE_TYPE_MASK + * + * @brief This is the mask of silicon stepping in product ID. + */ +#define IX_FEATURE_CTRL_DEVICE_TYPE_MASK (0x7) + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET + * + * @brief This is the mask of silicon stepping in product ID. + */ +#define IX_FEATURE_CTRL_DEVICE_TYPE_OFFSET 9 + + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_XSCALE_FREQ_533 + * + * @brief This is the value of 533MHz XScale Core in product ID. + */ +#define IX_FEATURE_CTRL_XSCALE_FREQ_533 ((0x1C)<<4) + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_XSCALE_FREQ_400 + * + * @brief This is the value of 400MHz XScale Core in product ID. + */ +#define IX_FEATURE_CTRL_XSCALE_FREQ_400 ((0x1D)<<4) + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_XSCALE_FREQ_266 + * + * @brief This is the value of 266MHz XScale Core in product ID. + */ +#define IX_FEATURE_CTRL_XSCALE_FREQ_266 ((0x1F)<<4) + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURE_CTRL_XSCALE_FREQ_MASK + * + * @brief This is the mask of XScale Core in product ID. + */ +#define IX_FEATURE_CTRL_XSCALE_FREQ_MASK ((0xFF)<<4) + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_UTOPIA_32PHY + * + * @brief Maximum UTOPIA PHY available is 32. + * + */ +#define IX_FEATURECTRL_REG_UTOPIA_32PHY 0x0 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_UTOPIA_16PHY + * + * @brief Maximum UTOPIA PHY available is 16. + * + */ +#define IX_FEATURECTRL_REG_UTOPIA_16PHY 0x1 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_UTOPIA_8PHY + * + * @brief Maximum UTOPIA PHY available to is 8. + * + */ +#define IX_FEATURECTRL_REG_UTOPIA_8PHY 0x2 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_UTOPIA_4PHY + * + * @brief Maximum UTOPIA PHY available to is 4. + * + */ +#define IX_FEATURECTRL_REG_UTOPIA_4PHY 0x3 + +#ifdef __ixp46X + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_XSCALE_533FREQ + * + * @brief Maximum frequency available to IXP46x is 533 MHz. + * + */ +#define IX_FEATURECTRL_REG_XSCALE_533FREQ 0x0 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_XSCALE_667FREQ + * + * @brief Maximum frequency available to IXP46x is 667 MHz. + * + */ +#define IX_FEATURECTRL_REG_XSCALE_667FREQ 0x1 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_XSCALE_400FREQ + * + * @brief Maximum frequency available to IXP46x is 400 MHz. + * + */ +#define IX_FEATURECTRL_REG_XSCALE_400FREQ 0x2 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_REG_XSCALE_266FREQ + * + * @brief Maximum frequency available to IXP46x is 266 MHz. + * + */ +#define IX_FEATURECTRL_REG_XSCALE_266FREQ 0x3 + +#endif /* __ixp46X */ + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE + * + * @brief Component selected is not available for device + * + */ +#define IX_FEATURECTRL_COMPONENT_NOT_AVAILABLE 0x0000 + +/** + * @ingroup IxFeatureCtrlAPI + * + * @def IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE + * + * @brief Component selected is not available for device + * + */ +#define IX_FEATURECTRL_COMPONENT_ALWAYS_AVAILABLE 0xffff + +/** + * @defgroup IxFeatureCtrlSwConfig Software Configuration for Access Component + * + * @ingroup IxFeatureCtrlAPI + * + * @brief This section describes software configuration in access component. The + * configuration can be changed at run-time. ixFeatureCtrlSwConfigurationCheck( ) + * will be used across applicable access component to check the configuration. + * ixFeatureCtrlSwConfigurationWrite( ) is used to write the software configuration. + * + * @note All software configurations are default to be enabled. + * + * @{ + */ +/** + * @ingroup IxFeatureCtrlSwConfig + * + * @def IX_FEATURE_CTRL_SWCONFIG_DISABLED + * + * @brief Software configuration is disabled. + * + */ +#define IX_FEATURE_CTRL_SWCONFIG_DISABLED 0 + +/** + * @ingroup IxFeatureCtrlSwConfig + * + * @def IX_FEATURE_CTRL_SWCONFIG_ENABLED + * + * @brief Software configuration is enabled. + * + */ +#define IX_FEATURE_CTRL_SWCONFIG_ENABLED 1 + +/** + * Section for enums + **/ + +/** + * @ingroup IxFeatureCtrlBuildDevice + * + * @enum IxFeatureCtrlBuildDevice + * + * @brief Indicates software build type. + * + * Default build type is IXP42X + * + */ +typedef enum +{ + IX_FEATURE_CTRL_SW_BUILD_IXP42X = 0, /** + * - if(IX_FEATURE_CTRL_COMPONENT_DISABLED != + * ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0))
+ * - if(IX_FEATURE_CTRL_COMPONENT_ENABLED == + * ixFeatureCtrlComponentCheck(IX_FEATURECTRL_PCI))
+ * + * This function is typically called during component initialization time. + * + * @param componentType @ref IxFeatureCtrlComponentType [in] - the type of a component as + * defined above as IX_FEATURECTRL_XXX (Exp: IX_FEATURECTRL_PCI, IX_FEATURECTRL_ETH0) + + * + * @return + * - IX_FEATURE_CTRL_COMPONENT_ENABLED if component is available + * - IX_FEATURE_CTRL_COMPONENT_DISABLED if component is unavailable + */ +PUBLIC IX_STATUS +ixFeatureCtrlComponentCheck (IxFeatureCtrlComponentType componentType); + +/** + * @ingroup IxFeatureCtrlAPI + * + * @fn IxFeatureCtrlProductId ixFeatureCtrlProductIdRead (void) + * + * @brief This function will return IXP400 product ID i.e. CP15, + * Register 0. + * + * @return + * - IxFeatureCtrlProductId - the value of product ID. + * + */ +PUBLIC IxFeatureCtrlProductId +ixFeatureCtrlProductIdRead (void) ; + +/** + * @ingroup IxFeatureCtrlAPI + * + * @fn IX_STATUS ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType) + * + * @brief This function checks whether the specified software configuration is + * enabled or disabled. + * + * Usage Example:
+ * - if(IX_FEATURE_CTRL_SWCONFIG_DISABLED != + * ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
+ * - if(IX_FEATURE_CTRL_SWCONFIG_ENABLED == + * ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
+ * + * This function is typically called during access component initialization time. + * + * @param swConfigType @ref IxFeatureCtrlSwConfig [in] - the type of a software configuration + * defined in IxFeatureCtrlSwConfig enumeration. + * + * @return + * - IX_FEATURE_CTRL_SWCONFIG_ENABLED if software configuration is enabled. + * - IX_FEATURE_CTRL_SWCONFIG_DISABLED if software configuration is disabled. + */ +PUBLIC IX_STATUS +ixFeatureCtrlSwConfigurationCheck (IxFeatureCtrlSwConfig swConfigType); + +/** + * @ingroup IxFeatureCtrlAPI + * + * @fn void ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled) + * + * @brief This function enable/disable the specified software configuration. + * + * Usage Example:
+ * - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, TRUE) is used + * to enable Ethernet Learning Feature
+ * - ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, FALSE) is used + * to disable Ethernet Learning Feature
+ * + * @param swConfigType IxFeatureCtrlSwConfig [in] - the type of a software configuration + * defined in IxFeatureCtrlSwConfig enumeration. + * @param enabled BOOL [in] - To enable(TRUE) / disable (FALSE) the specified software + * configuration. + * + * @return none + * + */ +PUBLIC void +ixFeatureCtrlSwConfigurationWrite (IxFeatureCtrlSwConfig swConfigType, BOOL enabled); + +/** + * @ingroup IxFeatureCtrlAPI + * + * @fn void ixFeatureCtrlIxp400SwVersionShow (void) + * + * @brief This function shows the current software release information for IXP400 + * + * @return none + * + */ +PUBLIC void +ixFeatureCtrlIxp400SwVersionShow (void); + +#endif /* IXFEATURECTRL_H */ + +/** + * @} defgroup IxFeatureCtrlAPI + */ diff --git a/drivers/net/npe/include/IxHssAcc.h b/drivers/net/npe/include/IxHssAcc.h new file mode 100644 index 0000000..07bb119 --- /dev/null +++ b/drivers/net/npe/include/IxHssAcc.h @@ -0,0 +1,1316 @@ +/** + * @file IxHssAcc.h + * + * @date 07-DEC-2001 + * + * @brief This file contains the public API of the IXP400 HSS Access + * component + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/* ------------------------------------------------------ + Doxygen group definitions + ------------------------------------------------------ */ +/** + * @defgroup IxHssAccAPI IXP400 HSS Access (IxHssAcc) API + * + * @brief The public API for the IXP400 HssAccess component + * + * IxHssAcc is the access layer to the HSS packetised and channelised + * services + * + * Design Notes
+ *
    + *
  • When a packet-pipe is configured for 56Kbps RAW mode, byte alignment of + * the transmitted data is not preserved. All raw data that is transmitted + * will be received in proper order by the receiver, but the first bit of + * the packet may be seen at any offset within a byte; all subsequent bytes + * will have the same offset for the duration of the packet. The same offset + * also applies to all subsequent packets received on the packet-pipe too. + * (Similar results will occur for data received from remote end.) While + * this behavior will also occur for 56Kbps HDLC mode, the HDLC + * encoding/decoding will preserve the original byte alignment at the + * receiver end. + *
+ * + * 56Kbps Packetised Service Bandwidth Limitation
+ *
    + *
  • IxHssAcc supports 56Kbps packetised service at a maximum aggregate rate + * for all HSS ports/HDLC channels of 12.288Mbps[1] in each direction, i.e. + * it supports 56Kbps packetised service on up to 8 T1 trunks. It does + * not support 56Kbps packetised service on 8 E1 trunks (i.e. 4 trunks per + * HSS port) unless those trunks are running 'fractional E1' with maximum + * aggregate rate of 12.288 Mbps in each direction.
    + * [1] 12.288Mbps = 1.536Mbp * 8 T1 + *
+ * @{ */ + +#ifndef IXHSSACC_H +#define IXHSSACC_H + +#include "IxOsal.h" + +/* + * #defines for function return types, etc. + */ + +/** + * @def IX_HSSACC_TSLOTS_PER_HSS_PORT + * + * @brief The max number of TDM timeslots supported per HSS port - 4E1's = + * 32x4 = 128 + */ +#define IX_HSSACC_TSLOTS_PER_HSS_PORT 128 + +/* ----------------------------------------------------------- + The following are HssAccess return values returned through + service interfaces. The globally defined IX_SUCCESS (0) and + IX_FAIL (1) in IxOsalTypes.h are also used. + ----------------------------------------------------------- */ +/** + * @def IX_HSSACC_PARAM_ERR + * + * @brief HssAccess function return value for a parameter error + */ +#define IX_HSSACC_PARAM_ERR 2 + +/** + * @def IX_HSSACC_RESOURCE_ERR + * + * @brief HssAccess function return value for a resource error + */ +#define IX_HSSACC_RESOURCE_ERR 3 + +/** + * @def IX_HSSACC_PKT_DISCONNECTING + * + * @brief Indicates that a disconnect call is progressing and will + * disconnect soon + */ +#define IX_HSSACC_PKT_DISCONNECTING 4 + +/** + * @def IX_HSSACC_Q_WRITE_OVERFLOW + * + * @brief Indicates that an attempt to Tx or to replenish an + * RxFree Q failed due to Q overflow. + */ +#define IX_HSSACC_Q_WRITE_OVERFLOW 5 + +/* ------------------------------------------------------------------- + The following errors are HSS/NPE errors returned on error retrieval + ------------------------------------------------------------------- */ +/** + * @def IX_HSSACC_NO_ERROR + * + * @brief HSS port no error present + */ +#define IX_HSSACC_NO_ERROR 0 + +/** + * @def IX_HSSACC_TX_FRM_SYNC_ERR + * + * @brief HSS port TX Frame Sync error + */ +#define IX_HSSACC_TX_FRM_SYNC_ERR 1 + +/** + * @def IX_HSSACC_TX_OVER_RUN_ERR + * + * @brief HSS port TX over-run error + */ +#define IX_HSSACC_TX_OVER_RUN_ERR 2 + +/** + * @def IX_HSSACC_CHANNELISED_SW_TX_ERR + * + * @brief NPE software error in channelised TX + */ +#define IX_HSSACC_CHANNELISED_SW_TX_ERR 3 + +/** + * @def IX_HSSACC_PACKETISED_SW_TX_ERR + * + * @brief NPE software error in packetised TX + */ +#define IX_HSSACC_PACKETISED_SW_TX_ERR 4 + +/** + * @def IX_HSSACC_RX_FRM_SYNC_ERR + * + * @brief HSS port RX Frame Sync error + */ +#define IX_HSSACC_RX_FRM_SYNC_ERR 5 + +/** + * @def IX_HSSACC_RX_OVER_RUN_ERR + * + * @brief HSS port RX over-run error + */ +#define IX_HSSACC_RX_OVER_RUN_ERR 6 + +/** + * @def IX_HSSACC_CHANNELISED_SW_RX_ERR + * + * @brief NPE software error in channelised RX + */ +#define IX_HSSACC_CHANNELISED_SW_RX_ERR 7 + +/** + * @def IX_HSSACC_PACKETISED_SW_RX_ERR + * + * @brief NPE software error in packetised TX + */ +#define IX_HSSACC_PACKETISED_SW_RX_ERR 8 + +/* ----------------------------------- + Packetised service specific defines + ----------------------------------- */ + +/** + * @def IX_HSSACC_PKT_MIN_RX_MBUF_SIZE + * + * @brief Minimum size of the Rx mbuf in bytes which the client must supply + * to the component. + */ +#define IX_HSSACC_PKT_MIN_RX_MBUF_SIZE 64 + +/* -------------------------------------------------------------------- + Enumerated Types - these enumerated values may be used in setting up + the contents of hardware registers + -------------------------------------------------------------------- */ +/** + * @enum IxHssAccHssPort + * @brief The HSS port ID - There are two identical ports (0-1). + * + */ +typedef enum +{ + IX_HSSACC_HSS_PORT_0, /**< HSS Port 0 */ + IX_HSSACC_HSS_PORT_1, /**< HSS Port 1 */ + IX_HSSACC_HSS_PORT_MAX /**< Delimiter for error checks */ +} IxHssAccHssPort; + +/** + * @enum IxHssAccHdlcPort + * @brief The HDLC port ID - There are four identical HDLC ports (0-3) per + * HSS port and they correspond to the 4 E1/T1 trunks. + * + */ +typedef enum +{ + IX_HSSACC_HDLC_PORT_0, /**< HDLC Port 0 */ + IX_HSSACC_HDLC_PORT_1, /**< HDLC Port 1 */ + IX_HSSACC_HDLC_PORT_2, /**< HDLC Port 2 */ + IX_HSSACC_HDLC_PORT_3, /**< HDLC Port 3 */ + IX_HSSACC_HDLC_PORT_MAX /**< Delimiter for error checks */ +} IxHssAccHdlcPort; + +/** + * @enum IxHssAccTdmSlotUsage + * @brief The HSS TDM stream timeslot assignment types + * + */ +typedef enum +{ + IX_HSSACC_TDMMAP_UNASSIGNED, /**< Unassigned */ + IX_HSSACC_TDMMAP_HDLC, /**< HDLC - packetised */ + IX_HSSACC_TDMMAP_VOICE56K, /**< Voice56K - channelised */ + IX_HSSACC_TDMMAP_VOICE64K, /**< Voice64K - channelised */ + IX_HSSACC_TDMMAP_MAX /**< Delimiter for error checks */ +} IxHssAccTdmSlotUsage; + +/** + * @enum IxHssAccFrmSyncType + * @brief The HSS frame sync pulse type + * + */ +typedef enum +{ + IX_HSSACC_FRM_SYNC_ACTIVE_LOW, /**< Frame sync is sampled low */ + IX_HSSACC_FRM_SYNC_ACTIVE_HIGH, /**< sampled high */ + IX_HSSACC_FRM_SYNC_FALLINGEDGE, /**< sampled on a falling edge */ + IX_HSSACC_FRM_SYNC_RISINGEDGE, /**< sampled on a rising edge */ + IX_HSSACC_FRM_SYNC_TYPE_MAX /**< Delimiter for error checks */ +} IxHssAccFrmSyncType; + +/** + * @enum IxHssAccFrmSyncEnable + * @brief The IxHssAccFrmSyncEnable determines how the frame sync pulse is + * used + * */ +typedef enum +{ + IX_HSSACC_FRM_SYNC_INPUT, /**< Frame sync is sampled as an input */ + IX_HSSACC_FRM_SYNC_INVALID_VALUE, /**< 1 is not used */ + IX_HSSACC_FRM_SYNC_OUTPUT_FALLING, /**< Frame sync is an output generated + off a falling clock edge */ + IX_HSSACC_FRM_SYNC_OUTPUT_RISING, /**< Frame sync is an output generated + off a rising clock edge */ + IX_HSSACC_FRM_SYNC_ENABLE_MAX /**< Delimiter for error checks */ +} IxHssAccFrmSyncEnable; + +/** + * @enum IxHssAccClkEdge + * @brief IxHssAccClkEdge is used to determine the clk edge to use for + * framing and data + * + */ +typedef enum +{ + IX_HSSACC_CLK_EDGE_FALLING, /**< Clock sampled off a falling edge */ + IX_HSSACC_CLK_EDGE_RISING, /**< Clock sampled off a rising edge */ + IX_HSSACC_CLK_EDGE_MAX /**< Delimiter for error checks */ +} IxHssAccClkEdge; + +/** + * @enum IxHssAccClkDir + * @brief The HSS clock direction + * + */ +typedef enum +{ + IX_HSSACC_SYNC_CLK_DIR_INPUT, /**< Clock is an input */ + IX_HSSACC_SYNC_CLK_DIR_OUTPUT, /**< Clock is an output */ + IX_HSSACC_SYNC_CLK_DIR_MAX /**< Delimiter for error checks */ +} IxHssAccClkDir; + +/** + * @enum IxHssAccFrmPulseUsage + * @brief The HSS frame pulse usage + * + */ +typedef enum +{ + IX_HSSACC_FRM_PULSE_ENABLED, /**< Generate/Receive frame pulses */ + IX_HSSACC_FRM_PULSE_DISABLED, /**< Disregard frame pulses */ + IX_HSSACC_FRM_PULSE_MAX /**< Delimiter for error checks */ +} IxHssAccFrmPulseUsage; + +/** + * @enum IxHssAccDataRate + * @brief The HSS Data rate in relation to the clock + * + */ +typedef enum +{ + IX_HSSACC_CLK_RATE, /**< Data rate is at the configured clk speed */ + IX_HSSACC_HALF_CLK_RATE, /**< Data rate is half the configured clk speed */ + IX_HSSACC_DATA_RATE_MAX /**< Delimiter for error checks */ +} IxHssAccDataRate; + +/** + * @enum IxHssAccDataPolarity + * @brief The HSS data polarity type + * + */ +typedef enum +{ + IX_HSSACC_DATA_POLARITY_SAME, /**< Don't invert data between NPE and + HSS FIFOs */ + IX_HSSACC_DATA_POLARITY_INVERT, /**< Invert data between NPE and HSS + FIFOs */ + IX_HSSACC_DATA_POLARITY_MAX /**< Delimiter for error checks */ +} IxHssAccDataPolarity; + +/** + * @enum IxHssAccBitEndian + * @brief HSS Data endianness + * + */ +typedef enum +{ + IX_HSSACC_LSB_ENDIAN, /**< TX/RX Least Significant Bit first */ + IX_HSSACC_MSB_ENDIAN, /**< TX/RX Most Significant Bit first */ + IX_HSSACC_ENDIAN_MAX /**< Delimiter for the purposes of error checks */ +} IxHssAccBitEndian; + + +/** + * @enum IxHssAccDrainMode + * @brief Tx pin open drain mode + * + */ +typedef enum +{ + IX_HSSACC_TX_PINS_NORMAL, /**< Normal mode */ + IX_HSSACC_TX_PINS_OPEN_DRAIN, /**< Open Drain mode */ + IX_HSSACC_TX_PINS_MAX /**< Delimiter for error checks */ +} IxHssAccDrainMode; + +/** + * @enum IxHssAccSOFType + * @brief HSS start of frame types + * + */ +typedef enum +{ + IX_HSSACC_SOF_FBIT, /**< Framing bit transmitted and expected on rx */ + IX_HSSACC_SOF_DATA, /**< Framing bit not transmitted nor expected on rx */ + IX_HSSACC_SOF_MAX /**< Delimiter for error checks */ +} IxHssAccSOFType; + +/** + * @enum IxHssAccDataEnable + * @brief IxHssAccDataEnable is used to determine whether or not to drive + * the data pins + * + */ +typedef enum +{ + IX_HSSACC_DE_TRI_STATE, /**< TRI-State the data pins */ + IX_HSSACC_DE_DATA, /**< Push data out the data pins */ + IX_HSSACC_DE_MAX /**< Delimiter for error checks */ +} IxHssAccDataEnable; + +/** + * @enum IxHssAccTxSigType + * @brief IxHssAccTxSigType is used to determine how to drive the data pins + * + */ +typedef enum +{ + IX_HSSACC_TXSIG_LOW, /**< Drive the data pins low */ + IX_HSSACC_TXSIG_HIGH, /**< Drive the data pins high */ + IX_HSSACC_TXSIG_HIGH_IMP, /**< Drive the data pins with high impedance */ + IX_HSSACC_TXSIG_MAX /**< Delimiter for error checks */ +} IxHssAccTxSigType; + +/** + * @enum IxHssAccFbType + * @brief IxHssAccFbType determines how to drive the Fbit + * + * @warning This will only be used for T1 @ 1.544MHz + * + */ +typedef enum +{ + IX_HSSACC_FB_FIFO, /**< Fbit is dictated in FIFO */ + IX_HSSACC_FB_HIGH_IMP, /**< Fbit is high impedance */ + IX_HSSACC_FB_MAX /**< Delimiter for error checks */ +} IxHssAccFbType; + +/** + * @enum IxHssAcc56kEndianness + * @brief 56k data endianness when using the 56k type + * + */ +typedef enum +{ + IX_HSSACC_56KE_BIT_7_UNUSED, /**< High bit is unused */ + IX_HSSACC_56KE_BIT_0_UNUSED, /**< Low bit is unused */ + IX_HSSACC_56KE_MAX /**< Delimiter for error checks */ +} IxHssAcc56kEndianness; + +/** + * @enum IxHssAcc56kSel + * @brief 56k data transmission type when using the 56k type + * + */ +typedef enum +{ + IX_HSSACC_56KS_32_8_DATA, /**< 32/8 bit data */ + IX_HSSACC_56KS_56K_DATA, /**< 56K data */ + IX_HSSACC_56KS_MAX /**< Delimiter for error checks */ +} IxHssAcc56kSel; + + +/** + * @enum IxHssAccClkSpeed + * @brief IxHssAccClkSpeed represents the HSS clock speeds available + * + */ +typedef enum +{ + IX_HSSACC_CLK_SPEED_512KHZ, /**< 512KHz */ + IX_HSSACC_CLK_SPEED_1536KHZ, /**< 1.536MHz */ + IX_HSSACC_CLK_SPEED_1544KHZ, /**< 1.544MHz */ + IX_HSSACC_CLK_SPEED_2048KHZ, /**< 2.048MHz */ + IX_HSSACC_CLK_SPEED_4096KHZ, /**< 4.096MHz */ + IX_HSSACC_CLK_SPEED_8192KHZ, /**< 8.192MHz */ + IX_HSSACC_CLK_SPEED_MAX /**< Delimiter for error checking */ +} IxHssAccClkSpeed; + +/** + * @enum IxHssAccPktStatus + * @brief Indicates the status of packets passed to the client + * + */ +typedef enum +{ + IX_HSSACC_PKT_OK, /**< Error free.*/ + IX_HSSACC_STOP_SHUTDOWN_ERROR, /**< Errored due to stop or shutdown + occurrance.*/ + IX_HSSACC_HDLC_ALN_ERROR, /**< HDLC alignment error */ + IX_HSSACC_HDLC_FCS_ERROR, /**< HDLC Frame Check Sum error.*/ + IX_HSSACC_RXFREE_Q_EMPTY_ERROR, /**< RxFree Q became empty + while receiving this packet.*/ + IX_HSSACC_HDLC_MAX_FRAME_SIZE_EXCEEDED, /**< HDLC frame size + received is greater than + max specified at connect.*/ + IX_HSSACC_HDLC_ABORT_ERROR, /**< HDLC frame received is invalid due to an + abort sequence received.*/ + IX_HSSACC_DISCONNECT_IN_PROGRESS /**< Packet returned + because a disconnect is in progress */ +} IxHssAccPktStatus; + + +/** + * @enum IxHssAccPktCrcType + * @brief HDLC CRC type + * + */ +typedef enum +{ + IX_HSSACC_PKT_16_BIT_CRC = 16, /**< 16 bit CRC is being used */ + IX_HSSACC_PKT_32_BIT_CRC = 32 /**< 32 bit CRC is being used */ +} IxHssAccPktCrcType; + +/** + * @enum IxHssAccPktHdlcIdleType + * @brief HDLC idle transmission type + * + */ +typedef enum +{ + IX_HSSACC_HDLC_IDLE_ONES, /**< idle tx/rx will be a succession of ones */ + IX_HSSACC_HDLC_IDLE_FLAGS /**< idle tx/rx will be repeated flags */ +} IxHssAccPktHdlcIdleType; + +/** + * @brief Structure containing HSS port configuration parameters + * + * Note: All of these are used for TX. Only some are specific to RX. + * + */ +typedef struct +{ + IxHssAccFrmSyncType frmSyncType; /**< frame sync pulse type (tx/rx) */ + IxHssAccFrmSyncEnable frmSyncIO; /**< how the frame sync pulse is + used (tx/rx) */ + IxHssAccClkEdge frmSyncClkEdge; /**< frame sync clock edge type + (tx/rx) */ + IxHssAccClkEdge dataClkEdge; /**< data clock edge type (tx/rx) */ + IxHssAccClkDir clkDirection; /**< clock direction (tx/rx) */ + IxHssAccFrmPulseUsage frmPulseUsage; /**< whether to use the frame sync + pulse or not (tx/rx) */ + IxHssAccDataRate dataRate; /**< data rate in relation to the + clock (tx/rx) */ + IxHssAccDataPolarity dataPolarity; /**< data polarity type (tx/rx) */ + IxHssAccBitEndian dataEndianness; /**< data endianness (tx/rx) */ + IxHssAccDrainMode drainMode; /**< tx pin open drain mode (tx) */ + IxHssAccSOFType fBitUsage; /**< start of frame types (tx/rx) */ + IxHssAccDataEnable dataEnable; /**< whether or not to drive the data + pins (tx) */ + IxHssAccTxSigType voice56kType; /**< how to drive the data pins for + voice56k type (tx) */ + IxHssAccTxSigType unassignedType; /**< how to drive the data pins for + unassigned type (tx) */ + IxHssAccFbType fBitType; /**< how to drive the Fbit (tx) */ + IxHssAcc56kEndianness voice56kEndian;/**< 56k data endianness when using + the 56k type (tx) */ + IxHssAcc56kSel voice56kSel; /**< 56k data transmission type when + using the 56k type (tx) */ + unsigned frmOffset; /**< frame pulse offset in bits wrt + the first timeslot (0-1023) (tx/rx) */ + unsigned maxFrmSize; /**< frame size in bits (1-1024) + (tx/rx) */ +} IxHssAccPortConfig; + +/** + * @brief Structure containing HSS configuration parameters + * + */ +typedef struct +{ + IxHssAccPortConfig txPortConfig; /**< HSS tx port configuration */ + IxHssAccPortConfig rxPortConfig; /**< HSS rx port configuration */ + unsigned numChannelised; /**< The number of channelised + timeslots (0-32) */ + unsigned hssPktChannelCount; /**< The number of packetised + clients (0 - 4) */ + UINT8 channelisedIdlePattern; /**< The byte to be transmitted on + channelised service when there + is no client data to tx */ + BOOL loopback; /**< The HSS loopback state */ + unsigned packetizedIdlePattern; /**< The data to be transmitted on + packetised service when there is + no client data to tx */ + IxHssAccClkSpeed clkSpeed; /**< The HSS clock speed */ +} IxHssAccConfigParams; + +/** + * @brief This structure contains 56Kbps, HDLC-mode configuration parameters + * + */ +typedef struct +{ + BOOL hdlc56kMode; /**< 56kbps(TRUE)/64kbps(FALSE) HDLC */ + IxHssAcc56kEndianness hdlc56kEndian; /**< 56kbps data endianness + - ignored if hdlc56kMode is FALSE*/ + BOOL hdlc56kUnusedBitPolarity0; /**< The polarity '0'(TRUE)/'1'(FALSE) of the unused + bit while in 56kbps mode + - ignored if hdlc56kMode is FALSE*/ +} IxHssAccHdlcMode; + +/** + * @brief This structure contains information required by the NPE to + * configure the HDLC co-processor + * + */ +typedef struct +{ + IxHssAccPktHdlcIdleType hdlcIdleType; /**< What to transmit when a HDLC port is idle */ + IxHssAccBitEndian dataEndian; /**< The HDLC data endianness */ + IxHssAccPktCrcType crcType; /**< The CRC type to be used for this HDLC port */ +} IxHssAccPktHdlcFraming; + +/** + * @typedef UINT32 IxHssAccPktUserId + * + * @brief The client supplied value which will be supplied as a parameter + * with a given callback. + * + * This value will be passed into the ixHssAccPktPortConnect function once each + * with given callbacks. This value will then be passed back to the client + * as one of the parameters to each of these callbacks, + * when these callbacks are called. + */ +typedef UINT32 IxHssAccPktUserId; + + +/** + * @typedef IxHssAccLastErrorCallback + * @brief Prototype of the clients function to accept notification of the + * last error + * + * This function is registered through the config. The client will initiate + * the last error retrieval. The HssAccess component will send a message to + * the NPE through the NPE Message Handler. When a response to the read is + * received, the NPE Message Handler will callback the HssAccess component + * which will execute this function in the same IxNpeMh context. The client + * will be passed the last error and the related service port (packetised + * 0-3, channelised 0) + * + * @param lastHssError unsigned [in] - The last Hss error registered that + * has been registered. + * @param servicePort unsigned [in] - This is the service port number. + * (packetised 0-3, channelised 0) + * + * @return void + */ +typedef void (*IxHssAccLastErrorCallback) (unsigned lastHssError, + unsigned servicePort); + +/** + * @typedef IxHssAccPktRxCallback + * @brief Prototype of the clients function to accept notification of + * packetised rx + * + * This function is registered through the ixHssAccPktPortConnect. hssPktAcc will pass + * received data in the form of mbufs to the client. The mbuf passed back + * to the client could contain a chain of buffers, depending on the packet + * size received. + * + * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contains the + * payload received. + * @param numHssErrs unsigned [in] - This is the number of hssErrors + * the Npe has received + * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the + * mbuf that has been received. + * @param rxUserId @ref IxHssAccPktUserId [in] - This is the client supplied value + * passed in at ixHssAccPktPortConnect time which is now returned to the client. + * + * @return void + */ +typedef void (*IxHssAccPktRxCallback) (IX_OSAL_MBUF *buffer, + unsigned numHssErrs, + IxHssAccPktStatus pktStatus, + IxHssAccPktUserId rxUserId); + +/** + * @typedef IxHssAccPktRxFreeLowCallback + * @brief Prototype of the clients function to accept notification of + * requirement of more Rx Free buffers + * + * The client can choose to register a callback of this type when + * calling a connecting. This function is registered through the ixHssAccPktPortConnect. + * If defined, the access layer will provide the trigger for + * this callback. The callback will be responsible for supplying mbufs to + * the access layer for use on the receive path from the HSS using + * ixHssPktAccFreeBufReplenish. + * + * @return void + */ +typedef void (*IxHssAccPktRxFreeLowCallback) (IxHssAccPktUserId rxFreeLowUserId); + +/** + * @typedef IxHssAccPktTxDoneCallback + * @brief Prototype of the clients function to accept notification of + * completion with Tx buffers + * + * This function is registered through the ixHssAccPktPortConnect. It enables + * the hssPktAcc to pass buffers back to the client + * when transmission is complete. + * + * @param *buffer @ref IX_OSAL_MBUF [in] - This is the mbuf which contained + * the payload that was for Tx. + * @param numHssErrs unsigned [in] - This is the number of hssErrors + * the Npe has received + * @param pktStatus @ref IxHssAccPktStatus [in] - This is the status of the + * mbuf that has been transmitted. + * @param txDoneUserId @ref IxHssAccPktUserId [in] - This is the client supplied value + * passed in at ixHssAccPktPortConnect time which is now returned to the client. + * + * @return void + */ +typedef void (*IxHssAccPktTxDoneCallback) (IX_OSAL_MBUF *buffer, + unsigned numHssErrs, + IxHssAccPktStatus pktStatus, + IxHssAccPktUserId txDoneUserId); + +/** + * @typedef IxHssAccChanRxCallback + * @brief Prototype of the clients function to accept notification of + * channelised rx + * + * This callback, if defined by the client in the connect, will get called + * in the context of an IRQ. The IRQ will be triggered when the hssSyncQMQ + * is not empty. The queued entry will be dequeued and this function will + * be executed. + * + * @param hssPortId @ref IxHssAccHssPort - The HSS port Id. There are two + * identical ports (0-1). + * @param txOffset unsigned [in] - an offset indicating from where within + * the txPtrList the NPE is currently transmitting from. + * @param rxOffset unsigned [in] - an offset indicating where within the + * receive buffers the NPE has just written the received data to. + * @param numHssErrs unsigned [in] - This is the number of hssErrors + * the Npe has received + * + * @return void + */ +typedef void (*IxHssAccChanRxCallback) (IxHssAccHssPort hssPortId, + unsigned rxOffset, + unsigned txOffset, + unsigned numHssErrs); + +/* + * Prototypes for interface functions. + */ + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccPortInit (IxHssAccHssPort hssPortId, + IxHssAccConfigParams *configParams, + IxHssAccTdmSlotUsage *tdmMap, + IxHssAccLastErrorCallback lastHssErrorCallback) + * + * @brief Initialise a HSS port. No channelised or packetised connections + * should exist in the HssAccess layer while this interface is being called. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param *configParams @ref IxHssAccConfigParams [in] - A pointer to the HSS + * configuration structure + * @param *tdmMap @ref IxHssAccTdmSlotUsage [in] - A pointer to an array of size + * IX_HSSACC_TSLOTS_PER_HSS_PORT, defining the slot usage over the HSS port + * @param lastHssErrorCallback @ref IxHssAccLastErrorCallback [in] - Client + * callback to report last error + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccPortInit (IxHssAccHssPort hssPortId, + IxHssAccConfigParams *configParams, + IxHssAccTdmSlotUsage *tdmMap, + IxHssAccLastErrorCallback lastHssErrorCallback); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccLastErrorRetrievalInitiate ( + IxHssAccHssPort hssPortId) + * + * @brief Initiate the retrieval of the last HSS error. The HSS port + * should be configured before attempting to call this interface. + * + * @param hssPortId @ref IxHssAccHssPort [in] - the HSS port ID + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccLastErrorRetrievalInitiate (IxHssAccHssPort hssPortId); + + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccInit () + * + * @brief This function is responsible for initialising resources for use + * by the packetised and channelised clients. It should be called after + * HSS NPE image has been downloaded into NPE-A and before any other + * HssAccess interface is called. + * No other HssAccPacketised interface should be called while this interface + * is being processed. + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due + * to a resource error + */ +PUBLIC IX_STATUS +ixHssAccInit (void); + + +/** + * + * @ingroup IxHssAccAPI + * + * @fn ixHssAccPktPortConnect (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + BOOL hdlcFraming, + IxHssAccHdlcMode hdlcMode, + BOOL hdlcBitInvert, + unsigned blockSizeInWords, + UINT32 rawIdleBlockPattern, + IxHssAccPktHdlcFraming hdlcTxFraming, + IxHssAccPktHdlcFraming hdlcRxFraming, + unsigned frmFlagStart, + IxHssAccPktRxCallback rxCallback, + IxHssAccPktUserId rxUserId, + IxHssAccPktRxFreeLowCallback rxFreeLowCallback, + IxHssAccPktUserId rxFreeLowUserId, + IxHssAccPktTxDoneCallback txDoneCallback, + IxHssAccPktUserId txDoneUserId) + * + * @brief This function is responsible for connecting a client to one of + * the 4 available HDLC ports. The HSS port should be configured before + * attempting a connect. No other HssAccPacketised interface should be + * called while this connect is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port and + * it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 + * @param hdlcFraming BOOL [in] - This value determines whether the service + * will use HDLC data or the debug, raw data type i.e. no HDLC processing + * @param hdlcMode @ref IxHssAccHdlcMode [in] - This structure contains 56Kbps, HDLC-mode + * configuration parameters + * @param hdlcBitInvert BOOL [in] - This value determines whether bit inversion + * will occur between HDLC and HSS co-processors i.e. post-HDLC processing for + * transmit and pre-HDLC processing for receive, for the specified HDLC Termination + * Point + * @param blockSizeInWords unsigned [in] - The max tx/rx block size + * @param rawIdleBlockPattern UINT32 [in] - Tx idle pattern in raw mode + * @param hdlcTxFraming @ref IxHssAccPktHdlcFraming [in] - This structure contains + * the following information required by the NPE to configure the HDLC + * co-processor for TX + * @param hdlcRxFraming @ref IxHssAccPktHdlcFraming [in] - This structure contains + * the following information required by the NPE to configure the HDLC + * co-processor for RX + * @param frmFlagStart unsigned - Number of flags to precede to + * transmitted flags (0-2). + * @param rxCallback @ref IxHssAccPktRxCallback [in] - Pointer to + * the clients packet receive function. + * @param rxUserId @ref IxHssAccPktUserId [in] - The client supplied rx value + * to be passed back as an argument to the supplied rxCallback + * @param rxFreeLowCallback @ref IxHssAccPktRxFreeLowCallback [in] - Pointer to + * the clients Rx free buffer request function. If NULL, assume client will + * trigger independently. + * @param rxFreeLowUserId @ref IxHssAccPktUserId [in] - The client supplied RxFreeLow value + * to be passed back as an argument to the supplied rxFreeLowCallback + * @param txDoneCallback @ref IxHssAccPktTxDoneCallback [in] - Pointer to the + * clients Tx done callback function + * @param txDoneUserId @ref IxHssAccPktUserId [in] - The client supplied txDone value + * to be passed back as an argument to the supplied txDoneCallback + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due + * to a resource error + */ +PUBLIC IX_STATUS +ixHssAccPktPortConnect (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + BOOL hdlcFraming, + IxHssAccHdlcMode hdlcMode, + BOOL hdlcBitInvert, + unsigned blockSizeInWords, + UINT32 rawIdleBlockPattern, + IxHssAccPktHdlcFraming hdlcTxFraming, + IxHssAccPktHdlcFraming hdlcRxFraming, + unsigned frmFlagStart, + IxHssAccPktRxCallback rxCallback, + IxHssAccPktUserId rxUserId, + IxHssAccPktRxFreeLowCallback rxFreeLowCallback, + IxHssAccPktUserId rxFreeLowUserId, + IxHssAccPktTxDoneCallback txDoneCallback, + IxHssAccPktUserId txDoneUserId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccPktPortEnable (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId) + * + * @brief This function is responsible for enabling a packetised service + * for the specified HSS/HDLC port combination. It enables the RX flow. The + * client must have already connected to a packetised service and is responsible + * for ensuring an adequate amount of RX mbufs have been supplied to the access + * component before enabling the packetised service. This function must be called + * on a given port before any call to ixHssAccPktPortTx on the same port. + * No other HssAccPacketised interface should be called while this interface is + * being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to enable the service + * on. + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccPktPortEnable (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId); + +/** + * @fn IX_STATUS ixHssAccPktPortDisable (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId) + * + * @brief This function is responsible for disabling a packetised service + * for the specified HSS/HDLC port combination. It disables the RX flow. + * The client must have already connected to and enabled a packetised service + * for the specified HDLC port. This disable interface can be called before a + * disconnect, but is not required to. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - The port id (0,1,2,3) to disable + * the service on. + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccPktPortDisable (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId) + * + * @brief This function is responsible for disconnecting a client from one + * of the 4 available HDLC ports. It is not required that the Rx Flow + * has been disabled before calling this function. If the RX Flow has not been + * disabled, the disconnect will disable it before proceeding with the + * disconnect. No other HssAccPacketised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port + * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PKT_DISCONNECTING The function has initiated the disconnecting + * procedure but it has not completed yet. + */ +PUBLIC IX_STATUS +ixHssAccPktPortDisconnect (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn BOOL ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId) + * + * @brief This function is called to check if a given HSS/HDLC port + * combination is in a connected state or not. This function may be called + * at any time to determine a ports state. No other HssAccPacketised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port + * to disconnect and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 + * + * @return + * - TRUE The state of this HSS/HDLC port combination is disconnected, + * so if a disconnect was called, it is now completed. + * - FALSE The state of this HSS/HDLC port combination is connected, + * so if a disconnect was called, it is not yet completed. + */ +PUBLIC BOOL +ixHssAccPktPortIsDisconnectComplete (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId); + + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + IX_OSAL_MBUF *buffer) + * + * @brief Function which the client calls at regular intervals to provide + * mbufs to the access component for RX. A connection should exist for + * the specified hssPortId/hdlcPortId combination before attempting to call this + * interface. Also, the connection should not be in a disconnecting state. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port + * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 + * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a free mbuf to filled with payload. + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due + * to a resource error + * - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q + * overflow + */ +PUBLIC IX_STATUS +ixHssAccPktPortRxFreeReplenish (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + IX_OSAL_MBUF *buffer); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccPktPortTx (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + IX_OSAL_MBUF *buffer) + * + * @brief Function which the client calls when it wants to transmit + * packetised data. An enabled connection should exist on the specified + * hssPortId/hdlcPortId combination before attempting to call this interface. + * No other HssAccPacketised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param hdlcPortId @ref IxHssAccHdlcPort [in] - This is the number of the HDLC port + * and it corresponds to the physical E1/T1 trunk i.e. 0, 1, 2, 3 + * @param *buffer @ref IX_OSAL_MBUF [in] - A pointer to a chain of mbufs which the + * client has filled with the payload + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + * - IX_HSSACC_RESOURCE_ERR The function did not execute successfully due + * to a resource error. See note. + * - IX_HSSACC_Q_WRITE_OVERFLOW The function did not succeed due to a Q + * overflow + * + * @note IX_HSSACC_RESOURCE_ERR is returned when a free descriptor cannot be + * obtained to send the chain of mbufs to the NPE. This is a normal scenario. + * HssAcc has a pool of descriptors and this error means that they are currently + * all in use. + * The recommended approach to this is to retry until a descriptor becomes free + * and the packet is successfully transmitted. + * Alternatively, the user could wait until the next IxHssAccPktTxDoneCallback + * callback is triggered, and then retry, as it is this event that causes a + * transmit descriptor to be freed. + */ +PUBLIC IX_STATUS +ixHssAccPktPortTx (IxHssAccHssPort hssPortId, + IxHssAccHdlcPort hdlcPortId, + IX_OSAL_MBUF *buffer); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccChanConnect (IxHssAccHssPort hssPortId, + unsigned bytesPerTSTrigger, + UINT8 *rxCircular, + unsigned numRxBytesPerTS, + UINT32 *txPtrList, + unsigned numTxPtrLists, + unsigned numTxBytesPerBlk, + IxHssAccChanRxCallback rxCallback) + * + * @brief This function allows the client to connect to the Tx/Rx NPE + * Channelised Service. There can only be one client per HSS port. The + * client is responsible for ensuring that the HSS port is configured + * appropriately before its connect request. No other HssAccChannelised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param bytesPerTSTrigger unsigned [in] - The NPE will trigger the access + * component after bytesPerTSTrigger have been received for all trunk + * timeslots. This figure is a multiple of 8 e.g. 8 for 1ms trigger, 16 for + * 2ms trigger. + * @param *rxCircular UINT8 [in] - A pointer to memory allocated by the + * client to be filled by data received. The buffer at this address is part + * of a pool of buffers to be accessed in a circular fashion. This address + * will be written to by the NPE. Therefore, it needs to be a physical address. + * @param numRxBytesPerTS unsigned [in] - The number of bytes allocated per + * timeslot within the receive memory. This figure will depend on the + * latency of the system. It needs to be deep enough for data to be read by + * the client before the NPE re-writes over that memory e.g. if the client + * samples at a rate of 40bytes per timeslot, numRxBytesPerTS may need to + * be 40bytes * 3. This would give the client 3 * 5ms of time before + * received data is over-written. + * @param *txPtrList UINT32 [in] - The address of an area of contiguous + * memory allocated by the client to be populated with pointers to data for + * transmission. Each pointer list contains a pointer per active channel. + * The txPtrs will point to data to be transmitted by the NPE. Therefore, + * they must point to physical addresses. + * @param numTxPtrLists unsigned [in] - The number of pointer lists in + * txPtrList. This figure is dependent on jitter. + * @param numTxBytesPerBlk unsigned [in] - The size of the Tx data, in + * bytes, that each pointer within the PtrList points to. + * @param rxCallback @ref IxHssAccChanRxCallback [in] - A client function + * pointer to be called back to handle the actual tx/rx of channelised + * data. If this is not NULL, an ISR will call this function. If this + * pointer is NULL, it implies that the client will use a polling mechanism + * to detect when the tx and rx of channelised data is to occur. The client + * will use hssChanAccStatus for this. + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ + +PUBLIC IX_STATUS +ixHssAccChanConnect (IxHssAccHssPort hssPortId, + unsigned bytesPerTSTrigger, + UINT8 *rxCircular, + unsigned numRxBytesPerTS, + UINT32 *txPtrList, + unsigned numTxPtrLists, + unsigned numTxBytesPerBlk, + IxHssAccChanRxCallback rxCallback); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccChanPortEnable (IxHssAccHssPort hssPortId) + * + * @brief This function is responsible for enabling a channelised service + * for the specified HSS port. It enables the NPE RX flow. The client must + * have already connected to a channelised service before enabling the + * channelised service. No other HssAccChannelised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccChanPortEnable (IxHssAccHssPort hssPortId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccChanPortDisable (IxHssAccHssPort hssPortId) + * + * @brief This function is responsible for disabling a channelised service + * for the specified HSS port. It disables the NPE RX flow. The client must + * have already connected to and enabled a channelised service for the + * specified HSS port. This disable interface can be called before a + * disconnect, but is not required to. No other HssAccChannelised + * interface should be called while this interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccChanPortDisable (IxHssAccHssPort hssPortId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccChanDisconnect (IxHssAccHssPort hssPortId) + * + * @brief This function allows the client to Disconnect from a channelised + * service. If the NPE RX Flow has not been disabled, the disconnect will + * disable it before proceeding with other disconnect functionality. + * No other HssAccChannelised interface should be called while this + * interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccChanDisconnect (IxHssAccHssPort hssPortId); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn IX_STATUS ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId, + BOOL *dataRecvd, + unsigned *rxOffset, + unsigned *txOffset, + unsigned *numHssErrs) + * + * @brief This function is called by the client to query whether or not + * channelised data has been received. If there is, hssChanAcc will return + * the details in the output parameters. An enabled connection should + * exist on the specified hssPortId before attempting to call this interface. + * No other HssAccChannelised interface should be called while this + * interface is being processed. + * + * @param hssPortId @ref IxHssAccHssPort [in] - The HSS port Id. There are two + * identical ports (0-1). + * @param *dataRecvd BOOL [out] - This BOOL indicates to the client whether + * or not the access component has read any data for the client. If + * FALSE, the other output parameters will not have been written to. + * @param *rxOffset unsigned [out] - An offset to indicate to the client + * where within the receive buffers the NPE has just written the received + * data to. + * @param *txOffset unsigned [out] - An offset to indicate to the client + * from where within the txPtrList the NPE is currently transmitting from + * @param *numHssErrs unsigned [out] - The total number of HSS port errors + * since initial port configuration + * + * + * @return + * - IX_SUCCESS The function executed successfully + * - IX_FAIL The function did not execute successfully + * - IX_HSSACC_PARAM_ERR The function did not execute successfully due to a + * parameter error + */ +PUBLIC IX_STATUS +ixHssAccChanStatusQuery (IxHssAccHssPort hssPortId, + BOOL *dataRecvd, + unsigned *rxOffset, + unsigned *txOffset, + unsigned *numHssErrs); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn void ixHssAccShow (void) + * + * @brief This function will display the current state of the IxHssAcc + * component. The output is sent to stdout. + * + * @return void + */ +PUBLIC void +ixHssAccShow (void); + +/** + * + * @ingroup IxHssAccAPI + * + * @fn void ixHssAccStatsInit (void) + * + * @brief This function will reset the IxHssAcc statistics. + * + * @return void + */ +PUBLIC void +ixHssAccStatsInit (void); + +#endif /* IXHSSACC_H */ + +/** + * @} defgroup IxHssAcc + */ diff --git a/drivers/net/npe/include/IxI2cDrv.h b/drivers/net/npe/include/IxI2cDrv.h new file mode 100644 index 0000000..92c6b24 --- /dev/null +++ b/drivers/net/npe/include/IxI2cDrv.h @@ -0,0 +1,867 @@ +/** + * @file IxI2cDrv.h + * + * @brief Header file for the IXP400 I2C Driver (IxI2cDrv) + * + * @version $Revision: 0.1 $ + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @defgroup IxI2cDrv IXP400 I2C Driver(IxI2cDrv) API + * + * @brief IXP400 I2C Driver Public API + * + * @{ + */ +#ifndef IXI2CDRV_H +#define IXI2CDRV_H + +#ifdef __ixp46X +#include "IxOsal.h" + +/* + * Section for #define + */ + +/** + * @ingroup IxI2cDrv + * @brief The interval of micro/mili seconds the IXP will wait before it polls for + * status from the ixI2cIntrXferStatus; Every 20us is 1 byte @ + * 400Kbps and 4 bytes @ 100Kbps. This is dependent on delay type selected + * through the API ixI2cDrvDelayTypeSelect. + */ +#define IX_I2C_US_POLL_FOR_XFER_STATUS 20 + +/** + * @ingroup IxI2cDrv + * @brief The number of tries that will be attempted to call a callback + * function if the callback does not or is unable to resolve the + * issue it is called to resolve + */ +#define IX_I2C_NUM_OF_TRIES_TO_CALL_CALLBACK_FUNC 10 + + +/** + * @ingroup IxI2cDrv + * @brief Number of tries slave will poll the IDBR Rx full bit before it + * gives up + */ +#define IX_I2C_NUM_TO_POLL_IDBR_RX_FULL 0x100 + +/** + * @ingroup IxI2cDrv + * @brief Number of tries slave will poll the IDBR Tx empty bit before it + * gives up + */ +#define IX_I2C_NUM_TO_POLL_IDBR_TX_EMPTY 0x100 + +/* + * Section for enum + */ + +/** + * @ingroup IxI2cDrv + * + * @enum IxI2cMasterStatus + * + * @brief The master status - transfer complete, bus error or arbitration loss + */ +typedef enum +{ + IX_I2C_MASTER_XFER_COMPLETE = IX_SUCCESS, + IX_I2C_MASTER_XFER_BUS_ERROR, + IX_I2C_MASTER_XFER_ARB_LOSS +} IxI2cMasterStatus; + + +/** + * @ingroup IxI2cDrv + * + * @enum IX_I2C_STATUS + * + * @brief The status that can be returned in a I2C driver initialization + */ +typedef enum +{ + IX_I2C_SUCCESS = IX_SUCCESS, /**< Success status */ + IX_I2C_FAIL, /**< Fail status */ + IX_I2C_NOT_SUPPORTED, /**< hardware does not have dedicated I2C hardware */ + IX_I2C_NULL_POINTER, /**< parameter passed in is NULL */ + IX_I2C_INVALID_SPEED_MODE_ENUM_VALUE, /**< speed mode selected is invalid */ + IX_I2C_INVALID_FLOW_MODE_ENUM_VALUE, /**< flow mode selected is invalid */ + IX_I2C_SLAVE_ADDR_CB_MISSING, /**< slave callback is NULL */ + IX_I2C_GEN_CALL_CB_MISSING, /**< general callback is NULL */ + IX_I2C_INVALID_SLAVE_ADDR, /**< invalid slave address specified */ + IX_I2C_INT_BIND_FAIL, /**< interrupt bind fail */ + IX_I2C_INT_UNBIND_FAIL, /**< interrupt unbind fail */ + IX_I2C_NOT_INIT, /**< I2C is not initialized yet */ + IX_I2C_MASTER_BUS_BUSY, /**< master detected a I2C bus busy */ + IX_I2C_MASTER_ARB_LOSS, /**< master experienced arbitration loss */ + IX_I2C_MASTER_XFER_ERROR, /**< master experienced a transfer error */ + IX_I2C_MASTER_BUS_ERROR, /**< master detected a I2C bus error */ + IX_I2C_MASTER_NO_BUFFER, /**< no buffer provided for master transfer */ + IX_I2C_MASTER_INVALID_XFER_MODE, /**< xfer mode selected is invalid */ + IX_I2C_SLAVE_ADDR_NOT_DETECTED, /**< polled slave addr not detected */ + IX_I2C_GEN_CALL_ADDR_DETECTED, /**< polling detected general call */ + IX_I2C_SLAVE_READ_DETECTED, /**< polling detected slave read request */ + IX_I2C_SLAVE_WRITE_DETECTED, /**< polling detected slave write request */ + IX_I2C_SLAVE_NO_BUFFER, /**< no buffer provided for slave transfers */ + IX_I2C_DATA_SIZE_ZERO, /**< data size transfer is zero - invalid */ + IX_I2C_SLAVE_WRITE_BUFFER_EMPTY, /**< slave buffer is used till empty */ + IX_I2C_SLAVE_WRITE_ERROR, /**< slave write experienced an error */ + IX_I2C_SLAVE_OR_GEN_READ_BUFFER_FULL, /**< slave buffer is filled up */ + IX_I2C_SLAVE_OR_GEN_READ_ERROR /**< slave read experienced an error */ +} IX_I2C_STATUS; + +/** + * @ingroup IxI2cDrv + * + * @enum IxI2cSpeedMode + * + * @brief Type of speed modes supported by the I2C hardware. + */ +typedef enum +{ + IX_I2C_NORMAL_MODE = 0x0, + IX_I2C_FAST_MODE +} IxI2cSpeedMode; + +/** + * @ingroup IxI2cDrv + * + * @enum IxI2cXferMode + * + * @brief Used for indicating it is a repeated start or normal transfer + */ +typedef enum +{ + IX_I2C_NORMAL = 0x0, + IX_I2C_REPEATED_START +} IxI2cXferMode; + +/** + * @ingroup IxI2cDrv + * + * @enum IxI2cFlowMode + * + * @brief Used for indicating it is a poll or interrupt mode + */ +typedef enum +{ + IX_I2C_POLL_MODE = 0x0, + IX_I2C_INTERRUPT_MODE +} IxI2cFlowMode; + +/** + * @ingroup IxI2cDrv + * + * @enum IxI2cDelayMode + * + * @brief Used for selecting looping delay or OS scheduler delay + */ +typedef enum +{ + IX_I2C_LOOP_DELAY = 1, /**< delay in microseconds */ + IX_I2C_SCHED_DELAY /**< delay in miliseconds */ +} IxI2cDelayMode; + +/** + * @ingroup IxI2cDrv + * + * @brief The pointer to the function that will be called when the master + * has completed its receive. The parameter that is passed will + * provide the status of the read (success, arb loss, or bus + * error), the transfer mode (normal or repeated start, the + * buffer pointer and number of bytes transferred. + */ +typedef void (*IxI2cMasterReadCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32); + +/** + * @ingroup IxI2cDrv + * + * @brief The pointer to the function that will be called when the master + * has completed its transmit. The parameter that is passed will + * provide the status of the write (success, arb loss, or buss + * error), the transfer mode (normal or repeated start), the + * buffer pointer and number of bytes transferred. + */ +typedef void (*IxI2cMasterWriteCallbackP)(IxI2cMasterStatus, IxI2cXferMode, char*, UINT32); + +/** + * @ingroup IxI2cDrv + * + * @brief The pointer to the function that will be called when a slave + * address detected in interrupt mode for a read. The parameters + * that is passed will provide the read status, buffer pointer, + * buffer size, and the bytes received. When a start of a read + * is initiated there will be no buffer allocated and this callback + * will be called to request for a buffer. While receiving, if the + * buffer gets filled, this callback will be called to request for + * a new buffer while sending the filled buffer's pointer and size, + * and data size received. When the receive is complete, this + * callback will be called to process the data and free the memory + * by passing the buffer's pointer and size, and data size received. + */ +typedef void (*IxI2cSlaveReadCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); + +/** + * @ingroup IxI2cDrv + * + * @brief The pointer to the function that will be called when a slave + * address detected in interrupt mode for a write. The parameters + * that is passed will provide the write status, buffer pointer, + * buffer size, and the bytes received. When a start of a write is + * initiated there will be no buffer allocated and this callback + * will be called to request for a buffer and to fill it with data. + * While transmitting, if the data in the buffer empties, this + * callback will be called to request for more data to be filled in + * the same or new buffer. When the transmit is complete, this + * callback will be called to free the memory or other actions to + * be taken. + */ +typedef void (*IxI2cSlaveWriteCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); + +/** + * @ingroup IxI2cDrv + * + * @brief The pointer to the function that will be called when a general + * call detected in interrupt mode for a read. The parameters that + * is passed will provide the read status, buffer pointer, buffer + * size, and the bytes received. When a start of a read is + * initiated there will be no buffer allocated and this callback + * will be called to request for a buffer. While receiving, if the + * buffer gets filled, this callback will be called to request for + * a new buffer while sending the filled buffer's pointer and size, + * and data size received. When the receive is complete, this + * callback will be called to process the data and free the memory + * by passing the buffer's pointer and size, and data size received. + */ +typedef void (*IxI2cGenCallCallbackP)(IX_I2C_STATUS, char*, UINT32, UINT32); + +/* + * Section for struct + */ + +/** + * @brief contains all the variables required to initialize the I2C unit + * + * Structure to be filled and used for calling initialization + */ +typedef struct +{ + IxI2cSpeedMode I2cSpeedSelect; /** + * NOTE: 1) An individual callback is to be registered for each Slave and Master + * Auxiliary Time Stamp registers. Thus to register for both Master and Slave time + * stamp interrupts either the same callback or two separate callbacks the API has + * to be invoked twice. + * 2) On the IXDP465 Development Platform, the Auxiliary Timestamp signal for + * slave mode is tied to GPIO 8 pin. This signal is software routed by default to + * PCI for backwards compatibility with the IXDP425 Development Platform. This + * routing must be disabled for the auxiliary slave time stamp register to work + * properly. The following commands may be used to accomplish this. However, refer + * to the IXDP465 Development Platform Users Guide or the BSP/LSP documentation for + * more specific information. + * + * For Linux (at the Redboot prompt i.e., before loading zImage): + * mfill -b 0x54100000 -1 -l 1 -p 8 + * mfill -b 0x54100001 -1 -l 1 -p 0x7f + * For vxWorks, at the prompt: + * intDisable(25) + * ixdp400FpgaIODetach(8) + * + * + * @li Re-entrant : no + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for callback or + invalid auxiliary snapshot mode + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccAuxTimeInterruptEnable(IxTimeSyncAccAuxMode auxMode, + IxTimeSyncAccAuxTimeCallback auxTimeCallback); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimeInterruptDisable( + IxTimeSyncAccAuxMode auxMode) + * + * @brief Disables the interrupt for the indicated mode of Auxiliary Time Stamp + * in the IEEE 1588 hardware assist block + * + * @param auxMode [in] - Auxiliary time stamp mode (slave or master) using which + * the interrupt will be disabled. + * + * This API will disable the Auxiliary Time Stamp Interrupt (Master or Slave) + * + * @li Re-entrant : yes + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_INVALIDPARAM - Invalid parameters passed + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccAuxTimeInterruptDisable(IxTimeSyncAccAuxMode auxMode); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn IxTimeSyncAccStatus ixTimeSyncAccAuxTimePoll( + IxTimeSyncAccAuxMode auxMode, + BOOL *auxPollFlag, + IxTimeSyncAccTimeValue *auxTime) + * + * @brief Poll for the Auxiliary Time Stamp captured for the mode indicated + * (Master or Slave) + * + * @param auxMode [in] - Auxiliary Snapshot Register (Slave or Master) to be checked + * @param auxPollFlag [out] - TRUE if the time stamp captured in auxiliary + snapshot register + * FALSE if the time stamp not captured in + auxiliary snapshot register + * @param auxTime [out] - Copy the current Auxiliary Snapshot Register value into the + * client provided buffer + * + * Polls for the Time stamp in the appropriate Auxiliary Snapshot Registers based + * on the mode specified. Return true and the contents of the Auxiliary snapshot, + * if it is available else return false. + * + * Please refer to the note #2 of the API @ref ixTimeSyncAccAuxTimeInterruptEnable + * for more information for Auxiliary Slave mode. + * + * @li Re-entrant : yes + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_INVALIDPARAM - Null parameter passed for auxPollFlag, + callback or invalid auxiliary snapshot mode + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + * @li IX_TIMESYNCACC_INTERRUPTMODEINUSE - Interrupt mode in use + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccAuxTimePoll(IxTimeSyncAccAuxMode auxMode, + BOOL *auxPollFlag, + IxTimeSyncAccTimeValue *auxTime); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn IxTimeSyncAccStatus ixTimeSyncAccReset(void) + * + * @brief Resets the IEEE 1588 hardware assist block + * + * Sets the reset bit in the IEEE1588 silicon which fully resets the silicon block + * + * @li Reentrant : yes + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccReset(void); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn IxTimeSyncAccStatus ixTimeSyncAccStatsGet(IxTimeSyncAccStats + *timeSyncStats) + * + * @brief Returns the IxTimeSyncAcc Statistics in the client supplied buffer + * + * @param timeSyncStats [out] - TimeSync statistics counter values + * + * This API will return the statistics of the received or transmitted messages. + * + * NOTE: 1) These counters are updated only when the client polls for the time + * stamps or interrupt are enabled. This is because the IxTimeSyncAcc module + * does not either transmit or receive messages and does only run the code + * when explicit requests received by client application. + * + * 2) These statistics reflect the number of valid PTP messages exchanged + * in Master and Slave modes but includes all the messages (including valid + * non-PTP messages) while operating in the Any mode. + * + * @li Reentrant : no + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_INVALIDPARAM - NULL parameter passed + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccStatsGet(IxTimeSyncAccStats *timeSyncStats); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn void ixTimeSyncAccStatsReset(void) + * + * @brief Reset Time Sync statistics + * + * This API will reset the statistics counters of the TimeSync access layer. + * + * @li Reentrant : yes + * @li ISR Callable: no + * + * @return @li None + */ +PUBLIC void +ixTimeSyncAccStatsReset(void); + +/** + * @ingroup IxTimeSyncAcc + * + * @fn IxTimeSyncAccStatus ixTimeSyncAccShow(void) + * + * @brief Displays the Time Sync current status + * + * This API will display status on the current configuration of the IEEE + * 1588 hardware assist block, contents of the various time stamp registers, + * outstanding interrupts and/or events. + * + * Note that this is intended for debug only, and in contrast to the other + * functions, it does not clear the any of the status bits associated with + * active timestamps and so is passive in its nature. + * + * @li Reentrant : yes + * @li ISR Callable : no + * + * @return @li IX_TIMESYNCACC_SUCCESS - Operation is successful + * @li IX_TIMESYNCACC_FAILED - Internal error occurred + */ +PUBLIC IxTimeSyncAccStatus +ixTimeSyncAccShow(void); + +#endif /* __ixp46X */ +#endif /* IXTIMESYNCACC_H */ + +/** + * @} defgroup IxTimeSyncAcc + */ + diff --git a/drivers/net/npe/include/IxTimerCtrl.h b/drivers/net/npe/include/IxTimerCtrl.h new file mode 100644 index 0000000..669dd3e --- /dev/null +++ b/drivers/net/npe/include/IxTimerCtrl.h @@ -0,0 +1,263 @@ +/** + * @file IxTimerCtrl.h + * @brief + * This is the header file for the Timer Control component. + * + * The timer callback control component provides a mechanism by which different + * client components can start a timer and have a supplied callback function + * invoked when the timer expires. + * The callbacks are all dispatched from one thread inside this component. + * Any component that needs to be called periodically should use this facility + * rather than create its own task with a sleep loop. + * + * @par + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/** + * @defgroup IxTimerCtrl IXP400 Timer Control (IxTimerCtrl) API + * + * @brief The public API for the IXP400 Timer Control Component. + * + * @{ + */ + +#ifndef IxTimerCtrl_H +#define IxTimerCtrl_H + + +#include "IxTypes.h" +/* #include "Ossl.h" */ + +/* + * #defines and macros used in this file. + */ + +/** + * @ingroup IxTimerCtrl + * + * @def IX_TIMERCTRL_NO_FREE_TIMERS + * + * @brief Timer schedule return code. + * + * Indicates that the request to start a timer failed because + * all available timer resources are used. + */ +#define IX_TIMERCTRL_NO_FREE_TIMERS 2 + + +/** + * @ingroup IxTimerCtrl + * + * @def IX_TIMERCTRL_PARAM_ERROR + * + * @brief Timer schedule return code. + * + * Indicates that the request to start a timer failed because + * the client has supplied invalid parameters. + */ +#define IX_TIMERCTRL_PARAM_ERROR 3 + + +/* + * Typedefs whose scope is limited to this file. + */ + +/** + * @ingroup IxTimerCtrl + * + * @brief A typedef for a pointer to a timer callback function. + * @para void * - This parameter is supplied by the client when the + * timer is started and passed back to the client in the callback. + * @note in general timer callback functions should not block or + * take longer than 100ms. This constraint is required to ensure that + * higher priority callbacks are not held up. + * All callbacks are called from the same thread. + * This thread is a shared resource. + * The parameter passed is provided when the timer is scheduled. + */ +typedef void (*IxTimerCtrlTimerCallback)(void *userParam); + + +/** + * @ingroup IxTimerCtrl + * + * @brief List used to identify the users of timers. + * @note The order in this list indicates priority. Components appearing + * higher in the list will be given priority over components lower in the + * list. When adding components, please insert at an appropriate position + * for priority ( i.e values should be less than IxTimerCtrlMaxPurpose ) . + */ +typedef enum +{ + IxTimerCtrlAdslPurpose, + /* Insert new purposes above this line only + */ + IxTimerCtrlMaxPurpose +} +IxTimerCtrlPurpose; + + +/* + * Function definition + */ + +/** + * @ingroup IxTimerCtrl + * + * @fn ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func, + void *userParam, + IxTimerCtrlPurpose purpose, + UINT32 relativeTime, + unsigned *timerId ) + * + * @brief Schedules a callback function to be called after a period of "time". + * The callback function should not block or run for more than 100ms. + * This function + * + * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called. + * @param userParam void [in] - a parameter to send to the callback function, can be NULL. + * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will + * decide the priority of callbacks with different purpose. + * @param relativeTime UINT32 [in] - time relative to now in milliseconds after which the callback + * will be called. The time must be greater than the duration of one OS tick. + * @param *timerId unsigned [out] - An id for the callback scheduled. + * This id can be used to cancel the callback. + * @return + * @li IX_SUCCESS - The timer was started successfully. + * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number + * of running timers has been exceeded. + * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied + * a NULL callback func, or the requested timeout is less than one OS tick. + * @note This function is re-entrant. The function accesses a list of running timers + * and may suspend the calling thread if this list is being accesed by another thread. + */ +PUBLIC IX_STATUS +ixTimerCtrlSchedule(IxTimerCtrlTimerCallback func, + void *userParam, + IxTimerCtrlPurpose purpose, + UINT32 relativeTime, + unsigned *timerId ); + + +/** + * @ingroup IxTimerCtrl + * + * @fn ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func, + void *param, + IxTimerCtrlPurpose purpose, + UINT32 interval, + unsigned *timerId ) + * + * @brief Schedules a callback function to be called after a period of "time". + * The callback function should not block or run for more than 100ms. + * + * @param func @ref IxTimerCtrlTimerCallback [in] - the callback function to be called. + * @param userParam void [in] - a parameter to send to the callback function, can be NULL. + * @param purpose @ref IxTimerCtrlPurpose [in] - the purpose of the callback, internally this component will + * decide the priority of callbacks with different purpose. + * @param interval UINT32 [in] - the interval in milliseconds between calls to func. + * @param timerId unsigned [out] - An id for the callback scheduled. + * This id can be used to cancel the callback. + * @return + * @li IX_SUCCESS - The timer was started successfully. + * @li IX_TIMERCTRL_NO_FREE_TIMERS - The timer was not started because the maximum number + * of running timers has been exceeded. + * @li IX_TIMERCTRL_PARAM_ERROR - The timer was not started because the client has supplied + * a NULL callback func, or the requested timeout is less than one OS tick. + * @note This function is re-entrant. The function accesses a list of running timers + * and may suspend the calling thread if this list is being accesed by another thread. + */ +PUBLIC IX_STATUS +ixTimerCtrlScheduleRepeating(IxTimerCtrlTimerCallback func, + void *param, + IxTimerCtrlPurpose purpose, + UINT32 interval, + unsigned *timerId ); + +/** + * @ingroup IxTimerCtrl + * + * @fn ixTimerCtrlCancel (unsigned id) + * + * @brief Cancels a scheduled callback. + * + * @param id unsigned [in] - the id of the callback to be cancelled. + * @return + * @li IX_SUCCESS - The timer was successfully stopped. + * @li IX_FAIL - The id parameter did not corrrespond to any running timer.. + * @note This function is re-entrant. The function accesses a list of running timers + * and may suspend the calling thread if this list is being accesed by another thread. + */ +PUBLIC IX_STATUS +ixTimerCtrlCancel (unsigned id); + +/** + * @ingroup IxTimerCtrl + * + * @fn ixTimerCtrlInit(void) + * + * @brief Initialise the Timer Control Component. + * @return + * @li IX_SUCCESS - The timer control component initialized successfully. + * @li IX_FAIL - The timer control component initialization failed, + * or the component was already initialized. + * @note This must be done before any other API function is called. + * This function should be called once only and is not re-entrant. + */ +PUBLIC IX_STATUS +ixTimerCtrlInit(void); + + +/** + * @ingroup IxTimerCtrl + * + * @fn ixTimerCtrlShow( void ) + * + * @brief Display the status of the Timer Control Component. + * @return void + * @note Displays a list of running timers. + * This function is not re-entrant. This function does not suspend the calling thread. + */ +PUBLIC void +ixTimerCtrlShow( void ); + +#endif /* IXTIMERCTRL_H */ + diff --git a/drivers/net/npe/include/IxTypes.h b/drivers/net/npe/include/IxTypes.h new file mode 100644 index 0000000..c4c5a2d --- /dev/null +++ b/drivers/net/npe/include/IxTypes.h @@ -0,0 +1,86 @@ +/** + * @file IxTypes.h (Replaced by OSAL) + * + * @date 28-NOV-2001 + + * @brief This file contains basic types used by the IXP400 software + * + * Design Notes: + * This file shall only include fundamental types and definitions to be + * shared by all the IXP400 components. + * Please DO NOT add component-specific types here. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @defgroup IxTypes IXP400 Types (IxTypes) + * + * @brief Basic data types used by the IXP400 project + * + * @{ + */ + +#ifndef IxTypes_H + +#ifndef __doxygen_HIDE + +#define IxTypes_H + +#endif /* __doxygen_HIDE */ + + +/* WR51880: Undefined data types workaround for backward compatibility */ +#ifdef __linux +#ifndef __INCvxTypesOldh +typedef int (*FUNCPTR)(void); +typedef int STATUS; +#define OK (0) +#define ERROR (-1) +#endif +#endif + +#include "IxOsalBackward.h" + +#endif /* IxTypes_H */ + +/** + * @} addtogroup IxTypes + */ diff --git a/drivers/net/npe/include/IxUART.h b/drivers/net/npe/include/IxUART.h new file mode 100644 index 0000000..03a4444 --- /dev/null +++ b/drivers/net/npe/include/IxUART.h @@ -0,0 +1,458 @@ +/** + * @file IxUART.h + * + * @date 12-OCT-01 + * + * @brief Public header for the Intel IXP400 internal UART, generic driver. + * + * Design Notes: + * This driver allows you to perform the following functions: + * Device Initialization, + * send/receive characters. + * + * Perform Uart IOCTL for the following: + * Set/Get the current baud rate, + * set parity, + * set the number of Stop bits, + * set the character Length (5,6,7,8), + * enable/disable Hardware flow control. + * + * Only Polled mode is supported for now. + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- +*/ + +/** + * @defgroup IxUARTAccAPI IXP400 UART Access (IxUARTAcc) API + * + * @brief IXP400 UARTAcc Driver Public API + * + * @{ + */ + + +/* Defaults */ + +/** + * @defgroup DefaultDefines Defines for Default Values + * + * @brief Default values which can be used for UART configuration + * + * @sa ixUARTDev + */ + +/** + * @def IX_UART_DEF_OPTS + * + * @brief The default hardware options to set the UART to - + * no flow control, 8 bit word, 1 stop bit, no parity + * + * @ingroup DefaultDefines + */ +#define IX_UART_DEF_OPTS (CLOCAL | CS8) + +/** + * @def IX_UART_DEF_XMIT + * + * @brief The default UART FIFO size - must be no bigger than 64 + * + * @ingroup DefaultDefines + */ +#define IX_UART_DEF_XMIT 64 + +/** + * @def IX_UART_DEF_BAUD + * + * @brief The default UART baud rate - 9600 + * + * @ingroup DefaultDefines + */ +#define IX_UART_DEF_BAUD 9600 + +/** + * @def IX_UART_MIN_BAUD + * + * @brief The minimum UART baud rate - 9600 + * + * @ingroup DefaultDefines + */ +#define IX_UART_MIN_BAUD 9600 + +/** + * @def IX_UART_MAX_BAUD + * + * @brief The maximum UART baud rate - 926100 + * + * @ingroup DefaultDefines + */ +#define IX_UART_MAX_BAUD 926100 + +/** + * @def IX_UART_XTAL + * + * @brief The UART clock speed + * + * @ingroup DefaultDefines + */ +#define IX_UART_XTAL 14745600 + + + +/* IOCTL commands (Request codes) */ + +/** + * @defgroup IoctlCommandDefines Defines for IOCTL Commands + * + * @brief IOCTL Commands (Request codes) which can be used + * with @ref ixUARTIoctl + */ + + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_BAUD_SET + * + * @brief Set the baud rate + */ +#define IX_BAUD_SET 0 + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_BAUD_GET + * + * @brief Get the baud rate + */ +#define IX_BAUD_GET 1 + +/** + * @ingroup IoctlCommandDefines + * @def IX_MODE_SET + * @brief Set the UART mode of operation + */ +#define IX_MODE_SET 2 + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_MODE_GET + * + * @brief Get the current UART mode of operation + */ +#define IX_MODE_GET 3 + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_OPTS_SET + * + * @brief Set the UART device options + */ +#define IX_OPTS_SET 4 + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_OPTS_GET + * + * @brief Get the UART device options + */ +#define IX_OPTS_GET 5 + +/** + * @ingroup IoctlCommandDefines + * + * @def IX_STATS_GET + * + * @brief Get the UART statistics + */ +#define IX_STATS_GET 6 + + +/* POSIX style ioctl arguments */ + +/** + * @defgroup IoctlArgDefines Defines for IOCTL Arguments + * + * @brief POSIX style IOCTL arguments which can be used + * with @ref ixUARTIoctl + * + * @sa ixUARTMode + */ + + +/** + * @ingroup IoctlArgDefines + * + * @def CLOCAL + * + * @brief Software flow control + */ +#ifdef CLOCAL +#undef CLOCAL +#endif +#define CLOCAL 0x1 + +/** + * @ingroup IoctlArgDefines + * + * @def CREAD + * + * @brief Enable interrupt receiver + */ +#ifdef CREAD +#undef CREAD +#endif +#define CREAD 0x2 + +/** + * @ingroup IoctlArgDefines + * + * @def CSIZE + * + * @brief Characters size + */ +#ifdef CSIZE +#undef CSIZE +#endif +#define CSIZE 0xc + +/** + * @ingroup IoctlArgDefines + * + * @def CS5 + * + * @brief 5 bits + */ +#ifdef CS5 +#undef CS5 +#endif +#define CS5 0x0 + +/** + * @ingroup IoctlArgDefines + * + * @def CS6 + * + * @brief 6 bits + */ +#ifdef CS6 +#undef CS6 +#endif +#define CS6 0x4 + +/** + * @ingroup IoctlArgDefines + * + * @def CS7 + * + * @brief 7 bits + */ +#ifdef CS7 +#undef CS7 +#endif +#define CS7 0x8 + +/** + * @ingroup IoctlArgDefines + * + * @def CS8 + * + * @brief 8 bits + */ +#ifdef CS8 +#undef CS8 +#endif +#define CS8 0xc + +/** + * @ingroup IoctlArgDefines + * + * @def STOPB + * + * @brief Send two stop bits (else one) + */ +#define STOPB 0x20 + +/** + * @ingroup IoctlArgDefines + * + * @def PARENB + * + * @brief Parity detection enabled (else disabled) + */ +#ifdef PARENB +#undef PARENB +#endif +#define PARENB 0x40 + +/** + * @ingroup IoctlArgDefines + * + * @def PARODD + * + * @brief Odd parity (else even) + */ +#ifdef PARODD +#undef PARODD +#endif +#define PARODD 0x80 + +/** + * @enum ixUARTMode + * @brief The mode to set to UART to. + */ +typedef enum +{ + INTERRUPT=0, /**< Interrupt mode */ + POLLED, /**< Polled mode */ + LOOPBACK /**< Loopback mode */ +} ixUARTMode; + +/** + * @struct ixUARTStats + * @brief Statistics for the UART. + */ +typedef struct +{ + UINT32 rxCount; + UINT32 txCount; + UINT32 overrunErr; + UINT32 parityErr; + UINT32 framingErr; + UINT32 breakErr; +} ixUARTStats; + +/** + * @struct ixUARTDev + * @brief Device descriptor for the UART. + */ +typedef struct +{ + UINT8 *addr; /**< device base address */ + ixUARTMode mode; /**< interrupt, polled or loopback */ + int baudRate; /**< baud rate */ + int freq; /**< UART clock frequency */ + int options; /**< hardware options */ + int fifoSize; /**< FIFO xmit size */ + + ixUARTStats stats; /**< device statistics */ +} ixUARTDev; + +/** + * @ingroup IxUARTAccAPI + * + * @fn IX_STATUS ixUARTInit(ixUARTDev* pUART) + * + * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. + * + * @brief Initialise the UART. This puts the chip in a quiescent state. + * + * @pre The base address for the UART must contain a valid value. + * Also the baud rate and hardware options must contain sensible values + * otherwise the defaults will be used as defined in ixUART.h + * + * @post UART is initialized and ready to send and receive data. + * + * @note This function should only be called once per device. + * + * @retval IX_SUCCESS - UART device successfully initialised. + * @retval IX_FAIL - Critical error, device not initialised. + ***************************************************************************/ +PUBLIC IX_STATUS ixUARTInit(ixUARTDev* pUART); + +/** + * @ingroup IxUARTAccAPI + * + * @fn IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar) + * + * @param pUART @ref ixUARTDev [out] - pointer to UART structure describing our device. + * @param outChar int [out] - character to transmit. + * + * @brief Transmit a character in polled mode. + * + * @pre UART device must be initialised. + * + * @retval IX_SUCCESS - character was successfully transmitted. + * @retval IX_FAIL - output buffer is full (try again). + ***************************************************************************/ +PUBLIC IX_STATUS ixUARTPollOutput(ixUARTDev* pUART, int outChar); + +/** + * @ingroup IxUARTAccAPI + * + * @fn IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar) + * + * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. + * @param *inChar char [in] - character read from the device. + * + * @brief Receive a character in polled mode. + * + * @pre UART device must be initialised. + * + * @retval IX_SUCCESS - character was successfully read. + * @retval IX_FAIL - input buffer empty (try again). + ***************************************************************************/ +PUBLIC IX_STATUS ixUARTPollInput(ixUARTDev* pUART, char *inChar); + +/** + * @ingroup IxUARTAccAPI + * + * @fn IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg) + * + * @param pUART @ref ixUARTDev [in] - pointer to UART structure describing our device. + * @param cmd int [in] - an ioctl request code. + * @param arg void* [in] - optional argument used to set the device mode, + * baud rate, and hardware options. + * + * @brief Perform I/O control routines on the device. + * + * @retval IX_SUCCESS - requested feature was set/read successfully. + * @retval IX_FAIL - error setting/reading the requested feature. + * + * @sa IoctlCommandDefines + * @sa IoctlArgDefines + ***************************************************************************/ +PUBLIC IX_STATUS ixUARTIoctl(ixUARTDev* pUART, int cmd, void* arg); + +/** + * @} defgroup IxUARTAcc + */ diff --git a/drivers/net/npe/include/IxVersionId.h b/drivers/net/npe/include/IxVersionId.h new file mode 100644 index 0000000..27796ed --- /dev/null +++ b/drivers/net/npe/include/IxVersionId.h @@ -0,0 +1,155 @@ +/** + * @file IxVersionId.h + * + * @date 22-Aug-2002 + * + * @brief This file contains the IXP400 Software version identifier + * + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + */ + +/** + * @defgroup IxVersionId IXP400 Version ID (IxVersionId) + * + * @brief Version Identifiers + * + * @{ + */ + +#ifndef IXVERSIONID_H +#define IXVERSIONID_H + +/** + * @brief Version Identifier String + * + * This string will be updated with each customer release of the IXP400 + * Software. + */ +#define IX_VERSION_ID "2_0" + +/** + * This string will be updated with each customer release of the IXP400 + * ADSL driver package. + */ +#define IX_VERSION_ADSL_ID "1_12" + + +/** + * This string will be updated with each customer release of the IXP400 + * USB Client driver package. + */ +#define IX_VERSION_USBRNDIS_ID "1_9" + +/** + * This string will be updated with each customer release of the IXP400 + * I2C Linux driver package. + */ +#define IX_VERSION_I2C_LINUX_ID "1_0" + +/** + * @brief Linux Ethernet Driver Patch Version Identifier String + * + * This string will be updated with each release of Linux Ethernet Patch + */ +#define LINUX_ETHERNET_DRIVER_PATCH_ID "1_4" + +/** + * @brief Linux Integration Patch Version Identifier String + * + * This String will be updated with each release of Linux Integration Patch + */ +#define LINUX_INTEGRATION_PATCH_ID "1_3" + +/** + * @brief Linux Ethernet Readme version Identifier String + * + * This string will be updated with each release of Linux Ethernet Readme + */ +#define LINUX_ETHERNET_README_ID "1_3" + +/** + * @brief Linux Integration Readme version Identifier String + * + * This string will be updated with each release of Linux Integration Readme + */ + +#define LINUX_INTEGRATION_README_ID "1_3" + +/** + * @brief Linux I2C driver Readme version Identifier String + * + * This string will be updated with each release of Linux I2C Driver Readme + */ +#define LINUX_I2C_DRIVER_README_ID "1_0" + +/** + * @brief ixp425_eth_update_nf_bridge.patch version Identifier String + * + * This string will be updated with each release of ixp425_eth_update_nf_bridge. +patch + * + */ + +#define IXP425_ETH_UPDATE_NF_BRIDGE_ID "1_3" + +/** + * @brief Internal Release Identifier String + * + * This string will be updated with each internal release (SQA drop) + * of the IXP400 Software. + */ +#define IX_VERSION_INTERNAL_ID "SQA3_5" + +/** + * @brief Compatible Tornado Version Identifier + */ +#define IX_VERSION_COMPATIBLE_TORNADO "Tornado2_2_1-PNE2_0" + +/** + * @brief Compatible Linux Version Identifier + */ +#define IX_VERSION_COMPATIBLE_LINUX "MVL3_1" + + +#endif /* IXVERSIONID_H */ + +/** + * @} addtogroup IxVersionId + */ diff --git a/drivers/net/npe/include/ix_error.h b/drivers/net/npe/include/ix_error.h new file mode 100644 index 0000000..d32ace2 --- /dev/null +++ b/drivers/net/npe/include/ix_error.h @@ -0,0 +1,66 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = FILENAME + * ix_error.h (Replaced by OSAL) + * + * = DESCRIPTION + * This file will describe the basic error type and support functions that + * will be used by the IXA SDK Framework API. + * + * = AUTHOR + * Intel Corporation + * + * = CHANGE HISTORY + * 4/22/2002 4:19:03 PM - creation time + * ============================================================================ + */ + +#if !defined(__IX_ERROR_H__) +#define __IX_ERROR_H__ + +#include "IxOsalBackward.h" + +#endif /* end !defined(__IX_ERROR_H__) */ + diff --git a/drivers/net/npe/include/ix_macros.h b/drivers/net/npe/include/ix_macros.h new file mode 100644 index 0000000..53f5942 --- /dev/null +++ b/drivers/net/npe/include/ix_macros.h @@ -0,0 +1,266 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = FILENAME + * ix_macros.h + * + * = DESCRIPTION + * This file will define the basic preprocessor macros that are going to be used + * the IXA SDK Framework API. + * + * = AUTHOR + * Intel Corporation + * + * = CHANGE HISTORY + * 4/22/2002 4:41:05 PM - creation time + * ============================================================================ + */ + +#if !defined(__IX_MACROS_H__) +#define __IX_MACROS_H__ + + +#if defined(__cplusplus) +extern "C" +{ +#endif /* end defined(__cplusplus) */ + + +/** + * MACRO NAME: IX_BIT_FIELD_MASK16 + * + * DESCRIPTION: Builds the mask required to extract the bit field from a 16 bit unsigned integer value. + * + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns a 16 bit mask that will extract the bit field from a 16 bit unsigned integer value. + */ +#define IX_BIT_FIELD_MASK16( \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + ((ix_bit_mask16)((((ix_uint16)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \ + (ix_uint16)1) << arg_FieldLSBBit)) + + + +/** + * MACRO NAME: IX_GET_BIT_FIELD16 + * + * DESCRIPTION: Extracts a bit field from 16 bit unsigned integer. The returned value is normalized in + * in the sense that will be right aligned. + * + * @Param: - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 - + * arg_FieldLSBBit)) - 1. + */ +#define IX_GET_BIT_FIELD16( \ + arg_PackedData16, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (((ix_uint16)(arg_PackedData16) & IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) >> \ + arg_FieldLSBBit) + + +/** + * MACRO NAME: IX_MAKE_BIT_FIELD16 + * + * DESCRIPTION: This macro will create a temporary 16 bit value with the bit field + * desired set to the desired value. + * + * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to + * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns a temporary ix_uint16 value that has the bit field set to the appropriate value. + */ +#define IX_MAKE_BIT_FIELD16( \ + arg_BitFieldValue, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (((ix_uint16)(arg_BitFieldValue) << arg_FieldLSBBit) & \ + IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit)) + +/** + * MACRO NAME: IX_SET_BIT_FIELD16 + * + * DESCRIPTION: Sets a new value for a bit field from a 16 bit unsigned integer. + * + * @Param: - IN arg_PackedData16 a 16 bit unsigned integer that contains the bit field of interest. + * @Param: - IN arg_BitFieldValue is the new vale of the bit field. The value can be from 0 to + * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns the updated value of arg_PackedData16. + */ +#define IX_SET_BIT_FIELD16( \ + arg_PackedData16, \ + arg_BitFieldValue, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (arg_PackedData16 = (((ix_uint16)(arg_PackedData16) & \ + ~(IX_BIT_FIELD_MASK16(arg_FieldLSBBit, arg_FieldMSBBit))) | \ + IX_MAKE_BIT_FIELD16(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit))) + + +/** + * MACRO NAME: IX_BIT_FIELD_MASK32 + * + * DESCRIPTION: Builds the mask required to extract the bit field from a 32 bit unsigned integer value. + * + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns a 32 bit mask that will extract the bit field from a 32 bit unsigned integer value. + */ +#define IX_BIT_FIELD_MASK32( \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + ((ix_bit_mask32)((((ix_uint32)1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - \ + (ix_uint32)1) << arg_FieldLSBBit)) + + + +/** + * MACRO NAME: IX_GET_BIT_FIELD32 + * + * DESCRIPTION: Extracts a bit field from 32 bit unsigned integer. The returned value is normalized in + * in the sense that will be right aligned. + * + * @Param: - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns the value of the bit field. The value can be from 0 to (1 << (arg_FieldMSBBit + 1 - + * arg_FieldLSBBit)) - 1. + */ +#define IX_GET_BIT_FIELD32( \ + arg_PackedData32, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (((ix_uint32)(arg_PackedData32) & IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit)) >> \ + arg_FieldLSBBit) + + + + +/** + * MACRO NAME: IX_MAKE_BIT_FIELD32 + * + * DESCRIPTION: This macro will create a temporary 32 bit value with the bit field + * desired set to the desired value. + * + * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to + * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns a temporary ix_uint32 value that has the bit field set to the appropriate value. + */ +#define IX_MAKE_BIT_FIELD32( \ + arg_BitFieldValue, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (((ix_uint32)(arg_BitFieldValue) << arg_FieldLSBBit) & \ + IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit)) + + +/** + * MACRO NAME: IX_SET_BIT_FIELD32 + * + * DESCRIPTION: Sets a new value for a bit field from a 32 bit unsigned integer. + * + * @Param: - IN arg_PackedData32 a 32 bit unsigned integer that contains the bit field of interest. + * @Param: - IN arg_BitFieldValue is the new value of the bit field. The value can be from 0 to + * (1 << (arg_FieldMSBBit + 1 - arg_FieldLSBBit)) - 1. + * @Param: - IN arg_FieldLSBBit an unsigned integer value representing the position of the least significant + * bit of the bit field. + * @Param: - IN arg_FieldMSBBit an unsigned integer value representing the position of the most significant + * bit of the bit field. + * + * @Return: Returns the updated value of arg_PackedData32. + */ +#define IX_SET_BIT_FIELD32( \ + arg_PackedData32, \ + arg_BitFieldValue, \ + arg_FieldLSBBit, \ + arg_FieldMSBBit \ + ) \ + (arg_PackedData32 = (((ix_uint32)(arg_PackedData32) & \ + ~(IX_BIT_FIELD_MASK32(arg_FieldLSBBit, arg_FieldMSBBit))) | \ + IX_MAKE_BIT_FIELD32(arg_BitFieldValue, arg_FieldLSBBit, arg_FieldMSBBit))) + + + +#if defined(__cplusplus) +} +#endif /* end defined(__cplusplus) */ + +#endif /* end !defined(__IX_MACROS_H__) */ diff --git a/drivers/net/npe/include/ix_os_type.h b/drivers/net/npe/include/ix_os_type.h new file mode 100644 index 0000000..8575096 --- /dev/null +++ b/drivers/net/npe/include/ix_os_type.h @@ -0,0 +1,65 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = FILENAME + * ix_os_type.h (Replaced by OSAL) + * + * = DESCRIPTION + * This file provides protable symbol definitions for the current OS type. + * + * = AUTHOR + * Intel Corporation + * + * = CHANGE HISTORY + * 4/22/2002 4:43:30 PM - creation time + * ============================================================================ + */ + +#if !defined(__IX_OS_TYPE_H__) +#define __IX_OS_TYPE_H__ + +#include "IxOsalBackward.h" + +#endif /* end !defined(__IX_OS_TYPE_H__) */ + diff --git a/drivers/net/npe/include/ix_ossl.h b/drivers/net/npe/include/ix_ossl.h new file mode 100644 index 0000000..b59f7d0 --- /dev/null +++ b/drivers/net/npe/include/ix_ossl.h @@ -0,0 +1,160 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = LIBRARY + * OSSL - Operating System Services Library + * + * = MODULE + * OSSL Abstraction layer header file + * + * = FILENAME + * ix_ossl.h (Replaced by OSAL) + * + * = DESCRIPTION + * This file contains the prototypes of OS-independent wrapper + * functions which allow the programmer not to be tied to a specific + * operating system. The OSSL functions can be divided into three classes: + * + * 1) synchronization-related wrapper functions around thread system calls + * 2) thread-related wrapper functions around thread calls + * 3) transactor/workbench osapi calls -- defined in osApi.h + * + * Both 1 and 2 classes of functions provide Thread Management, Thread + * Synchronization, Mutual Exclusion and Timer primitives. Namely, + * creation and deletion functions as well as the standard "wait" and + * "exit". Additionally, a couple of utility functions which enable to + * pause the execution of a thread are also provided. + * + * The 3rd class provides a slew of other OSAPI functions to handle + * Transactor/WorkBench OS calls. + * + * + * OSSL Thread APIs: + * The OSSL thread functions that allow for thread creation, + * get thread id, thread deletion and set thread priroity. + * + * ix_ossl_thread_create + * ix_ossl_thread_get_id + * ix_ossl_thread_exit + * ix_ossl_thread_kill + * ix_ossl_thread_set_priority + * ix_ossl_thread__delay + * + * OSSL Semaphore APIs: + * The OSSL semaphore functions that allow for initialization, + * posting, waiting and deletion of semaphores. + * + * ix_ossl_sem_init + * ix_ossl_sem_fini + * ix_ossl_sem_take + * ix_ossl_sem_give + * ix_ossl_sem_flush + * + * OSSL Mutex APIs: + * The OSSL wrapper functions that allow for initialization, + * posting, waiting and deletion of mutexes. + * + * ix_ossl_mutex_init + * ix_ossl_mutex_fini + * ix_ossl_mutex_lock + * ix_ossl_mutex_unlock + * + * OSSL Timer APIs: + * The timer APIs provide sleep and get time functions. + * + * ix_ossl_sleep + * ix_ossl_sleep_tick + * ix_ossl_time_get + * + * OSAPIs for Transactor/WorkBench: + * These OSAPI functions are used for transator OS calls. + * They are defined in osApi.h. + * + * Sem_Init + * Sem_Destroy + * Sem_Wait + * Sem_Wait + * Thread_Create + * Thread_Cancel + * Thread_SetPriority + * delayMs + * delayTick + * + * + * + ********************************************************************** + * + * + * = AUTHOR + * Intel Corporation + * + * = ACKNOWLEDGEMENTS + * + * + * = CREATION TIME + * 1/8/2002 1:53:42 PM + * + * = CHANGE HISTORY + * 02/22/2002 : Renamed osapi.h os_api.h + * Moved OS header file includes from OSSL.h to os_api.h + * Moved OS specific datatypes to os_api.h + * Modified data types, macros and functions as per + * 'C' coding guidelines. + * + * + * ============================================================================ + */ + +#ifndef _IX_OSSL_H +#ifndef __doxygen_hide +#define _IX_OSSL_H +#endif /* __doxygen_hide */ + +#include "IxOsalBackward.h" + +#endif /* _IX_OSSL_H */ + +/** + * @} defgroup IxOSSL + */ diff --git a/drivers/net/npe/include/ix_symbols.h b/drivers/net/npe/include/ix_symbols.h new file mode 100644 index 0000000..f7bb029 --- /dev/null +++ b/drivers/net/npe/include/ix_symbols.h @@ -0,0 +1,106 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = FILENAME + * ix_symbols.h + * + * = DESCRIPTION + * This file declares all the global preprocessor symbols required by + * the IXA SDK Framework API. + * + * = AUTHOR + * Intel Corporation + * + * = CHANGE HISTORY + * 4/23/2002 10:41:13 AM - creation time + * ============================================================================ + */ + +#if !defined(__IX_SYMBOLS_H__) +#define __IX_SYMBOLS_H__ + + +#if defined(__cplusplus) +extern "C" +{ +#endif /* end defined(__cplusplus) */ + +/** + * The IX_EXPORT_FUNCTION symbol will be used for compilation on different platforms. + * We are planning to provide a simulation version of the library that should work + * with the Transactor rather than the hardware. This implementation will be done on + * WIN32 in the form of a DLL that will need to export functions and symbols. + */ +#if (_IX_OS_TYPE_ == _IX_OS_WIN32_) +# if defined(_IX_LIB_INTERFACE_IMPLEMENTATION_) +# define IX_EXPORT_FUNCTION __declspec( dllexport ) +# elif defined(_IX_LIB_INTERFACE_IMPORT_DLL_) +# define IX_EXPORT_FUNCTION __declspec( dllimport ) +# else +# define IX_EXPORT_FUNCTION extern +# endif +#elif (_IX_OS_TYPE_ == _IX_OS_WINCE_) +# define IX_EXPORT_FUNCTION __declspec(dllexport) +#else +# define IX_EXPORT_FUNCTION extern +#endif + + +/** + * This symbols should be defined when we want to build for a multithreaded environment + */ +#define _IX_MULTI_THREADED_ 1 + + +/** + * This symbol should be defined in the case we to buils for a multithreaded environment + * but we want that our modules to work as if they are used in a single threaded environment. + */ +/* #define _IX_RM_EXPLICIT_SINGLE_THREADED_ 1 */ + +#if defined(__cplusplus) +} +#endif /* end defined(__cplusplus) */ + +#endif /* end !defined(__IX_SYMBOLS_H__) */ diff --git a/drivers/net/npe/include/ix_types.h b/drivers/net/npe/include/ix_types.h new file mode 100644 index 0000000..fc7b1e9 --- /dev/null +++ b/drivers/net/npe/include/ix_types.h @@ -0,0 +1,208 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = FILENAME + * ix_types.h + * + * = DESCRIPTION + * This file will define generic types that will guarantee the protability + * between different architectures and compilers. It should be used the entire + * IXA SDK Framework API. + * + * = AUTHOR + * Intel Corporation + * + * = CHANGE HISTORY + * 4/22/2002 4:44:17 PM - creation time + * ============================================================================ + */ + +#if !defined(__IX_TYPES_H__) +#define __IX_TYPES_H__ + + +#if defined(__cplusplus) +extern "C" +{ +#endif /* end defined(__cplusplus) */ + + +/** + * Define generic integral data types that will guarantee the size. + */ + +/** + * TYPENAME: ix_int8 + * + * DESCRIPTION: This type defines an 8 bit signed integer value. + * + */ +typedef signed char ix_int8; + + +/** + * TYPENAME: ix_uint8 + * + * DESCRIPTION: This type defines an 8 bit unsigned integer value. + * + */ +typedef unsigned char ix_uint8; + + +/** + * TYPENAME: ix_int16 + * + * DESCRIPTION: This type defines an 16 bit signed integer value. + * + */ +typedef signed short int ix_int16; + + +/** + * TYPENAME: ix_uint16 + * + * DESCRIPTION: This type defines an 16 bit unsigned integer value. + * + */ +typedef unsigned short int ix_uint16; + + +/** + * TYPENAME: ix_int32 + * + * DESCRIPTION: This type defines an 32 bit signed integer value. + * + */ +typedef signed int ix_int32; + + +/** + * TYPENAME: ix_uint32 + * + * DESCRIPTION: This type defines an 32 bit unsigned integer value. + * + */ +#ifndef __wince +typedef unsigned int ix_uint32; +#else +typedef unsigned long ix_uint32; +#endif + +/** + * TYPENAME: ix_int64 + * + * DESCRIPTION: This type defines an 64 bit signed integer value. + * + */ +#ifndef __wince +__extension__ typedef signed long long int ix_int64; +#endif + +/** + * TYPENAME: ix_uint64 + * + * DESCRIPTION: This type defines an 64 bit unsigned integer value. + * + */ +#ifndef __wince +__extension__ typedef unsigned long long int ix_uint64; +#endif + + +/** + * TYPENAME: ix_bit_mask8 + * + * DESCRIPTION: This is a generic type for a 8 bit mask. + */ +typedef ix_uint8 ix_bit_mask8; + + +/** + * TYPENAME: ix_bit_mask16 + * + * DESCRIPTION: This is a generic type for a 16 bit mask. + */ +typedef ix_uint16 ix_bit_mask16; + + +/** + * TYPENAME: ix_bit_mask32 + * + * DESCRIPTION: This is a generic type for a 32 bit mask. + */ +typedef ix_uint32 ix_bit_mask32; + + +/** + * TYPENAME: ix_bit_mask64 + * + * DESCRIPTION: This is a generic type for a 64 bit mask. + */ +#ifndef __wince +typedef ix_uint64 ix_bit_mask64; +#endif + + +/** + * TYPENAME: ix_handle + * + * DESCRIPTION: This type defines a generic handle. + * + */ +typedef ix_uint32 ix_handle; + + + +/** + * DESCRIPTION: This symbol defines a NULL handle + * + */ +#define IX_NULL_HANDLE ((ix_handle)0) + + +#if defined(__cplusplus) +} +#endif /* end defined(__cplusplus) */ + +#endif /* end !defined(__IX_TYPES_H__) */ diff --git a/drivers/net/npe/include/npe.h b/drivers/net/npe/include/npe.h new file mode 100644 index 0000000..b5eef86 --- /dev/null +++ b/drivers/net/npe/include/npe.h @@ -0,0 +1,90 @@ +/* + * (C) Copyright 2005 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef NPE_H +#define NPE_H + +/* + * defines... + */ +#define CONFIG_SYS_NPE_NUMS 1 +#ifdef CONFIG_HAS_ETH1 +#undef CONFIG_SYS_NPE_NUMS +#define CONFIG_SYS_NPE_NUMS 2 +#endif + +#define NPE_NUM_PORTS 3 +#define ACTIVE_PORTS 1 + +#define NPE_PKT_SIZE 1600 + +#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS 64 +#define CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS 2 + +#define NPE_MBUF_POOL_SIZE \ + ((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS + \ + CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) * \ + sizeof(IX_OSAL_MBUF) * ACTIVE_PORTS) + +#define NPE_PKT_POOL_SIZE \ + ((CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS + \ + CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS) * \ + NPE_PKT_SIZE * ACTIVE_PORTS) + +#define NPE_MEM_POOL_SIZE (NPE_MBUF_POOL_SIZE + NPE_PKT_POOL_SIZE) + +#define PHY_AUTONEGOTIATE_TIMEOUT 4000 /* 4000 ms autonegotiate timeout */ + +/* + * structs... + */ +struct npe { + u8 active; /* NPE active */ + u8 eth_id; /* IX_ETH_PORT_1 or IX_ETH_PORT_2 */ + u8 phy_no; /* which PHY (0 - 31) */ + u8 mac_address[6]; + + IX_OSAL_MBUF *rxQHead; + IX_OSAL_MBUF *txQHead; + + u8 *tx_pkts; + u8 *rx_pkts; + IX_OSAL_MBUF *rx_mbufs; + IX_OSAL_MBUF *tx_mbufs; + + int print_speed; + + int rx_read; + int rx_write; + int rx_len[PKTBUFSRX]; +}; + +/* + * prototypes... + */ +extern int npe_miiphy_read (const char *devname, unsigned char addr, + unsigned char reg, unsigned short *value); +extern int npe_miiphy_write (const char *devname, unsigned char addr, + unsigned char reg, unsigned short value); + +#endif /* ifndef NPE_H */ diff --git a/drivers/net/npe/include/os_datatypes.h b/drivers/net/npe/include/os_datatypes.h new file mode 100644 index 0000000..4387b2a --- /dev/null +++ b/drivers/net/npe/include/os_datatypes.h @@ -0,0 +1,82 @@ +/** + * ============================================================================ + * = COPYRIGHT + * + * @par + * IXP400 SW Release version 2.0 + * + * -- Copyright Notice -- + * + * @par + * Copyright 2001-2005, Intel Corporation. + * All rights reserved. + * + * @par + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * @par + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @par + * -- End of Copyright Notice -- + * = PRODUCT + * Intel(r) IXP425 Software Release + * + * = LIBRARY + * OSSL - Operating System Services Library + * + * = MODULE + * OS Specific Data Types header file + * + * = FILENAME + * OSSL.h (Replaced by OSAL) + * + * = DESCRIPTION + * This file contains definitions and encapsulations for OS specific data types. These + * encapsulated data types are used by OSSL header files and OS API functions. + * + * + ********************************************************************** + * + * + * = AUTHOR + * Intel Corporation + * + * = AKNOWLEDGEMENTS + * + * + * = CREATION TIME + * 1/8/2002 1:53:42 PM + * + * = CHANGE HISTORY + + * ============================================================================ + */ + +#ifndef _OS_DATATYPES_H +#define _OS_DATATYPES_H + +#include "IxOsalBackward.h" + +#endif /* _OS_DATATYPES_H */ + diff --git a/drivers/net/npe/miiphy.c b/drivers/net/npe/miiphy.c new file mode 100644 index 0000000..a04779a --- /dev/null +++ b/drivers/net/npe/miiphy.c @@ -0,0 +1,120 @@ +/*-----------------------------------------------------------------------------+ + | This source code is dual-licensed. You may use it under the terms of the + | GNU General Public License version 2, or under the license below. + | + | This source code has been made available to you by IBM on an AS-IS + | basis. Anyone receiving this source is licensed under IBM + | copyrights to use it in any way he or she deems fit, including + | copying it, modifying it, compiling it, and redistributing it either + | with or without modifications. No license under IBM patents or + | patent applications is to be implied by the copyright license. + | + | Any user of this software should understand that IBM cannot provide + | technical support for this software and will not be responsible for + | any consequences resulting from the use of this software. + | + | Any person who transfers this source code or any derivative work + | must include the IBM copyright notice, this paragraph, and the + | preceding two paragraphs in the transferred software. + | + | COPYRIGHT I B M CORPORATION 1995 + | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M + +-----------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------+ + | + | File Name: miiphy.c + | + | Function: This module has utilities for accessing the MII PHY through + | the EMAC3 macro. + | + | Author: Mark Wisner + | + | Change Activity- + | + | Date Description of Change BY + | --------- --------------------- --- + | 05-May-99 Created MKW + | 01-Jul-99 Changed clock setting of sta_reg from 66MHz to 50MHz to + | better match OPB speed. Also modified delay times. JWB + | 29-Jul-99 Added Full duplex support MKW + | 24-Aug-99 Removed printf from dp83843_duplex() JWB + | 19-Jul-00 Ported to esd cpci405 sr + | 23-Dec-03 Ported from miiphy.c to 440GX Travis Sawyer TBS + | + | + +-----------------------------------------------------------------------------*/ + +#include +#include +#include "IxOsal.h" +#include "IxEthAcc.h" +#include "IxEthAcc_p.h" +#include "IxEthAccMac_p.h" +#include "IxEthAccMii_p.h" + +/***********************************************************/ +/* Dump out to the screen PHY regs */ +/***********************************************************/ + +void miiphy_dump (char *devname, unsigned char addr) +{ + unsigned long i; + unsigned short data; + + + for (i = 0; i < 0x1A; i++) { + if (miiphy_read (devname, addr, i, &data)) { + printf ("read error for reg %lx\n", i); + return; + } + printf ("Phy reg %lx ==> %4x\n", i, data); + + /* jump to the next set of regs */ + if (i == 0x07) + i = 0x0f; + + } /* end for loop */ +} /* end dump */ + + +/***********************************************************/ +/* (Re)start autonegotiation */ +/***********************************************************/ +int phy_setup_aneg (char *devname, unsigned char addr) +{ + unsigned short ctl, adv; + + /* Setup standard advertise */ + miiphy_read (devname, addr, MII_ADVERTISE, &adv); + adv |= (LPA_LPACK | LPA_RFAULT | LPA_100BASE4 | + LPA_100FULL | LPA_100HALF | LPA_10FULL | + LPA_10HALF); + miiphy_write (devname, addr, MII_ADVERTISE, adv); + + /* Start/Restart aneg */ + miiphy_read (devname, addr, MII_BMCR, &ctl); + ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); + miiphy_write (devname, addr, MII_BMCR, ctl); + + return 0; +} + + +int npe_miiphy_read (const char *devname, unsigned char addr, + unsigned char reg, unsigned short *value) +{ + u16 val; + + ixEthAccMiiReadRtn(addr, reg, &val); + *value = val; + + return 0; +} /* phy_read */ + + +int npe_miiphy_write (const char *devname, unsigned char addr, + unsigned char reg, unsigned short value) +{ + ixEthAccMiiWriteRtn(addr, reg, value); + return 0; +} /* phy_write */ diff --git a/drivers/net/npe/npe.c b/drivers/net/npe/npe.c new file mode 100644 index 0000000..1fe3a95 --- /dev/null +++ b/drivers/net/npe/npe.c @@ -0,0 +1,696 @@ +/* + * (C) Copyright 2005-2006 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#if 0 +#define DEBUG /* define for debug output */ +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static IxQMgrDispatcherFuncPtr qDispatcherFunc = NULL; +static int npe_exists[NPE_NUM_PORTS]; +static int npe_used[NPE_NUM_PORTS]; + +/* A little extra so we can align to cacheline. */ +static u8 npe_alloc_pool[NPE_MEM_POOL_SIZE + CONFIG_SYS_CACHELINE_SIZE - 1]; +static u8 *npe_alloc_end; +static u8 *npe_alloc_free; + +static void *npe_alloc(int size) +{ + static int count = 0; + void *p = NULL; + + size = (size + (CONFIG_SYS_CACHELINE_SIZE-1)) & ~(CONFIG_SYS_CACHELINE_SIZE-1); + count++; + + if ((npe_alloc_free + size) < npe_alloc_end) { + p = npe_alloc_free; + npe_alloc_free += size; + } else { + printf("npe_alloc: failed (count=%d, size=%d)!\n", count, size); + } + return p; +} + +/* Not interrupt safe! */ +static void mbuf_enqueue(IX_OSAL_MBUF **q, IX_OSAL_MBUF *new) +{ + IX_OSAL_MBUF *m = *q; + + IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(new) = NULL; + + if (m) { + while(IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m)) + m = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m); + IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = new; + } else + *q = new; +} + +/* Not interrupt safe! */ +static IX_OSAL_MBUF *mbuf_dequeue(IX_OSAL_MBUF **q) +{ + IX_OSAL_MBUF *m = *q; + if (m) + *q = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m); + return m; +} + +static void reset_tx_mbufs(struct npe* p_npe) +{ + IX_OSAL_MBUF *m; + int i; + + p_npe->txQHead = NULL; + + for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS; i++) { + m = &p_npe->tx_mbufs[i]; + + memset(m, 0, sizeof(*m)); + + IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->tx_pkts[i * NPE_PKT_SIZE]; + IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; + mbuf_enqueue(&p_npe->txQHead, m); + } +} + +static void reset_rx_mbufs(struct npe* p_npe) +{ + IX_OSAL_MBUF *m; + int i; + + p_npe->rxQHead = NULL; + + HAL_DCACHE_INVALIDATE(p_npe->rx_pkts, NPE_PKT_SIZE * + CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); + + for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS; i++) { + m = &p_npe->rx_mbufs[i]; + + memset(m, 0, sizeof(*m)); + + IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->rx_pkts[i * NPE_PKT_SIZE]; + IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; + + if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) { + printf("ixEthAccPortRxFreeReplenish failed for port %d\n", p_npe->eth_id); + break; + } + } +} + +static void init_rx_mbufs(struct npe* p_npe) +{ + p_npe->rxQHead = NULL; + + p_npe->rx_pkts = npe_alloc(NPE_PKT_SIZE * + CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); + if (p_npe->rx_pkts == NULL) { + printf("alloc of packets failed.\n"); + return; + } + + p_npe->rx_mbufs = (IX_OSAL_MBUF *) + npe_alloc(sizeof(IX_OSAL_MBUF) * + CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS); + if (p_npe->rx_mbufs == NULL) { + printf("alloc of mbufs failed.\n"); + return; + } + + reset_rx_mbufs(p_npe); +} + +static void init_tx_mbufs(struct npe* p_npe) +{ + p_npe->tx_pkts = npe_alloc(NPE_PKT_SIZE * + CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS); + if (p_npe->tx_pkts == NULL) { + printf("alloc of packets failed.\n"); + return; + } + + p_npe->tx_mbufs = (IX_OSAL_MBUF *) + npe_alloc(sizeof(IX_OSAL_MBUF) * + CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS); + if (p_npe->tx_mbufs == NULL) { + printf("alloc of mbufs failed.\n"); + return; + } + + reset_tx_mbufs(p_npe); +} + +/* Convert IX_ETH_PORT_n to IX_NPEMH_NPEID_NPEx */ +static int __eth_to_npe(int eth_id) +{ + switch(eth_id) { + case IX_ETH_PORT_1: + return IX_NPEMH_NPEID_NPEB; + + case IX_ETH_PORT_2: + return IX_NPEMH_NPEID_NPEC; + + case IX_ETH_PORT_3: + return IX_NPEMH_NPEID_NPEA; + } + return 0; +} + +/* Poll the CSR machinery. */ +static void npe_poll(int eth_id) +{ + if (qDispatcherFunc != NULL) { + ixNpeMhMessagesReceive(__eth_to_npe(eth_id)); + (*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP); + } +} + +/* ethAcc RX callback */ +static void npe_rx_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid) +{ + struct npe* p_npe = (struct npe *)cbTag; + + if (IX_OSAL_MBUF_MLEN(m) > 0) { + mbuf_enqueue(&p_npe->rxQHead, m); + + if (p_npe->rx_write == ((p_npe->rx_read-1) & (PKTBUFSRX-1))) { + debug("Rx overflow: rx_write=%d rx_read=%d\n", + p_npe->rx_write, p_npe->rx_read); + } else { + debug("Received message #%d (len=%d)\n", p_npe->rx_write, + IX_OSAL_MBUF_MLEN(m)); + memcpy((void *)NetRxPackets[p_npe->rx_write], IX_OSAL_MBUF_MDATA(m), + IX_OSAL_MBUF_MLEN(m)); + p_npe->rx_len[p_npe->rx_write] = IX_OSAL_MBUF_MLEN(m); + p_npe->rx_write++; + if (p_npe->rx_write == PKTBUFSRX) + p_npe->rx_write = 0; + +#ifdef CONFIG_PRINT_RX_FRAMES + { + u8 *ptr = IX_OSAL_MBUF_MDATA(m); + int i; + + for (i=0; i<60; i++) { + debug("%02x ", *ptr++); + } + debug("\n"); + } +#endif + } + + m = mbuf_dequeue(&p_npe->rxQHead); + } else { + debug("Received frame with length 0!!!\n"); + m = mbuf_dequeue(&p_npe->rxQHead); + } + + /* Now return mbuf to NPE */ + IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL; + IX_OSAL_MBUF_FLAGS(m) = 0; + + if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) { + debug("npe_rx_callback: Error returning mbuf.\n"); + } +} + +/* ethAcc TX callback */ +static void npe_tx_callback(u32 cbTag, IX_OSAL_MBUF *m) +{ + struct npe* p_npe = (struct npe *)cbTag; + + debug("%s\n", __FUNCTION__); + + IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE; + IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL; + IX_OSAL_MBUF_FLAGS(m) = 0; + + mbuf_enqueue(&p_npe->txQHead, m); +} + + +static int npe_set_mac_address(struct eth_device *dev) +{ + struct npe *p_npe = (struct npe *)dev->priv; + IxEthAccMacAddr npeMac; + + debug("%s\n", __FUNCTION__); + + /* Set MAC address */ + memcpy(npeMac.macAddress, dev->enetaddr, 6); + + if (ixEthAccPortUnicastMacAddressSet(p_npe->eth_id, &npeMac) != IX_ETH_ACC_SUCCESS) { + printf("Error setting unicast address! %02x:%02x:%02x:%02x:%02x:%02x\n", + npeMac.macAddress[0], npeMac.macAddress[1], + npeMac.macAddress[2], npeMac.macAddress[3], + npeMac.macAddress[4], npeMac.macAddress[5]); + return 0; + } + + return 1; +} + +/* Boot-time CSR library initialization. */ +static int npe_csr_load(void) +{ + int i; + + if (ixQMgrInit() != IX_SUCCESS) { + debug("Error initialising queue manager!\n"); + return 0; + } + + ixQMgrDispatcherLoopGet(&qDispatcherFunc); + + if(ixNpeMhInitialize(IX_NPEMH_NPEINTERRUPTS_YES) != IX_SUCCESS) { + printf("Error initialising NPE Message handler!\n"); + return 0; + } + + if (npe_used[IX_ETH_PORT_1] && npe_exists[IX_ETH_PORT_1] && + ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS) + != IX_SUCCESS) { + printf("Error downloading firmware to NPE-B!\n"); + return 0; + } + + if (npe_used[IX_ETH_PORT_2] && npe_exists[IX_ETH_PORT_2] && + ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS) + != IX_SUCCESS) { + printf("Error downloading firmware to NPE-C!\n"); + return 0; + } + + /* don't need this for U-Boot */ + ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, FALSE); + + if (ixEthAccInit() != IX_ETH_ACC_SUCCESS) { + printf("Error initialising Ethernet access driver!\n"); + return 0; + } + + for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) { + if (!npe_used[i] || !npe_exists[i]) + continue; + if (ixEthAccPortInit(i) != IX_ETH_ACC_SUCCESS) { + printf("Error initialising Ethernet port%d!\n", i); + } + if (ixEthAccTxSchedulingDisciplineSet(i, FIFO_NO_PRIORITY) != IX_ETH_ACC_SUCCESS) { + printf("Error setting scheduling discipline for port %d.\n", i); + } + if (ixEthAccPortRxFrameAppendFCSDisable(i) != IX_ETH_ACC_SUCCESS) { + printf("Error disabling RX FCS for port %d.\n", i); + } + if (ixEthAccPortTxFrameAppendFCSEnable(i) != IX_ETH_ACC_SUCCESS) { + printf("Error enabling TX FCS for port %d.\n", i); + } + } + + return 1; +} + +static int npe_init(struct eth_device *dev, bd_t * bis) +{ + struct npe *p_npe = (struct npe *)dev->priv; + int i; + u16 reg_short; + int speed; + int duplex; + + debug("%s: 1\n", __FUNCTION__); + +#ifdef CONFIG_MII_NPE0_FIXEDLINK + if (0 == p_npe->eth_id) { + speed = CONFIG_MII_NPE0_SPEED; + duplex = CONFIG_MII_NPE0_FULLDUPLEX ? FULL : HALF; + } else +#endif +#ifdef CONFIG_MII_NPE1_FIXEDLINK + if (1 == p_npe->eth_id) { + speed = CONFIG_MII_NPE1_SPEED; + duplex = CONFIG_MII_NPE1_FULLDUPLEX ? FULL : HALF; + } else +#endif + { + miiphy_read(dev->name, p_npe->phy_no, MII_BMSR, ®_short); + + /* + * Wait if PHY is capable of autonegotiation and + * autonegotiation is not complete + */ + if ((reg_short & BMSR_ANEGCAPABLE) && + !(reg_short & BMSR_ANEGCOMPLETE)) { + puts("Waiting for PHY auto negotiation to complete"); + i = 0; + while (!(reg_short & BMSR_ANEGCOMPLETE)) { + /* + * Timeout reached ? + */ + if (i > PHY_AUTONEGOTIATE_TIMEOUT) { + puts(" TIMEOUT !\n"); + break; + } + + if ((i++ % 1000) == 0) { + putc('.'); + miiphy_read(dev->name, p_npe->phy_no, + MII_BMSR, ®_short); + } + udelay(1000); /* 1 ms */ + } + puts(" done\n"); + /* another 500 ms (results in faster booting) */ + udelay(500000); + } + speed = miiphy_speed(dev->name, p_npe->phy_no); + duplex = miiphy_duplex(dev->name, p_npe->phy_no); + } + + if (p_npe->print_speed) { + p_npe->print_speed = 0; + printf ("ENET Speed is %d Mbps - %s duplex connection\n", + (int) speed, (duplex == HALF) ? "HALF" : "FULL"); + } + + npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool); + npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool + + CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1)); + + /* initialize mbuf pool */ + init_rx_mbufs(p_npe); + init_tx_mbufs(p_npe); + + if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_callback, + (u32)p_npe) != IX_ETH_ACC_SUCCESS) { + printf("can't register RX callback!\n"); + return -1; + } + + if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_callback, + (u32)p_npe) != IX_ETH_ACC_SUCCESS) { + printf("can't register TX callback!\n"); + return -1; + } + + npe_set_mac_address(dev); + + if (ixEthAccPortEnable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) { + printf("can't enable port!\n"); + return -1; + } + + p_npe->active = 1; + + return 0; +} + +#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */ +/* Uninitialize CSR library. */ +static void npe_csr_unload(void) +{ + ixEthAccUnload(); + ixEthDBUnload(); + ixNpeMhUnload(); + ixQMgrUnload(); +} + +/* callback which is used by ethAcc to recover RX buffers when stopping */ +static void npe_rx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid) +{ + debug("%s\n", __FUNCTION__); +} + +/* callback which is used by ethAcc to recover TX buffers when stopping */ +static void npe_tx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m) +{ + debug("%s\n", __FUNCTION__); +} +#endif + +static void npe_halt(struct eth_device *dev) +{ + struct npe *p_npe = (struct npe *)dev->priv; + int i; + + debug("%s\n", __FUNCTION__); + + /* Delay to give time for recovery of mbufs */ + for (i = 0; i < 100; i++) { + npe_poll(p_npe->eth_id); + udelay(100); + } + +#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */ + if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_stop_callback, + (u32)p_npe) != IX_ETH_ACC_SUCCESS) { + debug("Error registering rx callback!\n"); + } + + if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_stop_callback, + (u32)p_npe) != IX_ETH_ACC_SUCCESS) { + debug("Error registering tx callback!\n"); + } + + if (ixEthAccPortDisable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) { + debug("npe_stop: Error disabling NPEB!\n"); + } + + /* Delay to give time for recovery of mbufs */ + for (i = 0; i < 100; i++) { + npe_poll(p_npe->eth_id); + udelay(10000); + } + + /* + * For U-Boot only, we are probably launching Linux or other OS that + * needs a clean slate for its NPE library. + */ +#if 0 /* test-only */ + for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) { + if (npe_used[i] && npe_exists[i]) + if (ixNpeDlNpeStopAndReset(__eth_to_npe(i)) != IX_SUCCESS) + printf("Failed to stop and reset NPE B.\n"); + } +#endif + +#endif + p_npe->active = 0; +} + + +static int npe_send(struct eth_device *dev, void *packet, int len) +{ + struct npe *p_npe = (struct npe *)dev->priv; + u8 *dest; + int err; + IX_OSAL_MBUF *m; + + debug("%s\n", __FUNCTION__); + m = mbuf_dequeue(&p_npe->txQHead); + dest = IX_OSAL_MBUF_MDATA(m); + IX_OSAL_MBUF_PKT_LEN(m) = IX_OSAL_MBUF_MLEN(m) = len; + IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = NULL; + + memcpy(dest, (char *)packet, len); + + if ((err = ixEthAccPortTxFrameSubmit(p_npe->eth_id, m, IX_ETH_ACC_TX_DEFAULT_PRIORITY)) + != IX_ETH_ACC_SUCCESS) { + printf("npe_send: Can't submit frame. err[%d]\n", err); + mbuf_enqueue(&p_npe->txQHead, m); + return 0; + } + +#ifdef DEBUG_PRINT_TX_FRAMES + { + u8 *ptr = IX_OSAL_MBUF_MDATA(m); + int i; + + for (i=0; ieth_id); + + return len; +} + +static int npe_rx(struct eth_device *dev) +{ + struct npe *p_npe = (struct npe *)dev->priv; + + debug("%s\n", __FUNCTION__); + npe_poll(p_npe->eth_id); + + debug("%s: rx_write=%d rx_read=%d\n", __FUNCTION__, p_npe->rx_write, p_npe->rx_read); + while (p_npe->rx_write != p_npe->rx_read) { + debug("Reading message #%d\n", p_npe->rx_read); + NetReceive(NetRxPackets[p_npe->rx_read], p_npe->rx_len[p_npe->rx_read]); + p_npe->rx_read++; + if (p_npe->rx_read == PKTBUFSRX) + p_npe->rx_read = 0; + } + + return 0; +} + +int npe_initialize(bd_t * bis) +{ + static int virgin = 0; + struct eth_device *dev; + int eth_num = 0; + struct npe *p_npe = NULL; + uchar enetaddr[6]; + + for (eth_num = 0; eth_num < CONFIG_SYS_NPE_NUMS; eth_num++) { + + /* See if we can actually bring up the interface, otherwise, skip it */ +#ifdef CONFIG_HAS_ETH1 + if (eth_num == 1) { + if (!eth_getenv_enetaddr("eth1addr", enetaddr)) + continue; + } else +#endif + if (!eth_getenv_enetaddr("ethaddr", enetaddr)) + continue; + + /* Allocate device structure */ + dev = (struct eth_device *)malloc(sizeof(*dev)); + if (dev == NULL) { + printf ("%s: Cannot allocate eth_device %d\n", __FUNCTION__, eth_num); + return -1; + } + memset(dev, 0, sizeof(*dev)); + + /* Allocate our private use data */ + p_npe = (struct npe *)malloc(sizeof(struct npe)); + if (p_npe == NULL) { + printf("%s: Cannot allocate private hw data for eth_device %d", + __FUNCTION__, eth_num); + free(dev); + return -1; + } + memset(p_npe, 0, sizeof(struct npe)); + + p_npe->eth_id = eth_num; + memcpy(dev->enetaddr, enetaddr, 6); +#ifdef CONFIG_HAS_ETH1 + if (eth_num == 1) + p_npe->phy_no = CONFIG_PHY1_ADDR; + else +#endif + p_npe->phy_no = CONFIG_PHY_ADDR; + + sprintf(dev->name, "NPE%d", eth_num); + dev->priv = (void *)p_npe; + dev->init = npe_init; + dev->halt = npe_halt; + dev->send = npe_send; + dev->recv = npe_rx; + + p_npe->print_speed = 1; + + if (0 == virgin) { + virgin = 1; + + if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X) { + switch (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) { + case IX_FEATURE_CTRL_SILICON_TYPE_B0: + default: /* newer than B0 */ + /* + * If it is B0 or newer Silicon, we + * only enable port when its + * corresponding Eth Coprocessor is + * available. + */ + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == + IX_FEATURE_CTRL_COMPONENT_ENABLED) + npe_exists[IX_ETH_PORT_1] = TRUE; + + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == + IX_FEATURE_CTRL_COMPONENT_ENABLED) + npe_exists[IX_ETH_PORT_2] = TRUE; + break; + case IX_FEATURE_CTRL_SILICON_TYPE_A0: + /* + * If it is A0 Silicon, we enable both as both Eth Coprocessors + * are available. + */ + npe_exists[IX_ETH_PORT_1] = TRUE; + npe_exists[IX_ETH_PORT_2] = TRUE; + break; + } + } else if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X) { + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) == + IX_FEATURE_CTRL_COMPONENT_ENABLED) + npe_exists[IX_ETH_PORT_1] = TRUE; + + if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) == + IX_FEATURE_CTRL_COMPONENT_ENABLED) + npe_exists[IX_ETH_PORT_2] = TRUE; + } + + npe_used[IX_ETH_PORT_1] = 1; + npe_used[IX_ETH_PORT_2] = 1; + + npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool); + npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool + + CONFIG_SYS_CACHELINE_SIZE - 1) + & ~(CONFIG_SYS_CACHELINE_SIZE - 1)); + + if (!npe_csr_load()) + return 0; + } + + eth_register(dev); + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + miiphy_register(dev->name, npe_miiphy_read, npe_miiphy_write); +#endif + + } /* end for each supported device */ + + return 1; +} -- cgit v1.1 From 7fd70820248b17aa8b574c2823f73d538c31958f Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 28 Jun 2012 21:37:57 +0000 Subject: net: emaclite: Support OF initialization Support new CONFIG_OF_CONTROL option where device probing is done based on device tree description. Signed-off-by: Michal Simek CC: Joe Hershberger --- drivers/net/xilinx_emaclite.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index d5bd737..d890d60 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -28,6 +28,9 @@ #include #include #include +#include + +DECLARE_GLOBAL_DATA_PTR; #undef DEBUG @@ -375,3 +378,30 @@ int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr, return 1; } + +#ifdef CONFIG_OF_CONTROL +int xilinx_emaclite_init(bd_t *bis) +{ + int offset = 0; + u32 ret = 0; + u32 reg; + + do { + offset = fdt_node_offset_by_compatible(gd->fdt_blob, offset, + "xlnx,xps-ethernetlite-1.00.a"); + if (offset != -1) { + reg = fdtdec_get_addr(gd->fdt_blob, offset, "reg"); + if (reg != FDT_ADDR_T_NONE) { + u32 rxpp = fdtdec_get_int(gd->fdt_blob, offset, + "xlnx,rx-ping-pong", 0); + u32 txpp = fdtdec_get_int(gd->fdt_blob, offset, + "xlnx,tx-ping-pong", 0); + ret |= xilinx_emaclite_initialize(bis, reg, + txpp, rxpp); + } + } + } while (offset != -1); + + return ret; +} +#endif -- cgit v1.1 From 905b3b00a177a22944ee4b9e505e9395f23e58ed Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 27 Jul 2012 09:50:07 +0000 Subject: dm: net: Fixup the armada100 FEC driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply the following questionable adjustment to silence GCC. armada100_fec.c: In function ‘armdfec_send’: armada100_fec.c:589:2: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] Signed-off-by: Marek Vasut Cc: Joe Hershberger Acked-by: Prafulla Wadaskar --- drivers/net/armada100_fec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/armada100_fec.c b/drivers/net/armada100_fec.c index d318a36..ed7cf20 100644 --- a/drivers/net/armada100_fec.c +++ b/drivers/net/armada100_fec.c @@ -565,7 +565,7 @@ static int armdfec_send(struct eth_device *dev, void *dataptr, int datasize) struct tx_desc *p_txdesc = darmdfec->p_txdesc; void *p = (void *)dataptr; int retry = PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS; - u32 cmd_sts; + u32 cmd_sts, temp; /* Copy buffer if it's misaligned */ if ((u32)dataptr & 0x07) { @@ -586,7 +586,8 @@ static int armdfec_send(struct eth_device *dev, void *dataptr, int datasize) p_txdesc->byte_cnt = datasize; /* Apply send command using high priority TX queue */ - writel((u32)p_txdesc, ®s->txcdp[TXQ]); + temp = (u32)®s->txcdp[TXQ]; + writel((u32)p_txdesc, temp); writel(SDMA_CMD_TXDL | SDMA_CMD_TXDH | SDMA_CMD_ERD, ®s->sdma_cmd); /* -- cgit v1.1 From dcd5a593f59b58da4875e3e78d7c74501bc319c4 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 2 Aug 2012 22:08:40 +0000 Subject: net: sh_eth: Add support R8A7740 of rmobile (arm core) R8A7740 of rmobile has ethernet device, and this is same IP of sh-ether. This support R8A7740 of rmobile. Signed-off-by: Hideyuki Sano Signed-off-by: Nobuhiro Iwamatsu --- drivers/net/sh_eth.c | 2 +- drivers/net/sh_eth.h | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 09af860..2d9cc32 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -394,7 +394,7 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) sh_eth_write(eth, TPAUSER_TPAUSE, TPAUSER); #endif -#if defined(CONFIG_CPU_SH7734) +#if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740) sh_eth_write(eth, CONFIG_SH_ETHER_SH7734_MII, RMII_MII); #endif /* Configure phy */ diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 3703c55..61d2df9 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -1,8 +1,8 @@ /* * sh_eth.h - Driver for Renesas SuperH ethernet controler. * - * Copyright (C) 2008, 2011 Renesas Solutions Corp. - * Copyright (c) 2008, 2011 Nobuhiro Iwamatsu + * Copyright (C) 2008 - 2012 Renesas Solutions Corp. + * Copyright (c) 2008 - 2012 Nobuhiro Iwamatsu * Copyright (c) 2007 Carlos Munoz * * This program is free software; you can redistribute it and/or modify @@ -25,6 +25,7 @@ #define SHETHER_NAME "sh_eth" +#if defined(CONFIG_SH) /* Malloc returns addresses in the P1 area (cacheable). However we need to use area P2 (non-cacheable) */ #define ADDR_TO_P2(addr) ((((int)(addr) & ~0xe0000000) | 0xa0000000)) @@ -35,6 +36,12 @@ #else #define ADDR_TO_PHY(addr) ((int)(addr) & ~0xe0000000) #endif +#elif defined(CONFIG_ARM) +#define inl readl +#define outl writel +#define ADDR_TO_PHY(addr) ((int)(addr)) +#define ADDR_TO_P2(addr) (addr) +#endif /* defined(CONFIG_SH) */ /* Number of supported ports */ #define MAX_PORT_NUM 2 @@ -292,6 +299,9 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { #elif defined(CONFIG_CPU_SH7724) #define SH_ETH_TYPE_ETHER #define BASE_IO_ADDR 0xA4600000 +#elif defined(CONFIG_R8A7740) +#define SH_ETH_TYPE_GETHER +#define BASE_IO_ADDR 0xE9A00000 #endif /* -- cgit v1.1 From 2c8fe5120f8da013cbd789be2f10cce880972836 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 31 Jul 2012 06:09:17 +0000 Subject: net: Make the netconsole buffer size configurable Allow a board to configure a larger buffer for netconsole, but leave the default. Signed-off-by: Joe Hershberger Cc: Mike Frysinger Acked-by: Mike Frysinger --- doc/README.NetConsole | 2 ++ drivers/net/netconsole.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/README.NetConsole b/doc/README.NetConsole index 070e86a..af7fc60 100644 --- a/doc/README.NetConsole +++ b/doc/README.NetConsole @@ -6,6 +6,8 @@ serial and network input/output devices by adjusting the 'stdin' and set either of these variables to "nc". Input and output can be switched independently. +CONFIG_NETCONSOLE_BUFFER_SIZE - Override the default buffer size + We use an environment variable 'ncip' to set the IP address and the port of the destination. The format is :. If is omitted, the value of 6666 is used. If the env var doesn't exist, the diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 86f5301..8fcf31c 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -28,7 +28,11 @@ DECLARE_GLOBAL_DATA_PTR; -static char input_buffer[512]; +#ifndef CONFIG_NETCONSOLE_BUFFER_SIZE +#define CONFIG_NETCONSOLE_BUFFER_SIZE 512 +#endif + +static char input_buffer[CONFIG_NETCONSOLE_BUFFER_SIZE]; static int input_size; /* char count in input buffer */ static int input_offset; /* offset to valid chars in input buffer */ static int input_recursion; @@ -214,7 +218,7 @@ static void nc_puts(const char *s) len = strlen(s); while (len) { - int send_len = min(len, 512); + int send_len = min(len, sizeof(input_buffer)); nc_send_packet(s, send_len); len -= send_len; s += send_len; -- cgit v1.1 From f8be7d659c45720edb91503d2a480fc198e7ee9d Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 3 Aug 2012 10:59:08 +0000 Subject: net: Improve the speed of netconsole Previously u-boot would initialize the network interface for every network operation and then shut it down again. This makes sense for most operations where the network in not known to be needed soon after the operation is complete. In the case of netconsole, it will use the network for every interaction with the shell or every printf. This means that the network is being reinitialized very often. On many devices, this intialization is very slow. This patch checks for consecutive netconsole actions and leaves the ethernet hardware initialized between them. It will still behave the same old way for all other network operations and any time another network operation happens between netconsole operations. Signed-off-by: Joe Hershberger Cc: Stefano Babic Acked-by: Stefano Babic --- common/cmd_bootm.c | 17 +++++++++++++++++ drivers/net/netconsole.c | 22 ++++++++++++++++++---- include/net.h | 42 +++++++++++++++++++++++++++++++++++++++++- net/eth.c | 8 ++------ net/net.c | 26 ++++++++++++++++++++------ 5 files changed, 98 insertions(+), 17 deletions(-) diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 45e726a..83fa5d7 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -564,6 +564,13 @@ int do_bootm_subcommand(cmd_tbl_t *cmdtp, int flag, int argc, break; case BOOTM_STATE_OS_GO: disable_interrupts(); +#ifdef CONFIG_NETCONSOLE + /* + * Stop the ethernet stack if NetConsole could have + * left it up + */ + eth_halt(); +#endif arch_preboot_os(); boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images); break; @@ -622,6 +629,11 @@ int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) */ iflag = disable_interrupts(); +#ifdef CONFIG_NETCONSOLE + /* Stop the ethernet stack if NetConsole could have left it up */ + eth_halt(); +#endif + #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the @@ -1599,6 +1611,11 @@ static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) */ disable_interrupts(); +#ifdef CONFIG_NETCONSOLE + /* Stop the ethernet stack if NetConsole could have left it up */ + eth_halt(); +#endif + #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 8fcf31c..da82aa9 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -44,6 +44,11 @@ static short nc_out_port; /* target output port */ static short nc_in_port; /* source input port */ static const char *output_packet; /* used by first send udp */ static int output_packet_len; +/* + * Start with a default last protocol. + * We are only interested in NETCONS or not. + */ +enum proto_t net_loop_last_protocol = BOOTP; static void nc_wait_arp_handler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, @@ -136,8 +141,13 @@ static void nc_send_packet(const char *buf, int len) } if (eth->state != ETH_STATE_ACTIVE) { - if (eth_init(gd->bd) < 0) - return; + if (eth_is_on_demand_init()) { + if (eth_init(gd->bd) < 0) + return; + eth_set_last_protocol(NETCONS); + } else + eth_init_state_only(gd->bd); + inited = 1; } pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE; @@ -146,8 +156,12 @@ static void nc_send_packet(const char *buf, int len) ip = nc_ip; NetSendUDPPacket(ether, ip, nc_out_port, nc_in_port, len); - if (inited) - eth_halt(); + if (inited) { + if (eth_is_on_demand_init()) + eth_halt(); + else + eth_halt_state_only(); + } } static int nc_start(void) diff --git a/include/net.h b/include/net.h index 6d2d6cd..e193b7b 100644 --- a/include/net.h +++ b/include/net.h @@ -102,7 +102,14 @@ extern int eth_register(struct eth_device* dev);/* Register network device */ extern int eth_unregister(struct eth_device *dev);/* Remove network device */ extern void eth_try_another(int first_restart); /* Change the device */ extern void eth_set_current(void); /* set nterface to ethcur var */ -extern struct eth_device *eth_get_dev(void); /* get the current device MAC */ +/* get the current device MAC */ +static inline __attribute__((always_inline)) +struct eth_device *eth_get_dev(void) +{ + extern struct eth_device *eth_current; + + return eth_current; +} extern struct eth_device *eth_get_dev_by_name(const char *devname); extern struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */ extern int eth_get_dev_index(void); /* get the device index */ @@ -151,6 +158,19 @@ extern int eth_rx(void); /* Check for received packets */ extern void eth_halt(void); /* stop SCC */ extern char *eth_get_name(void); /* get name of current device */ +/* Set active state */ +static inline __attribute__((always_inline)) int eth_init_state_only(bd_t *bis) +{ + eth_get_dev()->state = ETH_STATE_ACTIVE; + + return 0; +} +/* Set passive state */ +static inline __attribute__((always_inline)) void eth_halt_state_only(void) +{ + eth_get_dev()->state = ETH_STATE_PASSIVE; +} + /* * Set the hardware address for an ethernet interface based on 'eth%daddr' * environment variable (or just 'ethaddr' if eth_number is 0). @@ -532,6 +552,26 @@ void NcStart(void); int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len); #endif +static inline __attribute__((always_inline)) int eth_is_on_demand_init(void) +{ +#ifdef CONFIG_NETCONSOLE + extern enum proto_t net_loop_last_protocol; + + return net_loop_last_protocol != NETCONS; +#else + return 1; +#endif +} + +static inline void eth_set_last_protocol(int protocol) +{ +#ifdef CONFIG_NETCONSOLE + extern enum proto_t net_loop_last_protocol; + + net_loop_last_protocol = protocol; +#endif +} + /* * Check if autoload is enabled. If so, use either NFS or TFTP to download * the boot file. diff --git a/net/eth.c b/net/eth.c index bb4d95b..49458c8 100644 --- a/net/eth.c +++ b/net/eth.c @@ -121,12 +121,8 @@ static struct { static unsigned int eth_rcv_current, eth_rcv_last; #endif -static struct eth_device *eth_devices, *eth_current; - -struct eth_device *eth_get_dev(void) -{ - return eth_current; -} +static struct eth_device *eth_devices; +struct eth_device *eth_current; struct eth_device *eth_get_dev_by_name(const char *devname) { diff --git a/net/net.c b/net/net.c index f440434..a89946e 100644 --- a/net/net.c +++ b/net/net.c @@ -315,12 +315,15 @@ int NetLoop(enum proto_t protocol) bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start"); net_init(); - eth_halt(); - eth_set_current(); - if (eth_init(bd) < 0) { + if (eth_is_on_demand_init() || protocol != NETCONS) { eth_halt(); - return -1; - } + eth_set_current(); + if (eth_init(bd) < 0) { + eth_halt(); + return -1; + } + } else + eth_init_state_only(bd); restart: net_set_state(NETLOOP_CONTINUE); @@ -460,6 +463,9 @@ restart: net_cleanup_loop(); eth_halt(); + /* Invalidate the last protocol */ + eth_set_last_protocol(BOOTP); + puts("\nAbort\n"); /* include a debug print as well incase the debug messages are directed to stderr */ @@ -517,13 +523,21 @@ restart: sprintf(buf, "%lX", (unsigned long)load_addr); setenv("fileaddr", buf); } - eth_halt(); + if (protocol != NETCONS) + eth_halt(); + else + eth_halt_state_only(); + + eth_set_last_protocol(protocol); + ret = NetBootFileXferSize; debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n"); goto done; case NETLOOP_FAIL: net_cleanup_loop(); + /* Invalidate the last protocol */ + eth_set_last_protocol(BOOTP); debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n"); goto done; -- cgit v1.1 From e827fec2b24d4412eabed3cf0080a08a0a7d148c Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 18 Sep 2012 10:01:31 +0000 Subject: net: Allow netconsole settings to change after nc_start Refresh the netconsole settings from the env before each packet instead of only on netconsole init. Signed-off-by: Joe Hershberger --- drivers/net/netconsole.c | 96 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index da82aa9..63ce73c 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -69,8 +69,69 @@ static void nc_timeout(void) net_set_state(NETLOOP_SUCCESS); } +static int is_broadcast(IPaddr_t ip) +{ + static IPaddr_t netmask; + static IPaddr_t our_ip; + static int env_changed_id; + int env_id = get_env_id(); + + /* update only when the environment has changed */ + if (env_changed_id != env_id) { + netmask = getenv_IPaddr("netmask"); + our_ip = getenv_IPaddr("ipaddr"); + + env_changed_id = env_id; + } + + return (ip == ~0 || /* 255.255.255.255 */ + ((netmask & our_ip) == (netmask & ip) && /* on the same net */ + (netmask | ip) == ~0)); /* broadcast to our net */ +} + +static int refresh_settings_from_env(void) +{ + const char *p; + static int env_changed_id; + int env_id = get_env_id(); + + /* update only when the environment has changed */ + if (env_changed_id != env_id) { + if (getenv("ncip")) { + nc_ip = getenv_IPaddr("ncip"); + if (!nc_ip) + return -1; /* ncip is 0.0.0.0 */ + p = strchr(getenv("ncip"), ':'); + if (p != NULL) { + nc_out_port = simple_strtoul(p + 1, NULL, 10); + nc_in_port = nc_out_port; + } + } else + nc_ip = ~0; /* ncip is not set, so broadcast */ + + p = getenv("ncoutport"); + if (p != NULL) + nc_out_port = simple_strtoul(p, NULL, 10); + p = getenv("ncinport"); + if (p != NULL) + nc_in_port = simple_strtoul(p, NULL, 10); + + if (is_broadcast(nc_ip)) + /* broadcast MAC address */ + memset(nc_ether, 0xff, sizeof(nc_ether)); + else + /* force arp request */ + memset(nc_ether, 0, sizeof(nc_ether)); + } + return 0; +} + +/** + * Called from NetLoop in net/net.c before each packet + */ void NcStart(void) { + refresh_settings_from_env(); if (!output_packet_len || memcmp(nc_ether, NetEtherNullAddr, 6)) { /* going to check for input packet */ net_set_udp_handler(nc_handler); @@ -166,41 +227,14 @@ static void nc_send_packet(const char *buf, int len) static int nc_start(void) { - int netmask, our_ip; - char *p; + int retval; nc_out_port = 6666; /* default port */ nc_in_port = nc_out_port; - if (getenv("ncip")) { - - nc_ip = getenv_IPaddr("ncip"); - if (!nc_ip) - return -1; /* ncip is 0.0.0.0 */ - p = strchr(getenv("ncip"), ':'); - if (p != NULL) { - nc_out_port = simple_strtoul(p + 1, NULL, 10); - nc_in_port = nc_out_port; - } - } else - nc_ip = ~0; /* ncip is not set, so broadcast */ - - p = getenv("ncoutport"); - if (p != NULL) - nc_out_port = simple_strtoul(p, NULL, 10); - p = getenv("ncinport"); - if (p != NULL) - nc_in_port = simple_strtoul(p, NULL, 10); - - our_ip = getenv_IPaddr("ipaddr"); - netmask = getenv_IPaddr("netmask"); - - if (nc_ip == ~0 || /* 255.255.255.255 */ - ((netmask & our_ip) == (netmask & nc_ip) && /* on the same net */ - (netmask | nc_ip) == ~0)) /* broadcast to our net */ - memset(nc_ether, 0xff, sizeof(nc_ether)); - else - memset(nc_ether, 0, sizeof(nc_ether)); /* force arp request */ + retval = refresh_settings_from_env(); + if (retval != 0) + return retval; /* * Initialize the static IP settings and buffer pointers -- cgit v1.1 From 8a0eccb1056b313b45ab62e3aac400f339aa71b4 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 18 Sep 2012 10:01:32 +0000 Subject: net: Filter incoming netconsole packets by IP Check the incoming packets' source IP address... if ncip isn't set to a broadcast address, only listen to the client at ncip. Signed-off-by: Joe Hershberger --- drivers/net/netconsole.c | 8 ++++++-- include/net.h | 3 ++- net/net.c | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 63ce73c..dd7032a 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -147,13 +147,17 @@ void NcStart(void) } } -int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len) +int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, + unsigned src_port, unsigned len) { int end, chunk; - if (dest != nc_in_port || !len) + if (dest_port != nc_in_port || !len) return 0; /* not for us */ + if (src_ip != nc_ip && !is_broadcast(nc_ip)) + return 0; /* not from our client */ + debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt); if (input_size == sizeof(input_buffer)) diff --git a/include/net.h b/include/net.h index e193b7b..3539336 100644 --- a/include/net.h +++ b/include/net.h @@ -549,7 +549,8 @@ extern void NetReceive(uchar *, int); #ifdef CONFIG_NETCONSOLE void NcStart(void); -int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len); +int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port, + unsigned src_port, unsigned len); #endif static inline __attribute__((always_inline)) int eth_is_on_demand_init(void) diff --git a/net/net.c b/net/net.c index a89946e..809fb14 100644 --- a/net/net.c +++ b/net/net.c @@ -1161,6 +1161,7 @@ NetReceive(uchar *inpkt, int len) #ifdef CONFIG_NETCONSOLE nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE, + ntohl(ip->ip_src), ntohs(ip->udp_dst), ntohs(ip->udp_src), ntohs(ip->udp_len) - UDP_HDR_SIZE); -- cgit v1.1 From d23019f3d65c2746d8aecf5ab2c93591f00cb965 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Sat, 22 Sep 2012 06:55:53 +0000 Subject: common/lcd: fix build breakage for at91sam9x5ek and trats boards Commit 203c37b8c5556aad1901ce4954792afd718c7d42 (common lcd: simplify core functions) and commit bfdcc65e1163b4891643c2a670570c478b9af2a4 (common lcd: simplify lcd_display_bitmap) caused build breakage for at91sam9x5ek board configurations and for trats board. Fix these build errors. Signed-off-by: Anatolij Gustschin Acked-by: Nikita Kiryanov --- common/lcd.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/common/lcd.c b/common/lcd.c index fcc09ac..b6be800 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -509,8 +509,14 @@ static inline ushort *configuration_get_cmap(void) return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]); #elif defined(CONFIG_ATMEL_LCD) return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); +#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) + return panel_info.cmap; #else - return (ushort *)panel_info.cmap; +#if defined(CONFIG_LCD_LOGO) + return bmp_logo_palette; +#else + return NULL; +#endif #endif } @@ -636,10 +642,10 @@ static void splash_align_axis(int *axis, unsigned long panel_size, } #endif -#if defined CONFIG_CPU_PXA || defined(CONFIG_ATMEL_LCD) -#define FB_PUT_BYTE(fb, from) *(fb)++ = *(from)++ -#elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200) +#if defined(CONFIG_MPC823) || defined(CONFIG_MCC200) #define FB_PUT_BYTE(fb, from) *(fb)++ = (255 - *(from)++) +#else +#define FB_PUT_BYTE(fb, from) *(fb)++ = *(from)++ #endif #if defined(CONFIG_BMP_16BPP) -- cgit v1.1 From 59d63f7d2cad78382574beea01c85cbca96925df Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sat, 1 Sep 2012 16:27:56 +0000 Subject: ARM: arm1176: Define arch_cpu_init() at the SoC level Commit 86c6326 "ARM: arm1176: enable instruction cache in arch_cpu_init()" defined arch_cpu_init() in a file that is shared across all arm1176 SoCs. tnetv107x already implemented this function, which caused linking to break. Move the new conflicting arch_cpu_init() into arm1176/bcm2835/init.c so that it doesn't conflict; grep indicates this function is usually defined at the SoC-level, not the CPU-level, at least for ARM. Signed-off-by: Stephen Warren Acked-by: Marek Vasut --- arch/arm/cpu/arm1176/bcm2835/Makefile | 2 +- arch/arm/cpu/arm1176/bcm2835/init.c | 24 ++++++++++++++++++++++++ arch/arm/cpu/arm1176/cpu.c | 7 ------- 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 arch/arm/cpu/arm1176/bcm2835/init.c diff --git a/arch/arm/cpu/arm1176/bcm2835/Makefile b/arch/arm/cpu/arm1176/bcm2835/Makefile index 4ea6d6b..95da6a8 100644 --- a/arch/arm/cpu/arm1176/bcm2835/Makefile +++ b/arch/arm/cpu/arm1176/bcm2835/Makefile @@ -17,7 +17,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o -COBJS := reset.o timer.o +COBJS := init.o reset.o timer.o SRCS := $(SOBJS:.o=.c) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/arch/arm/cpu/arm1176/bcm2835/init.c b/arch/arm/cpu/arm1176/bcm2835/init.c new file mode 100644 index 0000000..e90d3bb --- /dev/null +++ b/arch/arm/cpu/arm1176/bcm2835/init.c @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2012 Stephen Warren + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +int arch_cpu_init(void) +{ + icache_enable(); + + return 0; +} diff --git a/arch/arm/cpu/arm1176/cpu.c b/arch/arm/cpu/arm1176/cpu.c index 532a90b..c0fd114 100644 --- a/arch/arm/cpu/arm1176/cpu.c +++ b/arch/arm/cpu/arm1176/cpu.c @@ -65,10 +65,3 @@ static void cache_flush (void) /* mem barrier to sync things */ asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0)); } - -int arch_cpu_init(void) -{ - icache_enable(); - - return 0; -} -- cgit v1.1 From cce5d210e68cab42944be74b8fe0c071b57f6949 Mon Sep 17 00:00:00 2001 From: Allen Martin Date: Wed, 29 Aug 2012 11:08:59 +0000 Subject: MAKEALL: fix per arch board lists The LIST_arm rule included the Atmel boards twice (by virtue of including both LIST_at91 and LIST_ARM9) and was missing all the arm720t, arm946es, and arm1176 boards. Change this list to use boards_by_arch() which is less error prone. After this change "./MAKEALL arm" and "./MAKEALL -a arm" build the same boards. Also fix up some missing and duplicate boards to arm, mips, and m68k. Signed-off-by: Allen Martin Acked-by: Tom Rini --- MAKEALL | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/MAKEALL b/MAKEALL index eb7dd02..806f21f 100755 --- a/MAKEALL +++ b/MAKEALL @@ -334,18 +334,27 @@ LIST_ppc=" \ LIST_SA="$(boards_by_cpu sa1100)" ######################################################################### +## ARM7 Systems +######################################################################### + +LIST_ARM7="$(boards_by_cpu arm720t)" + +######################################################################### ## ARM9 Systems ######################################################################### LIST_ARM9="$(boards_by_cpu arm920t) \ $(boards_by_cpu arm926ejs) \ $(boards_by_cpu arm925t) \ + $(boards_by_cpu arm946es) \ " ######################################################################### ## ARM11 Systems ######################################################################### -LIST_ARM11="$(boards_by_cpu arm1136)" +LIST_ARM11="$(boards_by_cpu arm1136) \ + $(boards_by_cpu arm1176) \ +" ######################################################################### ## ARMV7 Systems @@ -371,16 +380,7 @@ LIST_ixp="$(boards_by_cpu ixp)" ## ARM groups ######################################################################### -LIST_arm=" \ - ${LIST_SA} \ - ${LIST_ARM9} \ - ${LIST_ARM10} \ - ${LIST_ARM11} \ - ${LIST_ARMV7} \ - ${LIST_at91} \ - ${LIST_pxa} \ - ${LIST_ixp} \ -" +LIST_arm="$(boards_by_arch arm)" ######################################################################### ## MIPS Systems (default = big endian) @@ -388,6 +388,9 @@ LIST_arm=" \ LIST_mips4kc=" \ incaip \ + incaip_100MHz \ + incaip_133MHz \ + incaip_150MHz \ qemu_mips \ vct_platinum \ vct_platinum_small \ @@ -461,14 +464,7 @@ LIST_microblaze="$(boards_by_arch microblaze)" ## ColdFire Systems ######################################################################### -LIST_m68k="$(boards_by_arch m68k) - EB+MCF-EV123 \ - EB+MCF-EV123_internal \ - M52277EVB \ - M5235EVB \ - M54451EVB \ - M54455EVB \ -" +LIST_m68k="$(boards_by_arch m68k)" LIST_coldfire=${LIST_m68k} ######################################################################### -- cgit v1.1 From 2f5016462710050ce6c052bbc87cba115f53a51f Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 21 Sep 2012 12:46:54 +0000 Subject: disk: make get_partition_info() always available to disk.c Now that get_device_and_partition() always calls get_partition_info() when disk.c is compiled, we must always compile the function, rather than ifdef it away. The implementation must be conditional based on CONFIG_CMD_* etc., since that's what e.g. part_dos.c uses to ifdef out get_partition_info_dos(); CONFIG_DOS_PARTITION can be enabled even without those commands being enabled. Technically, this change is required before Rob's "disk/part: introduce get_device_and_partition" patch. However, at least when the compiler optimizer is turned on, it isn't required before then in practice, since get_device_and_partition() calls get_dev(), which is stubbed out in disk.c under exactly the same conditions that get_partition_info() is not compiled, and hence the compiler never generates code for the call to the missing function. However, in my later patch "disk: get_device_and_partition() "auto" partition and cleanup", the optimizer doesn't succeed at this, and may attempt to reference the undefined function. Signed-off-by: Stephen Warren --- disk/part.c | 118 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 63 insertions(+), 55 deletions(-) diff --git a/disk/part.c b/disk/part.c index 76f3939..f659cc3 100644 --- a/disk/part.c +++ b/disk/part.c @@ -291,61 +291,6 @@ void init_part (block_dev_desc_t * dev_desc) } -int get_partition_info (block_dev_desc_t *dev_desc, int part - , disk_partition_t *info) -{ - switch (dev_desc->part_type) { -#ifdef CONFIG_MAC_PARTITION - case PART_TYPE_MAC: - if (get_partition_info_mac(dev_desc,part,info) == 0) { - PRINTF ("## Valid MAC partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_DOS_PARTITION - case PART_TYPE_DOS: - if (get_partition_info_dos(dev_desc,part,info) == 0) { - PRINTF ("## Valid DOS partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_ISO_PARTITION - case PART_TYPE_ISO: - if (get_partition_info_iso(dev_desc,part,info) == 0) { - PRINTF ("## Valid ISO boot partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_AMIGA_PARTITION - case PART_TYPE_AMIGA: - if (get_partition_info_amiga(dev_desc, part, info) == 0) - { - PRINTF ("## Valid Amiga partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_EFI_PARTITION - case PART_TYPE_EFI: - if (get_partition_info_efi(dev_desc,part,info) == 0) { - PRINTF ("## Valid EFI partition found ##\n"); - return (0); - } - break; -#endif - default: - break; - } - return (-1); -} - static void print_part_header (const char *type, block_dev_desc_t * dev_desc) { puts ("\nPartition Map for "); @@ -433,3 +378,66 @@ void print_part (block_dev_desc_t * dev_desc) #endif #endif + +int get_partition_info(block_dev_desc_t *dev_desc, int part + , disk_partition_t *info) +{ +#if defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ + defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_CMD_USB) || \ + defined(CONFIG_MMC) || \ + defined(CONFIG_SYSTEMACE) + + switch (dev_desc->part_type) { +#ifdef CONFIG_MAC_PARTITION + case PART_TYPE_MAC: + if (get_partition_info_mac(dev_desc, part, info) == 0) { + PRINTF("## Valid MAC partition found ##\n"); + return 0; + } + break; +#endif + +#ifdef CONFIG_DOS_PARTITION + case PART_TYPE_DOS: + if (get_partition_info_dos(dev_desc, part, info) == 0) { + PRINTF("## Valid DOS partition found ##\n"); + return 0; + } + break; +#endif + +#ifdef CONFIG_ISO_PARTITION + case PART_TYPE_ISO: + if (get_partition_info_iso(dev_desc, part, info) == 0) { + PRINTF("## Valid ISO boot partition found ##\n"); + return 0; + } + break; +#endif + +#ifdef CONFIG_AMIGA_PARTITION + case PART_TYPE_AMIGA: + if (get_partition_info_amiga(dev_desc, part, info) == 0) { + PRINTF("## Valid Amiga partition found ##\n"); + return 0; + } + break; +#endif + +#ifdef CONFIG_EFI_PARTITION + case PART_TYPE_EFI: + if (get_partition_info_efi(dev_desc, part, info) == 0) { + PRINTF("## Valid EFI partition found ##\n"); + return 0; + } + break; +#endif + default: + break; + } +#endif + + return -1; +} -- cgit v1.1 From 7405a133101e009c760b98dd4dbcdc49b82ec3b3 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 21 Sep 2012 04:02:30 +0000 Subject: combine block device load commands into common function All the raw block load commands duplicate the same code. Starting with the ide version as it has progress updates convert ide, usb, and scsi boot commands to all use a common version. Signed-off-by: Rob Herring --- common/Makefile | 1 + common/cmd_disk.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/cmd_ide.c | 151 +------------------------------------------- common/cmd_scsi.c | 123 +----------------------------------- common/cmd_usb.c | 138 +--------------------------------------- include/command.h | 4 ++ 6 files changed, 191 insertions(+), 409 deletions(-) create mode 100644 common/cmd_disk.c diff --git a/common/Makefile b/common/Makefile index 22e8a6f..482795e 100644 --- a/common/Makefile +++ b/common/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_SYS_HUSH_PARSER) += hush.o COBJS-y += s_record.o COBJS-$(CONFIG_SERIAL_MULTI) += serial.o COBJS-y += xyzModem.o +COBJS-y += cmd_disk.o # core command COBJS-y += cmd_boot.o diff --git a/common/cmd_disk.c b/common/cmd_disk.c new file mode 100644 index 0000000..e73fc4e --- /dev/null +++ b/common/cmd_disk.c @@ -0,0 +1,183 @@ +/* + * (C) Copyright 2000-2011 + * 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 +#include + +int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, + char *const argv[]) +{ + char *boot_device = NULL; + char *ep; + int dev, part = 0; + ulong addr, cnt; + disk_partition_t info; + image_header_t *hdr; + block_dev_desc_t *dev_desc; + +#if defined(CONFIG_FIT) + const void *fit_hdr = NULL; +#endif + + bootstage_mark(BOOTSTAGE_ID_IDE_START); + switch (argc) { + case 1: + addr = CONFIG_SYS_LOAD_ADDR; + boot_device = getenv("bootdevice"); + break; + case 2: + addr = simple_strtoul(argv[1], NULL, 16); + boot_device = getenv("bootdevice"); + break; + case 3: + addr = simple_strtoul(argv[1], NULL, 16); + boot_device = argv[2]; + break; + default: + bootstage_error(BOOTSTAGE_ID_IDE_ADDR); + return CMD_RET_USAGE; + } + bootstage_mark(BOOTSTAGE_ID_IDE_ADDR); + + if (!boot_device) { + puts("\n** No boot device **\n"); + bootstage_error(BOOTSTAGE_ID_IDE_BOOT_DEVICE); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE); + + dev = simple_strtoul(boot_device, &ep, 16); + + dev_desc = get_dev(intf, dev); + if (dev_desc->type == DEV_TYPE_UNKNOWN) { + printf("\n** Device %d not available\n", dev); + bootstage_error(BOOTSTAGE_ID_IDE_TYPE); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_TYPE); + + if (*ep) { + if (*ep != ':') { + puts("\n** Invalid boot device, use `dev[:part]' **\n"); + bootstage_error(BOOTSTAGE_ID_IDE_PART); + return 1; + } + part = simple_strtoul(++ep, NULL, 16); + } + bootstage_mark(BOOTSTAGE_ID_IDE_PART); + + if (get_partition_info(dev_desc, part, &info)) { + bootstage_error(BOOTSTAGE_ID_IDE_PART_INFO); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_PART_INFO); + + if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) + && + (strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0) + ) { + printf("\n** Invalid partition type \"%.32s\"" " (expect \"" + BOOT_PART_TYPE "\")\n", + info.type); + bootstage_error(BOOTSTAGE_ID_IDE_PART_TYPE); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_PART_TYPE); + + printf("\nLoading from disk device %d, partition %d: " + "Name: %.32s Type: %.32s\n", dev, part, info.name, info.type); + + debug("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", + info.start, info.size, info.blksz); + + if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) { + printf("** Read error on %d:%d\n", dev, part); + bootstage_error(BOOTSTAGE_ID_IDE_PART_READ); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ); + + switch (genimg_get_format((void *) addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *) addr; + + bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT); + + if (!image_check_hcrc(hdr)) { + puts("\n** Bad Header Checksum **\n"); + bootstage_error(BOOTSTAGE_ID_IDE_CHECKSUM); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_CHECKSUM); + + image_print_contents(hdr); + + cnt = image_get_image_size(hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *) addr; + puts("Fit image detected...\n"); + + cnt = fit_get_size(fit_hdr); + break; +#endif + default: + bootstage_error(BOOTSTAGE_ID_IDE_FORMAT); + puts("** Unknown image type\n"); + return 1; + } + + cnt += info.blksz - 1; + cnt /= info.blksz; + cnt -= 1; + + if (dev_desc->block_read(dev, info.start + 1, cnt, + (ulong *)(addr + info.blksz)) != cnt) { + printf("** Read error on %d:%d\n", dev, part); + bootstage_error(BOOTSTAGE_ID_IDE_READ); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_READ); + +#if defined(CONFIG_FIT) + /* This cannot be done earlier, + * we need complete FIT image in RAM first */ + if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) { + if (!fit_check_format(fit_hdr)) { + bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ); + puts("** Bad FIT image format\n"); + return 1; + } + bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK); + fit_print_contents(fit_hdr); + } +#endif + + flush_cache(addr, (cnt+1)*info.blksz); + + /* Loading ok, update default load address */ + load_addr = addr; + + return bootm_maybe_autostart(cmdtp, argv[0]); +} diff --git a/common/cmd_ide.c b/common/cmd_ide.c index f5b6c7b..6e1e568 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -334,156 +334,7 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - char *boot_device = NULL; - char *ep; - int dev, part = 0; - ulong addr, cnt; - disk_partition_t info; - image_header_t *hdr; - -#if defined(CONFIG_FIT) - const void *fit_hdr = NULL; -#endif - - bootstage_mark(BOOTSTAGE_ID_IDE_START); - switch (argc) { - case 1: - addr = CONFIG_SYS_LOAD_ADDR; - boot_device = getenv("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - default: - bootstage_error(BOOTSTAGE_ID_IDE_ADDR); - return CMD_RET_USAGE; - } - bootstage_mark(BOOTSTAGE_ID_IDE_ADDR); - - if (!boot_device) { - puts("\n** No boot device **\n"); - bootstage_error(BOOTSTAGE_ID_IDE_BOOT_DEVICE); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE); - - dev = simple_strtoul(boot_device, &ep, 16); - - if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { - printf("\n** Device %d not available\n", dev); - bootstage_error(BOOTSTAGE_ID_IDE_TYPE); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_TYPE); - - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - bootstage_error(BOOTSTAGE_ID_IDE_PART); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - bootstage_mark(BOOTSTAGE_ID_IDE_PART); - - if (get_partition_info(&ide_dev_desc[dev], part, &info)) { - bootstage_error(BOOTSTAGE_ID_IDE_PART_INFO); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_PART_INFO); - - if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) - && - (strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0) - ) { - printf("\n** Invalid partition type \"%.32s\"" " (expect \"" - BOOT_PART_TYPE "\")\n", - info.type); - bootstage_error(BOOTSTAGE_ID_IDE_PART_TYPE); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_PART_TYPE); - - printf("\nLoading from IDE device %d, partition %d: " - "Name: %.32s Type: %.32s\n", dev, part, info.name, info.type); - - debug("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", - info.start, info.size, info.blksz); - - if (ide_dev_desc[dev]. - block_read(dev, info.start, 1, (ulong *) addr) != 1) { - printf("** Read error on %d:%d\n", dev, part); - bootstage_error(BOOTSTAGE_ID_IDE_PART_READ); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ); - - switch (genimg_get_format((void *) addr)) { - case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *) addr; - - bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT); - - if (!image_check_hcrc(hdr)) { - puts("\n** Bad Header Checksum **\n"); - bootstage_error(BOOTSTAGE_ID_IDE_CHECKSUM); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_CHECKSUM); - - image_print_contents(hdr); - - cnt = image_get_image_size(hdr); - break; -#if defined(CONFIG_FIT) - case IMAGE_FORMAT_FIT: - fit_hdr = (const void *) addr; - puts("Fit image detected...\n"); - - cnt = fit_get_size(fit_hdr); - break; -#endif - default: - bootstage_error(BOOTSTAGE_ID_IDE_FORMAT); - puts("** Unknown image type\n"); - return 1; - } - - cnt += info.blksz - 1; - cnt /= info.blksz; - cnt -= 1; - - if (ide_dev_desc[dev].block_read(dev, info.start + 1, cnt, - (ulong *)(addr + info.blksz)) != cnt) { - printf("** Read error on %d:%d\n", dev, part); - bootstage_error(BOOTSTAGE_ID_IDE_READ); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_READ); - -#if defined(CONFIG_FIT) - /* This cannot be done earlier, we need complete FIT image in RAM first */ - if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) { - if (!fit_check_format(fit_hdr)) { - bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ); - puts("** Bad FIT image format\n"); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK); - fit_print_contents(fit_hdr); - } -#endif - - /* Loading ok, update default load address */ - - load_addr = addr; - - return bootm_maybe_autostart(cmdtp, argv[0]); + return common_diskboot(cmdtp, "ide", argc, argv); } /* ------------------------------------------------------------------------- */ diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index d15b567..22d0119 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -206,128 +206,7 @@ block_dev_desc_t * scsi_get_dev(int dev) */ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char *boot_device = NULL; - char *ep; - int dev, part = 0; - ulong addr, cnt; - disk_partition_t info; - image_header_t *hdr; -#if defined(CONFIG_FIT) - const void *fit_hdr = NULL; -#endif - - switch (argc) { - case 1: - addr = CONFIG_SYS_LOAD_ADDR; - boot_device = getenv ("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv ("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - default: - return CMD_RET_USAGE; - } - - if (!boot_device) { - puts ("\n** No boot device **\n"); - return 1; - } - - dev = simple_strtoul(boot_device, &ep, 16); - printf("booting from dev %d\n",dev); - if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { - printf ("\n** Device %d not available\n", dev); - return 1; - } - - if (*ep) { - if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - if (get_partition_info (&scsi_dev_desc[dev], part, &info)) { - printf("error reading partinfo\n"); - return 1; - } - if ((strncmp((char *)(info.type), BOOT_PART_TYPE, sizeof(info.type)) != 0) && - (strncmp((char *)(info.type), BOOT_PART_COMP, sizeof(info.type)) != 0)) { - printf ("\n** Invalid partition type \"%.32s\"" - " (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - return 1; - } - - printf ("\nLoading from SCSI device %d, partition %d: " - "Name: %.32s Type: %.32s\n", - dev, part, info.name, info.type); - - debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", - info.start, info.size, info.blksz); - - if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) { - printf ("** Read error on %d:%d\n", dev, part); - return 1; - } - - switch (genimg_get_format ((void *)addr)) { - case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *)addr; - - if (!image_check_hcrc (hdr)) { - puts ("\n** Bad Header Checksum **\n"); - return 1; - } - - image_print_contents (hdr); - cnt = image_get_image_size (hdr); - break; -#if defined(CONFIG_FIT) - case IMAGE_FORMAT_FIT: - fit_hdr = (const void *)addr; - puts ("Fit image detected...\n"); - - cnt = fit_get_size (fit_hdr); - break; -#endif - default: - puts ("** Unknown image type\n"); - return 1; - } - - cnt += info.blksz - 1; - cnt /= info.blksz; - cnt -= 1; - - if (scsi_read (dev, info.start+1, cnt, - (ulong *)(addr+info.blksz)) != cnt) { - printf ("** Read error on %d:%d\n", dev, part); - return 1; - } - -#if defined(CONFIG_FIT) - /* This cannot be done earlier, we need complete FIT image in RAM first */ - if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) { - if (!fit_check_format (fit_hdr)) { - puts ("** Bad FIT image format\n"); - return 1; - } - fit_print_contents (fit_hdr); - } -#endif - - /* Loading ok, update default load address */ - load_addr = addr; - - flush_cache (addr, (cnt+1)*info.blksz); - - return bootm_maybe_autostart(cmdtp, argv[0]); + return common_diskboot(cmdtp, "scsi", argc, argv); } /********************************************************************************* diff --git a/common/cmd_usb.c b/common/cmd_usb.c index a8e3ae5..181e727 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -355,143 +355,7 @@ void usb_show_tree(struct usb_device *dev) #ifdef CONFIG_USB_STORAGE int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char *boot_device = NULL; - char *ep; - int dev, part = 1; - ulong addr, cnt; - disk_partition_t info; - image_header_t *hdr; - block_dev_desc_t *stor_dev; -#if defined(CONFIG_FIT) - const void *fit_hdr = NULL; -#endif - - switch (argc) { - case 1: - addr = CONFIG_SYS_LOAD_ADDR; - boot_device = getenv("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - default: - return CMD_RET_USAGE; - } - - if (!boot_device) { - puts("\n** No boot device **\n"); - return 1; - } - - dev = simple_strtoul(boot_device, &ep, 16); - stor_dev = usb_stor_get_dev(dev); - if (stor_dev == NULL || stor_dev->type == DEV_TYPE_UNKNOWN) { - printf("\n** Device %d not available\n", dev); - return 1; - } - if (stor_dev->block_read == NULL) { - printf("storage device not initialized. Use usb scan\n"); - return 1; - } - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - - if (get_partition_info(stor_dev, part, &info)) { - /* try to boot raw .... */ - strncpy((char *)&info.type[0], BOOT_PART_TYPE, - sizeof(BOOT_PART_TYPE)); - strncpy((char *)&info.name[0], "Raw", 4); - info.start = 0; - info.blksz = 0x200; - info.size = 2880; - printf("error reading partinfo...try to boot raw\n"); - } - if ((strncmp((char *)info.type, BOOT_PART_TYPE, - sizeof(info.type)) != 0) && - (strncmp((char *)info.type, BOOT_PART_COMP, - sizeof(info.type)) != 0)) { - printf("\n** Invalid partition type \"%.32s\"" - " (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - return 1; - } - printf("\nLoading from USB device %d, partition %d: " - "Name: %.32s Type: %.32s\n", - dev, part, info.name, info.type); - - debug("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", - info.start, info.size, info.blksz); - - if (stor_dev->block_read(dev, info.start, 1, (ulong *)addr) != 1) { - printf("** Read error on %d:%d\n", dev, part); - return 1; - } - - switch (genimg_get_format((void *)addr)) { - case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *)addr; - - if (!image_check_hcrc(hdr)) { - puts("\n** Bad Header Checksum **\n"); - return 1; - } - - image_print_contents(hdr); - - cnt = image_get_image_size(hdr); - break; -#if defined(CONFIG_FIT) - case IMAGE_FORMAT_FIT: - fit_hdr = (const void *)addr; - puts("Fit image detected...\n"); - - cnt = fit_get_size(fit_hdr); - break; -#endif - default: - puts("** Unknown image type\n"); - return 1; - } - - cnt += info.blksz - 1; - cnt /= info.blksz; - cnt -= 1; - - if (stor_dev->block_read(dev, info.start+1, cnt, - (ulong *)(addr+info.blksz)) != cnt) { - printf("\n** Read error on %d:%d\n", dev, part); - return 1; - } - -#if defined(CONFIG_FIT) - /* This cannot be done earlier, we need complete FIT image in RAM - * first - */ - if (genimg_get_format((void *)addr) == IMAGE_FORMAT_FIT) { - if (!fit_check_format(fit_hdr)) { - puts("** Bad FIT image format\n"); - return 1; - } - fit_print_contents(fit_hdr); - } -#endif - - /* Loading ok, update default load address */ - load_addr = addr; - - flush_cache(addr, (cnt+1)*info.blksz); - - return bootm_maybe_autostart(cmdtp, argv[0]); + return common_diskboot(cmdtp, "usb", argc, argv); } #endif /* CONFIG_USB_STORAGE */ diff --git a/include/command.h b/include/command.h index 6e1bdc2..1f06aa1 100644 --- a/include/command.h +++ b/include/command.h @@ -110,6 +110,10 @@ static inline int bootm_maybe_autostart(cmd_tbl_t *cmdtp, const char *cmd) return 0; } #endif + +extern int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, + char *const argv[]); + extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); /* -- cgit v1.1 From 40e0e5686accd2f7ae7fd81297620d0e132624d9 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 23 Aug 2012 11:31:43 +0000 Subject: disk/part: check bootable flag for DOS partitions Determine which partitions are bootable/active. In the partition listing, print "Boot" for partitions with the bootable/active flag set. Signed-off-by: Rob Herring --- disk/part_dos.c | 11 +++++++++-- include/part.h | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/disk/part_dos.c b/disk/part_dos.c index a43dd9c..24ac00c 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -60,14 +60,20 @@ static inline int is_extended(int part_type) part_type == 0x85); } +static inline int is_bootable(dos_partition_t *p) +{ + return p->boot_ind == 0x80; +} + static void print_one_part (dos_partition_t *p, int ext_part_sector, int part_num) { int lba_start = ext_part_sector + le32_to_int (p->start4); int lba_size = le32_to_int (p->size4); - printf ("%5d\t\t%10d\t%10d\t%2x%s\n", + printf("%5d\t\t%10d\t%10d\t%2x%s%s\n", part_num, lba_start, lba_size, p->sys_ind, - (is_extended (p->sys_ind) ? " Extd" : "")); + (is_extended(p->sys_ind) ? " Extd" : ""), + (is_bootable(p) ? " Boot" : "")); } static int test_block_type(unsigned char *buffer) @@ -222,6 +228,7 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part } /* sprintf(info->type, "%d, pt->sys_ind); */ sprintf ((char *)info->type, "U-Boot"); + info->bootable = is_bootable(pt); return 0; } diff --git a/include/part.h b/include/part.h index e1478f4..447f69d 100644 --- a/include/part.h +++ b/include/part.h @@ -93,6 +93,7 @@ typedef struct disk_partition { ulong blksz; /* block size in bytes */ uchar name[32]; /* partition name */ uchar type[32]; /* string type description */ + int bootable; /* Active/Bootable flag is set */ } disk_partition_t; /* Misc _get_dev functions */ -- cgit v1.1 From 99d2c205d4a151faf5f9a406316b9dd960f43475 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 21 Sep 2012 04:08:17 +0000 Subject: disk/part: introduce get_device_and_partition All block device related commands (scsiboot, fatload, ext2ls, etc.) have simliar duplicated device and partition parsing and selection code. This adds a common function to replace various implementations. The new function has an enhancement over current versions. If no device or partition is specified on the command line, the bootdevice env variable will be used (scsiboot does this). Signed-off-by: Rob Herring --- disk/part.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- include/part.h | 13 +++++++++-- 2 files changed, 78 insertions(+), 4 deletions(-) diff --git a/disk/part.c b/disk/part.c index f659cc3..f0afd89 100644 --- a/disk/part.c +++ b/disk/part.c @@ -70,7 +70,7 @@ static const struct block_drvr block_drvr[] = { DECLARE_GLOBAL_DATA_PTR; -block_dev_desc_t *get_dev(char* ifname, int dev) +block_dev_desc_t *get_dev(const char *ifname, int dev) { const struct block_drvr *drvr = block_drvr; block_dev_desc_t* (*reloc_get_dev)(int dev); @@ -97,7 +97,7 @@ block_dev_desc_t *get_dev(char* ifname, int dev) return NULL; } #else -block_dev_desc_t *get_dev(char* ifname, int dev) +block_dev_desc_t *get_dev(const char *ifname, int dev) { return NULL; } @@ -288,6 +288,7 @@ void init_part (block_dev_desc_t * dev_desc) return; } #endif + dev_desc->part_type = PART_TYPE_UNKNOWN; } @@ -441,3 +442,67 @@ int get_partition_info(block_dev_desc_t *dev_desc, int part return -1; } + +int get_device_and_partition(const char *ifname, const char *dev_str, + block_dev_desc_t **dev_desc, + disk_partition_t *info) +{ + int ret; + char *ep; + int dev; + block_dev_desc_t *desc; + int part = 0; + char *part_str; + + if (dev_str) + dev = simple_strtoul(dev_str, &ep, 16); + + if (!dev_str || (dev_str == ep)) { + dev_str = getenv("bootdevice"); + if (dev_str) + dev = simple_strtoul(dev_str, &ep, 16); + if (!dev_str || (dev_str == ep)) + goto err; + } + + desc = get_dev(ifname, dev); + if (!desc || (desc->type == DEV_TYPE_UNKNOWN)) + goto err; + + if (desc->part_type == PART_TYPE_UNKNOWN) { + /* disk doesn't use partition table */ + if (!desc->lba) { + printf("**Bad disk size - %s %d:0 **\n", ifname, dev); + return -1; + } + info->start = 0; + info->size = desc->lba; + info->blksz = desc->blksz; + + *dev_desc = desc; + return 0; + } + + part_str = strchr(dev_str, ':'); + if (part_str) + part = (int)simple_strtoul(++part_str, NULL, 16); + + ret = get_partition_info(desc, part, info); + if (ret) { + printf("** Invalid partition %d, use `dev[:part]' **\n", part); + return -1; + } + if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) { + printf("** Invalid partition type \"%.32s\"" + " (expect \"" BOOT_PART_TYPE "\")\n", + info->type); + return -1; + } + + *dev_desc = desc; + return part; + +err: + puts("** Invalid boot device, use `dev[:part]' **\n"); + return -1; +} diff --git a/include/part.h b/include/part.h index 447f69d..a6d06f3 100644 --- a/include/part.h +++ b/include/part.h @@ -98,7 +98,7 @@ typedef struct disk_partition { /* Misc _get_dev functions */ #ifdef CONFIG_PARTITIONS -block_dev_desc_t* get_dev(char* ifname, int dev); +block_dev_desc_t *get_dev(const char *ifname, int dev); block_dev_desc_t* ide_get_dev(int dev); block_dev_desc_t* sata_get_dev(int dev); block_dev_desc_t* scsi_get_dev(int dev); @@ -112,8 +112,12 @@ int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t void print_part (block_dev_desc_t *dev_desc); void init_part (block_dev_desc_t *dev_desc); void dev_print(block_dev_desc_t *dev_desc); +int get_device_and_partition(const char *ifname, const char *dev_str, + block_dev_desc_t **dev_desc, + disk_partition_t *info); #else -static inline block_dev_desc_t* get_dev(char* ifname, int dev) { return NULL; } +static inline block_dev_desc_t *get_dev(const char *ifname, int dev) +{ return NULL; } static inline block_dev_desc_t* ide_get_dev(int dev) { return NULL; } static inline block_dev_desc_t* sata_get_dev(int dev) { return NULL; } static inline block_dev_desc_t* scsi_get_dev(int dev) { return NULL; } @@ -127,6 +131,11 @@ static inline int get_partition_info (block_dev_desc_t * dev_desc, int part, static inline void print_part (block_dev_desc_t *dev_desc) {} static inline void init_part (block_dev_desc_t *dev_desc) {} static inline void dev_print(block_dev_desc_t *dev_desc) {} +static inline int get_device_and_partition(const char *ifname, + const char *dev_str, + block_dev_desc_t **dev_desc, + disk_partition_t *info) +{ *dev_desc = NULL; return -1; } #endif #ifdef CONFIG_MAC_PARTITION -- cgit v1.1 From 945010629641b00cca95d1fed4f63009a2b4a113 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 23 Aug 2012 11:31:45 +0000 Subject: ext4: remove init_fs/deinit_fs There's no real need to expose this and it can be removed by using a static allocation. Signed-off-by: Rob Herring --- common/cmd_ext4.c | 10 +++------- common/cmd_ext_common.c | 19 +++---------------- fs/ext4/ext4fs.c | 36 ++---------------------------------- include/ext4fs.h | 2 -- include/zfs_common.h | 2 -- 5 files changed, 8 insertions(+), 61 deletions(-) diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c index 77094c4..e92c02f 100644 --- a/common/cmd_ext4.c +++ b/common/cmd_ext4.c @@ -151,8 +151,6 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc, printf("Block device %s %d not supported\n", argv[1], dev); return 1; } - if (init_fs(ext4_dev_desc)) - return 1; fs = get_fs(); if (*ep) { @@ -173,21 +171,21 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc, file_size = simple_strtoul(argv[5], NULL, 10); /* set the device as block device */ - part_length = ext4fs_set_blk_dev(fs->dev_desc, part); + part_length = ext4fs_set_blk_dev(ext4_dev_desc, part); if (part_length == 0) { printf("Bad partition - %s %d:%lu\n", argv[1], dev, part); goto fail; } /* register the device and partition */ - if (ext4_register_device(fs->dev_desc, part) != 0) { + if (ext4_register_device(ext4_dev_desc, part) != 0) { printf("Unable to use %s %d:%lu for fattable\n", argv[1], dev, part); goto fail; } /* get the partition information */ - if (!get_partition_info(fs->dev_desc, part, &info)) { + if (!get_partition_info(ext4_dev_desc, part, &info)) { total_sector = (info.size * info.blksz) / SECTOR_SIZE; fs->total_sect = total_sector; } else { @@ -207,13 +205,11 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc, goto fail; } ext4fs_close(); - deinit_fs(fs->dev_desc); return 0; fail: ext4fs_close(); - deinit_fs(fs->dev_desc); return 1; } diff --git a/common/cmd_ext_common.c b/common/cmd_ext_common.c index 56ee9a5..8972ccc 100644 --- a/common/cmd_ext_common.c +++ b/common/cmd_ext_common.c @@ -75,7 +75,6 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, ulong part_length; int filelen; disk_partition_t info; - struct ext_filesystem *fs; char buf[12]; unsigned long count; const char *addr_str; @@ -117,10 +116,7 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, printf("** Block device %s %d not supported\n", argv[1], dev); return 1; } - if (init_fs(ext4_dev_desc)) - return 1; - fs = get_fs(); if (*ep) { if (*ep != ':') { puts("** Invalid boot device, use `dev[:part]' **\n"); @@ -130,7 +126,7 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, } if (part != 0) { - if (get_partition_info(fs->dev_desc, part, &info)) { + if (get_partition_info(ext4_dev_desc, part, &info)) { printf("** Bad partition %lu **\n", part); goto fail; } @@ -149,7 +145,7 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, filename, argv[1], dev); } - part_length = ext4fs_set_blk_dev(fs->dev_desc, part); + part_length = ext4fs_set_blk_dev(ext4_dev_desc, part); if (part_length == 0) { printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part); ext4fs_close(); @@ -180,7 +176,6 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, } ext4fs_close(); - deinit_fs(fs->dev_desc); /* Loading ok, update default load address */ load_addr = addr; @@ -190,7 +185,6 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, return 0; fail: - deinit_fs(fs->dev_desc); return 1; } @@ -200,7 +194,6 @@ int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) int dev; unsigned long part = 1; char *ep; - struct ext_filesystem *fs; int part_length; if (argc < 3) return cmd_usage(cmdtp); @@ -214,10 +207,6 @@ int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) return 1; } - if (init_fs(ext4_dev_desc)) - return 1; - - fs = get_fs(); if (*ep) { if (*ep != ':') { puts("\n** Invalid boot device, use `dev[:part]' **\n"); @@ -229,7 +218,7 @@ int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) if (argc == 4) filename = argv[3]; - part_length = ext4fs_set_blk_dev(fs->dev_desc, part); + part_length = ext4fs_set_blk_dev(ext4_dev_desc, part); if (part_length == 0) { printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part); ext4fs_close(); @@ -250,10 +239,8 @@ int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) }; ext4fs_close(); - deinit_fs(fs->dev_desc); return 0; fail: - deinit_fs(fs->dev_desc); return 1; } diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c index 114c2a2..c366e6f 100644 --- a/fs/ext4/ext4fs.c +++ b/fs/ext4/ext4fs.c @@ -44,43 +44,11 @@ int ext4fs_symlinknest; block_dev_desc_t *ext4_dev_desc; +struct ext_filesystem ext_fs; struct ext_filesystem *get_fs(void) { - if (ext4_dev_desc == NULL || ext4_dev_desc->priv == NULL) - printf("Invalid Input Arguments %s\n", __func__); - - return ext4_dev_desc->priv; -} - -int init_fs(block_dev_desc_t *dev_desc) -{ - struct ext_filesystem *fs; - if (dev_desc == NULL) { - printf("Invalid Input Arguments %s\n", __func__); - return -EINVAL; - } - - fs = zalloc(sizeof(struct ext_filesystem)); - if (fs == NULL) { - printf("malloc failed: %s\n", __func__); - return -ENOMEM; - } - - fs->dev_desc = dev_desc; - dev_desc->priv = fs; - - return 0; -} - -void deinit_fs(block_dev_desc_t *dev_desc) -{ - if (dev_desc == NULL) { - printf("Invalid Input Arguments %s\n", __func__); - return; - } - free(dev_desc->priv); - dev_desc->priv = NULL; + return &ext_fs; } void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot) diff --git a/include/ext4fs.h b/include/ext4fs.h index ab2983c..6ad008c 100644 --- a/include/ext4fs.h +++ b/include/ext4fs.h @@ -130,8 +130,6 @@ int ext4fs_write(const char *fname, unsigned char *buffer, #endif struct ext_filesystem *get_fs(void); -int init_fs(block_dev_desc_t *dev_desc); -void deinit_fs(block_dev_desc_t *dev_desc); int ext4fs_open(const char *filename); int ext4fs_read(char *buf, unsigned len); int ext4fs_mount(unsigned part_length); diff --git a/include/zfs_common.h b/include/zfs_common.h index 04e73d0..628231e 100644 --- a/include/zfs_common.h +++ b/include/zfs_common.h @@ -94,8 +94,6 @@ struct zfs_dirhook_info { struct zfs_filesystem *zfsget_fs(void); -int init_fs(block_dev_desc_t *dev_desc); -void deinit_fs(block_dev_desc_t *dev_desc); int zfs_open(zfs_file_t, const char *filename); uint64_t zfs_read(zfs_file_t, char *buf, uint64_t len); struct zfs_data *zfs_mount(device_t); -- cgit v1.1 From 81180819b842602f29f325298ee3e522beda3e0a Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 23 Aug 2012 11:31:46 +0000 Subject: cmd_extX: use common get_device_and_partition function Convert ext2/4 load, ls, and write functions to use common device and partition parsing function. With the common function "dev:part" can come from the environment and a '-' can be used in that case. Signed-off-by: Rob Herring --- common/cmd_ext4.c | 102 ++++-------------------------------------------- common/cmd_ext_common.c | 95 +++++++++++--------------------------------- fs/ext4/dev.c | 32 ++++++--------- fs/ext4/ext4_common.h | 1 - fs/ext4/ext4fs.c | 1 - include/ext4fs.h | 3 +- include/ext_common.h | 2 + 7 files changed, 46 insertions(+), 190 deletions(-) diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c index e92c02f..48f9ba3 100644 --- a/common/cmd_ext4.c +++ b/common/cmd_ext4.c @@ -56,21 +56,6 @@ #include #endif -#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION) -#error DOS or EFI partition support must be selected -#endif - -uint64_t total_sector; -uint64_t part_offset; -#if defined(CONFIG_CMD_EXT4_WRITE) -static uint64_t part_size; -static uint16_t cur_part = 1; -#endif - -#define DOS_PART_MAGIC_OFFSET 0x1fe -#define DOS_FS_TYPE_OFFSET 0x36 -#define DOS_FS32_TYPE_OFFSET 0x52 - int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { @@ -89,77 +74,24 @@ int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) } #if defined(CONFIG_CMD_EXT4_WRITE) -static int ext4_register_device(block_dev_desc_t *dev_desc, int part_no) -{ - unsigned char buffer[SECTOR_SIZE]; - disk_partition_t info; - - if (!dev_desc->block_read) - return -1; - - /* check if we have a MBR (on floppies we have only a PBR) */ - if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) { - printf("** Can't read from device %d **\n", dev_desc->dev); - return -1; - } - if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || - buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { - /* no signature found */ - return -1; - } - - /* First we assume there is a MBR */ - if (!get_partition_info(dev_desc, part_no, &info)) { - part_offset = info.start; - cur_part = part_no; - part_size = info.size; - } else if ((strncmp((char *)&buffer[DOS_FS_TYPE_OFFSET], - "FAT", 3) == 0) || (strncmp((char *)&buffer - [DOS_FS32_TYPE_OFFSET], - "FAT32", 5) == 0)) { - /* ok, we assume we are on a PBR only */ - cur_part = 1; - part_offset = 0; - } else { - printf("** Partition %d not valid on device %d **\n", - part_no, dev_desc->dev); - return -1; - } - - return 0; -} - int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { const char *filename = "/"; - int part_length; - unsigned long part = 1; - int dev; - char *ep; + int dev, part; unsigned long ram_address; unsigned long file_size; disk_partition_t info; - struct ext_filesystem *fs; + block_dev_desc_t *dev_desc; if (argc < 6) return cmd_usage(cmdtp); - dev = (int)simple_strtoul(argv[2], &ep, 16); - ext4_dev_desc = get_dev(argv[1], dev); - if (ext4_dev_desc == NULL) { - printf("Block device %s %d not supported\n", argv[1], dev); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + if (part < 0) return 1; - } - fs = get_fs(); - if (*ep) { - if (*ep != ':') { - puts("Invalid boot device, use `dev[:part]'\n"); - goto fail; - } - part = simple_strtoul(++ep, NULL, 16); - } + dev = dev_desc->dev; /* get the filename */ filename = argv[3]; @@ -171,30 +103,10 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc, file_size = simple_strtoul(argv[5], NULL, 10); /* set the device as block device */ - part_length = ext4fs_set_blk_dev(ext4_dev_desc, part); - if (part_length == 0) { - printf("Bad partition - %s %d:%lu\n", argv[1], dev, part); - goto fail; - } - - /* register the device and partition */ - if (ext4_register_device(ext4_dev_desc, part) != 0) { - printf("Unable to use %s %d:%lu for fattable\n", - argv[1], dev, part); - goto fail; - } - - /* get the partition information */ - if (!get_partition_info(ext4_dev_desc, part, &info)) { - total_sector = (info.size * info.blksz) / SECTOR_SIZE; - fs->total_sect = total_sector; - } else { - printf("error : get partition info\n"); - goto fail; - } + ext4fs_set_blk_dev(dev_desc, &info); /* mount the filesystem */ - if (!ext4fs_mount(part_length)) { + if (!ext4fs_mount(info.size)) { printf("Bad ext4 partition %s %d:%lu\n", argv[1], dev, part); goto fail; } diff --git a/common/cmd_ext_common.c b/common/cmd_ext_common.c index 8972ccc..7d26944 100644 --- a/common/cmd_ext_common.c +++ b/common/cmd_ext_common.c @@ -68,13 +68,11 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { char *filename = NULL; - char *ep; - int dev; - unsigned long part = 1; + int dev, part; ulong addr = 0; - ulong part_length; int filelen; disk_partition_t info; + block_dev_desc_t *dev_desc; char buf[12]; unsigned long count; const char *addr_str; @@ -110,50 +108,19 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, return 1; } - dev = (int)simple_strtoul(argv[2], &ep, 16); - ext4_dev_desc = get_dev(argv[1], dev); - if (ext4_dev_desc == NULL) { - printf("** Block device %s %d not supported\n", argv[1], dev); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts("** Invalid boot device, use `dev[:part]' **\n"); - goto fail; - } - part = simple_strtoul(++ep, NULL, 16); - } + dev = dev_desc->dev; + printf("Loading file \"%s\" from %s device %d%c%c\n", + filename, argv[1], dev, + part ? ':' : ' ', part ? part + '0' : ' '); - if (part != 0) { - if (get_partition_info(ext4_dev_desc, part, &info)) { - printf("** Bad partition %lu **\n", part); - goto fail; - } - - if (strncmp((char *)info.type, BOOT_PART_TYPE, - strlen(BOOT_PART_TYPE)) != 0) { - printf("** Invalid partition type \"%s\"" - " (expect \"" BOOT_PART_TYPE "\")\n", info.type); - goto fail; - } - printf("Loading file \"%s\" " - "from %s device %d:%lu %s\n", - filename, argv[1], dev, part, info.name); - } else { - printf("Loading file \"%s\" from %s device %d\n", - filename, argv[1], dev); - } + ext4fs_set_blk_dev(dev_desc, &info); - part_length = ext4fs_set_blk_dev(ext4_dev_desc, part); - if (part_length == 0) { - printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part); - ext4fs_close(); - goto fail; - } - - if (!ext4fs_mount(part_length)) { - printf("** Bad ext2 partition or disk - %s %d:%lu **\n", + if (!ext4fs_mount(info.size)) { + printf("** Bad ext2 partition or disk - %s %d:%d **\n", argv[1], dev, part); ext4fs_close(); goto fail; @@ -169,7 +136,7 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, filelen = count; if (ext4fs_read((char *)addr, filelen) != filelen) { - printf("** Unable to read \"%s\" from %s %d:%lu **\n", + printf("** Unable to read \"%s\" from %s %d:%d **\n", filename, argv[1], dev, part); ext4fs_close(); goto fail; @@ -192,41 +159,25 @@ int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { const char *filename = "/"; int dev; - unsigned long part = 1; - char *ep; - int part_length; - if (argc < 3) - return cmd_usage(cmdtp); - - dev = (int)simple_strtoul(argv[2], &ep, 16); + int part; + block_dev_desc_t *dev_desc; + disk_partition_t info; - ext4_dev_desc = get_dev(argv[1], dev); + if (argc < 2) + return cmd_usage(cmdtp); - if (ext4_dev_desc == NULL) { - printf("\n** Block device %s %d not supported\n", argv[1], dev); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + if (part < 0) return 1; - } - - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - goto fail; - } - part = simple_strtoul(++ep, NULL, 16); - } if (argc == 4) filename = argv[3]; - part_length = ext4fs_set_blk_dev(ext4_dev_desc, part); - if (part_length == 0) { - printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part); - ext4fs_close(); - goto fail; - } + dev = dev_desc->dev; + ext4fs_set_blk_dev(dev_desc, &info); - if (!ext4fs_mount(part_length)) { - printf("** Bad ext2 partition or disk - %s %d:%lu **\n", + if (!ext4fs_mount(info.size)) { + printf("** Bad ext2 partition or disk - %s %d:%d **\n", argv[1], dev, part); ext4fs_close(); goto fail; diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c index 9e85228..1596a92 100644 --- a/fs/ext4/dev.c +++ b/fs/ext4/dev.c @@ -38,26 +38,20 @@ #include #include +#include #include +unsigned long part_offset; + static block_dev_desc_t *ext4fs_block_dev_desc; -static disk_partition_t part_info; +static disk_partition_t *part_info; -int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part) +void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info) { ext4fs_block_dev_desc = rbdd; - - if (part == 0) { - /* disk doesn't use partition table */ - part_info.start = 0; - part_info.size = rbdd->lba; - part_info.blksz = rbdd->blksz; - } else { - if (get_partition_info(ext4fs_block_dev_desc, - part, &part_info)) - return 0; - } - return part_info.size; + part_info = info; + part_offset = info->start; + get_fs()->total_sect = (info->size * info->blksz) / SECTOR_SIZE; } int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf) @@ -68,7 +62,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf) /* Check partition boundaries */ if ((sector < 0) || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >= - part_info.size)) { + part_info->size)) { printf("%s read outside partition %d\n", __func__, sector); return 0; } @@ -88,7 +82,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf) /* read first part which isn't aligned with start of sector */ if (ext4fs_block_dev_desc-> block_read(ext4fs_block_dev_desc->dev, - part_info.start + sector, 1, + part_info->start + sector, 1, (unsigned long *) sec_buf) != 1) { printf(" ** ext2fs_devread() read error **\n"); return 0; @@ -111,14 +105,14 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf) block_len = SECTOR_SIZE; ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev, - part_info.start + sector, + part_info->start + sector, 1, (unsigned long *)p); memcpy(buf, p, byte_len); return 1; } if (ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev, - part_info.start + sector, + part_info->start + sector, block_len / SECTOR_SIZE, (unsigned long *) buf) != block_len / SECTOR_SIZE) { @@ -134,7 +128,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf) /* read rest of data which are not in whole sector */ if (ext4fs_block_dev_desc-> block_read(ext4fs_block_dev_desc->dev, - part_info.start + sector, 1, + part_info->start + sector, 1, (unsigned long *) sec_buf) != 1) { printf("* %s read error - last part\n", __func__); return 0; diff --git a/fs/ext4/ext4_common.h b/fs/ext4/ext4_common.h index 0af625d..f728134 100644 --- a/fs/ext4/ext4_common.h +++ b/fs/ext4/ext4_common.h @@ -62,7 +62,6 @@ static inline void *zalloc(size_t size) return p; } -extern unsigned long part_offset; int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode); int ext4fs_read_file(struct ext2fs_node *node, int pos, diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c index c366e6f..93dcb7e 100644 --- a/fs/ext4/ext4fs.c +++ b/fs/ext4/ext4fs.c @@ -43,7 +43,6 @@ #include "ext4_common.h" int ext4fs_symlinknest; -block_dev_desc_t *ext4_dev_desc; struct ext_filesystem ext_fs; struct ext_filesystem *get_fs(void) diff --git a/include/ext4fs.h b/include/ext4fs.h index 6ad008c..b6eedde 100644 --- a/include/ext4fs.h +++ b/include/ext4fs.h @@ -113,7 +113,6 @@ struct ext_filesystem { block_dev_desc_t *dev_desc; }; -extern block_dev_desc_t *ext4_dev_desc; extern struct ext2_data *ext4fs_root; extern struct ext2fs_node *ext4fs_file; @@ -137,6 +136,6 @@ void ext4fs_close(void); int ext4fs_ls(const char *dirname); void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot); int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf); -int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part); +void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info); long int read_allocated_block(struct ext2_inode *inode, int fileblock); #endif diff --git a/include/ext_common.h b/include/ext_common.h index 9b97522..ce73857 100644 --- a/include/ext_common.h +++ b/include/ext_common.h @@ -186,6 +186,8 @@ struct ext2_data { struct ext2fs_node diropen; }; +extern unsigned long part_offset; + int do_ext2ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); int do_ext2load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc, -- cgit v1.1 From cfda5aeab89d73779e26f0d34cf10f64caa67431 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 23 Aug 2012 11:31:47 +0000 Subject: cmd_fat: use common get_device_and_partition function Convert fatload, fatls, and fatinfo to use common device and partition parsing function. With the common function "dev:part" can come from the environment and a '-' can be used in that case. Signed-off-by: Rob Herring --- common/cmd_fat.c | 100 +++++++++++++++++++------------------------------------ 1 file changed, 34 insertions(+), 66 deletions(-) diff --git a/common/cmd_fat.c b/common/cmd_fat.c index 559a16d..90412d6 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -40,29 +40,20 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) unsigned long count; char buf [12]; block_dev_desc_t *dev_desc=NULL; - int dev=0; - int part=1; - char *ep; + disk_partition_t info; + int part, dev; if (argc < 5) { - printf( "usage: fatload " + printf("usage: fatload [] " " [bytes]\n"); return 1; } - dev = (int)simple_strtoul(argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - if (dev_desc == NULL) { - puts("\n** Invalid boot device **\n"); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } + + dev = dev_desc->dev; if (fat_register_device(dev_desc,part)!=0) { printf("\n** Unable to use %s %d:%d for fatload **\n", argv[1], dev, part); @@ -93,7 +84,7 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( fatload, 6, 0, do_fat_fsload, "load binary file from a dos filesystem", - " [bytes]\n" + " [] [bytes]\n" " - load binary file 'filename' from 'dev' on 'interface'\n" " to address 'addr' from dos filesystem" ); @@ -101,29 +92,20 @@ U_BOOT_CMD( int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = "/"; - int ret; - int dev=0; - int part=1; - char *ep; + int ret, dev, part; block_dev_desc_t *dev_desc=NULL; + disk_partition_t info; - if (argc < 3) { - printf("usage: fatls [directory]\n"); + if (argc < 2) { + printf("usage: fatls [] [directory]\n"); return 0; } - dev = (int)simple_strtoul(argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - if (dev_desc == NULL) { - puts("\n** Invalid boot device **\n"); + + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } + + dev = dev_desc->dev; if (fat_register_device(dev_desc,part)!=0) { printf("\n** Unable to use %s %d:%d for fatls **\n", argv[1], dev, part); @@ -142,34 +124,26 @@ int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( fatls, 4, 1, do_fat_ls, "list files in a directory (default /)", - " [directory]\n" + " [] [directory]\n" " - list files from 'dev' on 'interface' in a 'directory'" ); int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int dev=0; - int part=1; - char *ep; - block_dev_desc_t *dev_desc=NULL; + int dev, part; + block_dev_desc_t *dev_desc; + disk_partition_t info; if (argc < 2) { - printf("usage: fatinfo \n"); + printf("usage: fatinfo []\n"); return 0; } - dev = (int)simple_strtoul(argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - if (dev_desc == NULL) { - puts("\n** Invalid boot device **\n"); + + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } + + dev = dev_desc->dev; if (fat_register_device(dev_desc,part)!=0) { printf("\n** Unable to use %s %d:%d for fatinfo **\n", argv[1], dev, part); @@ -181,7 +155,7 @@ int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( fatinfo, 3, 1, do_fat_fsinfo, "print information about filesystem", - " \n" + " []\n" " - print information about filesystem from 'dev' on 'interface'" ); @@ -193,6 +167,7 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag, unsigned long addr; unsigned long count; block_dev_desc_t *dev_desc = NULL; + disk_partition_t info; int dev = 0; int part = 1; char *ep; @@ -200,19 +175,12 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag, if (argc < 5) return cmd_usage(cmdtp); - dev = (int)simple_strtoul(argv[2], &ep, 16); - dev_desc = get_dev(argv[1], dev); - if (dev_desc == NULL) { - puts("\n** Invalid boot device **\n"); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } + + dev = dev_desc->dev; + if (fat_register_device(dev_desc, part) != 0) { printf("\n** Unable to use %s %d:%d for fatwrite **\n", argv[1], dev, part); -- cgit v1.1 From 475c7970c18526adb406f8bc648c44255b300225 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 23 Aug 2012 11:31:48 +0000 Subject: cmd_disk: use common get_device_and_partition function Signed-off-by: Rob Herring --- common/cmd_disk.c | 77 ++++++++++++++----------------------------------------- 1 file changed, 19 insertions(+), 58 deletions(-) diff --git a/common/cmd_disk.c b/common/cmd_disk.c index e73fc4e..8df9344 100644 --- a/common/cmd_disk.c +++ b/common/cmd_disk.c @@ -23,14 +23,16 @@ */ #include #include +#include +#if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_USB_STORAGE) int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, char *const argv[]) { - char *boot_device = NULL; - char *ep; - int dev, part = 0; - ulong addr, cnt; + int dev, part; + ulong addr = CONFIG_SYS_LOAD_ADDR; + ulong cnt; disk_partition_t info; image_header_t *hdr; block_dev_desc_t *dev_desc; @@ -40,72 +42,30 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, #endif bootstage_mark(BOOTSTAGE_ID_IDE_START); - switch (argc) { - case 1: - addr = CONFIG_SYS_LOAD_ADDR; - boot_device = getenv("bootdevice"); - break; - case 2: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = getenv("bootdevice"); - break; - case 3: - addr = simple_strtoul(argv[1], NULL, 16); - boot_device = argv[2]; - break; - default: + if (argc > 3) { bootstage_error(BOOTSTAGE_ID_IDE_ADDR); return CMD_RET_USAGE; } bootstage_mark(BOOTSTAGE_ID_IDE_ADDR); - if (!boot_device) { - puts("\n** No boot device **\n"); - bootstage_error(BOOTSTAGE_ID_IDE_BOOT_DEVICE); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE); + if (argc > 1) + addr = simple_strtoul(argv[1], NULL, 16); - dev = simple_strtoul(boot_device, &ep, 16); + bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE); - dev_desc = get_dev(intf, dev); - if (dev_desc->type == DEV_TYPE_UNKNOWN) { - printf("\n** Device %d not available\n", dev); + part = get_device_and_partition(intf, (argc == 3) ? argv[2] : NULL, + &dev_desc, &info); + if (part < 0) { bootstage_error(BOOTSTAGE_ID_IDE_TYPE); return 1; } - bootstage_mark(BOOTSTAGE_ID_IDE_TYPE); - - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - bootstage_error(BOOTSTAGE_ID_IDE_PART); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - bootstage_mark(BOOTSTAGE_ID_IDE_PART); - if (get_partition_info(dev_desc, part, &info)) { - bootstage_error(BOOTSTAGE_ID_IDE_PART_INFO); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_PART_INFO); - - if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) - && - (strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0) - ) { - printf("\n** Invalid partition type \"%.32s\"" " (expect \"" - BOOT_PART_TYPE "\")\n", - info.type); - bootstage_error(BOOTSTAGE_ID_IDE_PART_TYPE); - return 1; - } - bootstage_mark(BOOTSTAGE_ID_IDE_PART_TYPE); + dev = dev_desc->dev; + bootstage_mark(BOOTSTAGE_ID_IDE_TYPE); - printf("\nLoading from disk device %d, partition %d: " - "Name: %.32s Type: %.32s\n", dev, part, info.name, info.type); + printf("\nLoading from %s device %d, partition %d: " + "Name: %.32s Type: %.32s\n", intf, dev, part, info.name, + info.type); debug("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", info.start, info.size, info.blksz); @@ -181,3 +141,4 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, return bootm_maybe_autostart(cmdtp, argv[0]); } +#endif -- cgit v1.1 From 412045704477a9b4d46b7e1fddbd53ec5dcde155 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 23 Aug 2012 11:31:49 +0000 Subject: cmd_zfs: use common get_device_and_partition function Convert zfsload and zfsls to use common device and partition parsing function. With the common function "dev:part" can come from the environment and a '-' can be used in that case. Signed-off-by: Rob Herring --- common/cmd_zfs.c | 88 ++++++++++++---------------------------------------- fs/zfs/dev.c | 35 +++++++-------------- include/zfs_common.h | 5 +-- 3 files changed, 31 insertions(+), 97 deletions(-) diff --git a/common/cmd_zfs.c b/common/cmd_zfs.c index a6ea2c0..27f8856 100644 --- a/common/cmd_zfs.c +++ b/common/cmd_zfs.c @@ -49,12 +49,11 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *filename = NULL; - char *ep; int dev; - unsigned long part = 1; + int part; ulong addr = 0; - ulong part_length; disk_partition_t info; + block_dev_desc_t *dev_desc; char buf[12]; unsigned long count; const char *addr_str; @@ -95,48 +94,17 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - dev = (int)simple_strtoul(argv[2], &ep, 16); - zfs_dev_desc = get_dev(argv[1], dev); - if (zfs_dev_desc == NULL) { - printf("** Block device %s %d not supported\n", argv[1], dev); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts("** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } + dev = dev_desc->dev; + printf("Loading file \"%s\" from %s device %d%c%c\n", + filename, argv[1], dev, + part ? ':' : ' ', part ? part + '0' : ' '); - if (part != 0) { - if (get_partition_info(zfs_dev_desc, part, &info)) { - printf("** Bad partition %lu **\n", part); - return 1; - } - - if (strncmp((char *)info.type, BOOT_PART_TYPE, - strlen(BOOT_PART_TYPE)) != 0) { - printf("** Invalid partition type \"%s\" (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - return 1; - } - printf("Loading file \"%s\" " - "from %s device %d:%lu %s\n", - filename, argv[1], dev, part, info.name); - } else { - printf("Loading file \"%s\" from %s device %d\n", - filename, argv[1], dev); - } - - part_length = zfs_set_blk_dev(zfs_dev_desc, part); - if (part_length == 0) { - printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part); - return 1; - } - - vdev.part_length = part_length; + zfs_set_blk_dev(dev_desc, &info); + vdev.part_length = info.size; memset(&zfile, 0, sizeof(zfile)); zfile.device = &vdev; @@ -149,7 +117,7 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) zfile.size = (uint64_t)count; if (zfs_read(&zfile, (char *)addr, zfile.size) != zfile.size) { - printf("** Unable to read \"%s\" from %s %d:%lu **\n", + printf("** Unable to read \"%s\" from %s %d:%d **\n", filename, argv[1], dev, part); zfs_close(&zfile); return 1; @@ -181,41 +149,23 @@ int zfs_print(const char *entry, const struct zfs_dirhook_info *data) static int do_zfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { const char *filename = "/"; - int dev; - unsigned long part = 1; - char *ep; - int part_length; + int part; + block_dev_desc_t *dev_desc; + disk_partition_t info; struct device_s vdev; - if (argc < 3) + if (argc < 2) return cmd_usage(cmdtp); - dev = (int)simple_strtoul(argv[2], &ep, 16); - zfs_dev_desc = get_dev(argv[1], dev); - - if (zfs_dev_desc == NULL) { - printf("\n** Block device %s %d not supported\n", argv[1], dev); - return 1; - } - - if (*ep) { - if (*ep != ':') { - puts("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = simple_strtoul(++ep, NULL, 16); - } - if (argc == 4) filename = argv[3]; - part_length = zfs_set_blk_dev(zfs_dev_desc, part); - if (part_length == 0) { - printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + if (part < 0) return 1; - } - vdev.part_length = part_length; + zfs_set_blk_dev(dev_desc, &info); + vdev.part_length = info.size; zfs_ls(&vdev, filename, zfs_print); diff --git a/fs/zfs/dev.c b/fs/zfs/dev.c index d68372c..36be8f5 100644 --- a/fs/zfs/dev.c +++ b/fs/zfs/dev.c @@ -26,23 +26,12 @@ #include static block_dev_desc_t *zfs_block_dev_desc; -static disk_partition_t part_info; +static disk_partition_t *part_info; -int zfs_set_blk_dev(block_dev_desc_t *rbdd, int part) +void zfs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info) { zfs_block_dev_desc = rbdd; - - if (part == 0) { - /* disk doesn't use partition table */ - part_info.start = 0; - part_info.size = rbdd->lba; - part_info.blksz = rbdd->blksz; - } else { - if (get_partition_info(zfs_block_dev_desc, part, &part_info)) - return 0; - } - - return part_info.size; + part_info = info; } /* err */ @@ -57,7 +46,7 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf) */ if ((sector < 0) || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >= - part_info.size)) { + part_info->size)) { /* errnum = ERR_OUTSIDE_PART; */ printf(" ** zfs_devread() read outside partition sector %d\n", sector); return 1; @@ -79,8 +68,8 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf) if (byte_offset != 0) { /* read first part which isn't aligned with start of sector */ if (zfs_block_dev_desc->block_read(zfs_block_dev_desc->dev, - part_info.start + sector, 1, - (unsigned long *) sec_buf) != 1) { + part_info->start + sector, 1, + (unsigned long *)sec_buf) != 1) { printf(" ** zfs_devread() read error **\n"); return 1; } @@ -102,17 +91,15 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf) block_len = SECTOR_SIZE; zfs_block_dev_desc->block_read(zfs_block_dev_desc->dev, - part_info.start + sector, - 1, (unsigned long *)p); + part_info->start + sector, + 1, (unsigned long *)p); memcpy(buf, p, byte_len); return 0; } if (zfs_block_dev_desc->block_read(zfs_block_dev_desc->dev, - part_info.start + sector, - block_len / SECTOR_SIZE, - (unsigned long *) buf) != - block_len / SECTOR_SIZE) { + part_info->start + sector, block_len / SECTOR_SIZE, + (unsigned long *) buf) != block_len / SECTOR_SIZE) { printf(" ** zfs_devread() read error - block\n"); return 1; } @@ -126,7 +113,7 @@ int zfs_devread(int sector, int byte_offset, int byte_len, char *buf) /* read rest of data which are not in whole sector */ if (zfs_block_dev_desc-> block_read(zfs_block_dev_desc->dev, - part_info.start + sector, 1, + part_info->start + sector, 1, (unsigned long *) sec_buf) != 1) { printf(" ** zfs_devread() read error - last part\n"); return 1; diff --git a/include/zfs_common.h b/include/zfs_common.h index 628231e..3bd575e 100644 --- a/include/zfs_common.h +++ b/include/zfs_common.h @@ -66,9 +66,6 @@ struct zfs_filesystem { block_dev_desc_t *dev_desc; }; - -extern block_dev_desc_t *zfs_dev_desc; - struct device_s { uint64_t part_length; }; @@ -101,7 +98,7 @@ int zfs_close(zfs_file_t); int zfs_ls(device_t dev, const char *path, int (*hook) (const char *, const struct zfs_dirhook_info *)); int zfs_devread(int sector, int byte_offset, int byte_len, char *buf); -int zfs_set_blk_dev(block_dev_desc_t *rbdd, int part); +void zfs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info); void zfs_unmount(struct zfs_data *data); int lzjb_decompress(void *, void *, uint32_t, uint32_t); #endif -- cgit v1.1 From 650f36641ccfe1c2444277891da7c76cdde99f8b Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 23 Aug 2012 11:31:50 +0000 Subject: cmd_reiser: use common get_device_and_partition function Convert reiserload and reiserls to use common device and partition parsing function. With the common function "dev:part" can come from the environment and a '-' can be used in that case. Signed-off-by: Rob Herring --- common/cmd_reiser.c | 81 +++++++++++------------------------------------------ fs/reiserfs/dev.c | 29 +++++++------------ include/reiserfs.h | 2 +- 3 files changed, 28 insertions(+), 84 deletions(-) diff --git a/common/cmd_reiser.c b/common/cmd_reiser.c index fbb9484..2865014 100644 --- a/common/cmd_reiser.c +++ b/common/cmd_reiser.c @@ -50,43 +50,27 @@ int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = "/"; - int dev=0; - int part=1; - char *ep; + int dev, part; block_dev_desc_t *dev_desc=NULL; - int part_length; + disk_partition_t info; if (argc < 3) return CMD_RET_USAGE; - dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - - if (dev_desc == NULL) { - printf ("\n** Block device %s %d not supported\n", argv[1], dev); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + if (part < 0) return 1; - } - - if (*ep) { - if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } if (argc == 4) { filename = argv[3]; } + dev = dev_desc->dev; PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename); - if ((part_length = reiserfs_set_blk_dev(dev_desc, part)) == 0) { - printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part); - return 1; - } + reiserfs_set_blk_dev(dev_desc, &info); - if (!reiserfs_mount(part_length)) { + if (!reiserfs_mount(info.size)) { printf ("** Bad Reiserfs partition or disk - %s %d:%d **\n", argv[1], dev, part); return 1; } @@ -112,9 +96,8 @@ U_BOOT_CMD( int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *filename = NULL; - char *ep; - int dev, part = 0; - ulong addr = 0, part_length, filelen; + int dev, part; + ulong addr = 0, filelen; disk_partition_t info; block_dev_desc_t *dev_desc = NULL; char buf [12]; @@ -157,49 +140,19 @@ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - dev = (int)simple_strtoul (argv[2], &ep, 16); - dev_desc = get_dev(argv[1],dev); - if (dev_desc==NULL) { - printf ("\n** Block device %s %d not supported\n", argv[1], dev); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + if (part < 0) return 1; - } - if (*ep) { - if (*ep != ':') { - puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - return 1; - } - part = (int)simple_strtoul(++ep, NULL, 16); - } - PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part); + dev = dev_desc->dev; - if (part != 0) { - if (get_partition_info (dev_desc, part, &info)) { - printf ("** Bad partition %d **\n", part); - return 1; - } + printf("Loading file \"%s\" from %s device %d%c%c\n", + filename, argv[1], dev, + part ? ':' : ' ', part ? part + '0' : ' '); - if (strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) { - printf ("\n** Invalid partition type \"%.32s\"" - " (expect \"" BOOT_PART_TYPE "\")\n", - info.type); - return 1; - } - PRINTF ("\nLoading from block device %s device %d, partition %d: " - "Name: %.32s Type: %.32s File:%s\n", - argv[1], dev, part, info.name, info.type, filename); - } else { - PRINTF ("\nLoading from block device %s device %d, File:%s\n", - argv[1], dev, filename); - } - - - if ((part_length = reiserfs_set_blk_dev(dev_desc, part)) == 0) { - printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part); - return 1; - } + reiserfs_set_blk_dev(dev_desc, &info); - if (!reiserfs_mount(part_length)) { + if (!reiserfs_mount(info.size)) { printf ("** Bad Reiserfs partition or disk - %s %d:%d **\n", argv[1], dev, part); return 1; } diff --git a/fs/reiserfs/dev.c b/fs/reiserfs/dev.c index 1facfaf..cb288d6 100644 --- a/fs/reiserfs/dev.c +++ b/fs/reiserfs/dev.c @@ -25,24 +25,13 @@ #include "reiserfs_private.h" static block_dev_desc_t *reiserfs_block_dev_desc; -static disk_partition_t part_info; +static disk_partition_t *part_info; -int reiserfs_set_blk_dev(block_dev_desc_t *rbdd, int part) +void reiserfs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info) { reiserfs_block_dev_desc = rbdd; - - if (part == 0) { - /* disk doesn't use partition table */ - part_info.start = 0; - part_info.size = rbdd->lba; - part_info.blksz = rbdd->blksz; - } else { - if (get_partition_info (reiserfs_block_dev_desc, part, &part_info)) { - return 0; - } - } - return (part_info.size); + part_info = info; } @@ -59,7 +48,7 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf) */ if (sector < 0 || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) - >= part_info.size)) { + >= part_info->size)) { /* errnum = ERR_OUTSIDE_PART; */ printf (" ** reiserfs_devread() read outside partition\n"); return 0; @@ -83,7 +72,8 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf) if (byte_offset != 0) { /* read first part which isn't aligned with start of sector */ if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev, - part_info.start+sector, 1, (unsigned long *)sec_buf) != 1) { + part_info->start + sector, 1, + (unsigned long *)sec_buf) != 1) { printf (" ** reiserfs_devread() read error\n"); return 0; } @@ -96,8 +86,8 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf) /* read sector aligned part */ block_len = byte_len & ~(SECTOR_SIZE-1); if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev, - part_info.start+sector, block_len/SECTOR_SIZE, (unsigned long *)buf) != - block_len/SECTOR_SIZE) { + part_info->start + sector, block_len/SECTOR_SIZE, + (unsigned long *)buf) != block_len/SECTOR_SIZE) { printf (" ** reiserfs_devread() read error - block\n"); return 0; } @@ -108,7 +98,8 @@ int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf) if ( byte_len != 0 ) { /* read rest of data which are not in whole sector */ if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev, - part_info.start+sector, 1, (unsigned long *)sec_buf) != 1) { + part_info->start + sector, 1, + (unsigned long *)sec_buf) != 1) { printf (" ** reiserfs_devread() read error - last part\n"); return 0; } diff --git a/include/reiserfs.h b/include/reiserfs.h index c465b3c..dc89342 100644 --- a/include/reiserfs.h +++ b/include/reiserfs.h @@ -75,7 +75,7 @@ typedef enum } reiserfs_error_t; -extern int reiserfs_set_blk_dev(block_dev_desc_t *rbdd, int part); +extern void reiserfs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info); extern int reiserfs_ls (char *dirname); extern int reiserfs_open (char *filename); extern int reiserfs_read (char *buf, unsigned len); -- cgit v1.1 From 2023e60861283ee808950a558e14b45be8776bf4 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 21 Sep 2012 09:50:56 +0000 Subject: disk: introduce get_device() This patch introduces function get_device(). This looks up a block_dev_desc_t from an interface name (e.g. mmc) and device number (e.g. 0). This function is essentially the non-partition-specific prefix of get_device_and_partition(). Signed-off-by: Stephen Warren --- disk/part.c | 22 ++++++++++++++++++++++ include/part.h | 5 +++++ 2 files changed, 27 insertions(+) diff --git a/disk/part.c b/disk/part.c index f0afd89..ed6bbe2 100644 --- a/disk/part.c +++ b/disk/part.c @@ -443,6 +443,28 @@ int get_partition_info(block_dev_desc_t *dev_desc, int part return -1; } +int get_device(const char *ifname, const char *dev_str, + block_dev_desc_t **dev_desc) +{ + char *ep; + int dev; + + dev = simple_strtoul(dev_str, &ep, 16); + if (*ep) { + printf("** Bad device specification %s %s **\n", + ifname, dev_str); + return -1; + } + + *dev_desc = get_dev(ifname, dev); + if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) { + printf("** Bad device %s %s **\n", ifname, dev_str); + return -1; + } + + return dev; +} + int get_device_and_partition(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc, disk_partition_t *info) diff --git a/include/part.h b/include/part.h index a6d06f3..144df4e 100644 --- a/include/part.h +++ b/include/part.h @@ -112,6 +112,8 @@ int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t void print_part (block_dev_desc_t *dev_desc); void init_part (block_dev_desc_t *dev_desc); void dev_print(block_dev_desc_t *dev_desc); +int get_device(const char *ifname, const char *dev_str, + block_dev_desc_t **dev_desc); int get_device_and_partition(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc, disk_partition_t *info); @@ -131,6 +133,9 @@ static inline int get_partition_info (block_dev_desc_t * dev_desc, int part, static inline void print_part (block_dev_desc_t *dev_desc) {} static inline void init_part (block_dev_desc_t *dev_desc) {} static inline void dev_print(block_dev_desc_t *dev_desc) {} +static inline int get_device(const char *ifname, const char *dev_str, + block_dev_desc_t **dev_desc) +{ return -1; } static inline int get_device_and_partition(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc, -- cgit v1.1 From 10a37fd7a40826c43a63591855346adf1a1ac02d Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 21 Sep 2012 09:50:57 +0000 Subject: disk: get_device_and_partition() "auto" partition and cleanup Rework get_device_and_partition() to: a) Implement a new partition ID of "auto", which requests that U-Boot search for the first "bootable" partition, and fall back to the first valid partition if none is found. This way, users don't need to specify an explicit partition in their commands. b) Make use of get_device(). c) Add parameter to indicate whether returning a whole device is acceptable, or whether a partition is mandatory. d) Make error-checking of the user's device-/partition-specification more complete. In particular, if strtoul() doesn't convert all characters, it's an error rather than just ignored. The resultant device/partition returned by the function will be as follows, based on whether the disk has a partition table (ptable) or not, and whether the calling command allows the whole device to be returned or not. (D and P are integers, P >= 1) D D: No ptable: !allow_whole_dev: error allow_whole_dev: device D ptable: device D partition 1 D:0 !allow_whole_dev: error allow_whole_dev: device D D:P No ptable: error ptable: device D partition P D:auto No ptable: !allow_whole_dev: error allow_whole_dev: device D ptable: first partition in device D with bootable flag set. If none, first valid paratition in device D. Note: In order to review this patch, it's probably easiest to simply look at the file contents post-application, rather than reading the patch itself. Signed-off-by: Rob Herring [swarren: Rob implemented scanning for bootable partitions. I fixed a couple of issues there, switched the syntax to ":auto", added the error-checking rework, and ":0" syntax for the whole device] Signed-off-by: Stephen Warren --- common/cmd_disk.c | 2 +- common/cmd_ext4.c | 2 +- common/cmd_ext_common.c | 4 +- common/cmd_fat.c | 8 +- common/cmd_reiser.c | 4 +- common/cmd_zfs.c | 4 +- disk/part.c | 197 +++++++++++++++++++++++++++++++++++++----------- include/part.h | 9 ++- 8 files changed, 171 insertions(+), 59 deletions(-) diff --git a/common/cmd_disk.c b/common/cmd_disk.c index 8df9344..ee4e215 100644 --- a/common/cmd_disk.c +++ b/common/cmd_disk.c @@ -54,7 +54,7 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE); part = get_device_and_partition(intf, (argc == 3) ? argv[2] : NULL, - &dev_desc, &info); + &dev_desc, &info, 1); if (part < 0) { bootstage_error(BOOTSTAGE_ID_IDE_TYPE); return 1; diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c index 48f9ba3..ca46561 100644 --- a/common/cmd_ext4.c +++ b/common/cmd_ext4.c @@ -87,7 +87,7 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc, if (argc < 6) return cmd_usage(cmdtp); - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; diff --git a/common/cmd_ext_common.c b/common/cmd_ext_common.c index 7d26944..1952f4d 100644 --- a/common/cmd_ext_common.c +++ b/common/cmd_ext_common.c @@ -108,7 +108,7 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc, return 1; } - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; @@ -166,7 +166,7 @@ int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) if (argc < 2) return cmd_usage(cmdtp); - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; diff --git a/common/cmd_fat.c b/common/cmd_fat.c index 90412d6..01e02f5 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -49,7 +49,7 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; @@ -101,7 +101,7 @@ int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; @@ -139,7 +139,7 @@ int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; @@ -175,7 +175,7 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag, if (argc < 5) return cmd_usage(cmdtp); - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; diff --git a/common/cmd_reiser.c b/common/cmd_reiser.c index 2865014..e658618 100644 --- a/common/cmd_reiser.c +++ b/common/cmd_reiser.c @@ -57,7 +57,7 @@ int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc < 3) return CMD_RET_USAGE; - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; @@ -140,7 +140,7 @@ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; diff --git a/common/cmd_zfs.c b/common/cmd_zfs.c index 27f8856..d580f7b 100644 --- a/common/cmd_zfs.c +++ b/common/cmd_zfs.c @@ -94,7 +94,7 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; @@ -160,7 +160,7 @@ static int do_zfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (argc == 4) filename = argv[3]; - part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info); + part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); if (part < 0) return 1; diff --git a/disk/part.c b/disk/part.c index ed6bbe2..0dd4b0f 100644 --- a/disk/part.c +++ b/disk/part.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #undef PART_DEBUG @@ -465,66 +466,176 @@ int get_device(const char *ifname, const char *dev_str, return dev; } -int get_device_and_partition(const char *ifname, const char *dev_str, +#define PART_UNSPECIFIED -2 +#define PART_AUTO -1 +#define MAX_SEARCH_PARTITIONS 16 +int get_device_and_partition(const char *ifname, const char *dev_part_str, block_dev_desc_t **dev_desc, - disk_partition_t *info) + disk_partition_t *info, int allow_whole_dev) { - int ret; - char *ep; + int ret = -1; + const char *part_str; + char *dup_str = NULL; + const char *dev_str; int dev; - block_dev_desc_t *desc; - int part = 0; - char *part_str; - - if (dev_str) - dev = simple_strtoul(dev_str, &ep, 16); - - if (!dev_str || (dev_str == ep)) { - dev_str = getenv("bootdevice"); - if (dev_str) - dev = simple_strtoul(dev_str, &ep, 16); - if (!dev_str || (dev_str == ep)) - goto err; + char *ep; + int p; + int part; + disk_partition_t tmpinfo; + + /* If no dev_part_str, use bootdevice environment variable */ + if (!dev_part_str) + dev_part_str = getenv("bootdevice"); + + /* If still no dev_part_str, it's an error */ + if (!dev_part_str) { + printf("** No device specified **\n"); + goto cleanup; + } + + /* Separate device and partition ID specification */ + part_str = strchr(dev_part_str, ':'); + if (part_str) { + dup_str = strdup(dev_part_str); + dup_str[part_str - dev_part_str] = 0; + dev_str = dup_str; + part_str++; + } else { + dev_str = dev_part_str; } - desc = get_dev(ifname, dev); - if (!desc || (desc->type == DEV_TYPE_UNKNOWN)) - goto err; + /* Look up the device */ + dev = get_device(ifname, dev_str, dev_desc); + if (dev < 0) + goto cleanup; + + /* Convert partition ID string to number */ + if (!part_str || !*part_str) { + part = PART_UNSPECIFIED; + } else if (!strcmp(part_str, "auto")) { + part = PART_AUTO; + } else { + /* Something specified -> use exactly that */ + part = (int)simple_strtoul(part_str, &ep, 16); + /* + * Less than whole string converted, + * or request for whole device, but caller requires partition. + */ + if (*ep || (part == 0 && !allow_whole_dev)) { + printf("** Bad partition specification %s %s **\n", + ifname, dev_part_str); + goto cleanup; + } + } + + /* + * No partition table on device, + * or user requested partition 0 (entire device). + */ + if (((*dev_desc)->part_type == PART_TYPE_UNKNOWN) || + (part == 0)) { + if (!(*dev_desc)->lba) { + printf("** Bad device size - %s %s **\n", ifname, + dev_str); + goto cleanup; + } - if (desc->part_type == PART_TYPE_UNKNOWN) { - /* disk doesn't use partition table */ - if (!desc->lba) { - printf("**Bad disk size - %s %d:0 **\n", ifname, dev); - return -1; + /* + * If user specified a partition ID other than 0, + * or the calling command only accepts partitions, + * it's an error. + */ + if ((part > 0) || (!allow_whole_dev)) { + printf("** No partition table - %s %s **\n", ifname, + dev_str); + goto cleanup; } + info->start = 0; - info->size = desc->lba; - info->blksz = desc->blksz; + info->size = (*dev_desc)->lba; + info->blksz = (*dev_desc)->blksz; + info->bootable = 0; +#ifdef CONFIG_PARTITION_UUIDS + info->uuid[0] = 0; +#endif - *dev_desc = desc; - return 0; + ret = 0; + goto cleanup; } - part_str = strchr(dev_str, ':'); - if (part_str) - part = (int)simple_strtoul(++part_str, NULL, 16); - - ret = get_partition_info(desc, part, info); - if (ret) { - printf("** Invalid partition %d, use `dev[:part]' **\n", part); - return -1; + /* + * Now there's known to be a partition table, + * not specifying a partition means to pick partition 1. + */ + if (part == PART_UNSPECIFIED) + part = 1; + + /* + * If user didn't specify a partition number, or did specify something + * other than "auto", use that partition number directly. + */ + if (part != PART_AUTO) { + ret = get_partition_info(*dev_desc, part, info); + if (ret) { + printf("** Invalid partition %d **\n", part); + goto cleanup; + } + } else { + /* + * Find the first bootable partition. + * If none are bootable, fall back to the first valid partition. + */ + part = 0; + for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { + ret = get_partition_info(*dev_desc, p, info); + if (ret) + continue; + + /* + * First valid partition, or new better partition? + * If so, save partition ID. + */ + if (!part || info->bootable) + part = p; + + /* Best possible partition? Stop searching. */ + if (info->bootable) + break; + + /* + * We now need to search further for best possible. + * If we what we just queried was the best so far, + * save the info since we over-write it next loop. + */ + if (part == p) + tmpinfo = *info; + } + /* If we found any acceptable partition */ + if (part) { + /* + * If we searched all possible partition IDs, + * return the first valid partition we found. + */ + if (p == MAX_SEARCH_PARTITIONS + 1) + *info = tmpinfo; + ret = 0; + } else { + printf("** No valid partitions found **\n"); + goto cleanup; + } } if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) { printf("** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info->type); - return -1; + ret = -1; + goto cleanup; } - *dev_desc = desc; - return part; + ret = part; + goto cleanup; -err: - puts("** Invalid boot device, use `dev[:part]' **\n"); - return -1; +cleanup: + free(dup_str); + return ret; } diff --git a/include/part.h b/include/part.h index 144df4e..3f780a1 100644 --- a/include/part.h +++ b/include/part.h @@ -114,9 +114,9 @@ void init_part (block_dev_desc_t *dev_desc); void dev_print(block_dev_desc_t *dev_desc); int get_device(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc); -int get_device_and_partition(const char *ifname, const char *dev_str, +int get_device_and_partition(const char *ifname, const char *dev_part_str, block_dev_desc_t **dev_desc, - disk_partition_t *info); + disk_partition_t *info, int allow_whole_dev); #else static inline block_dev_desc_t *get_dev(const char *ifname, int dev) { return NULL; } @@ -137,9 +137,10 @@ static inline int get_device(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc) { return -1; } static inline int get_device_and_partition(const char *ifname, - const char *dev_str, + const char *dev_part_str, block_dev_desc_t **dev_desc, - disk_partition_t *info) + disk_partition_t *info, + int allow_whole_dev) { *dev_desc = NULL; return -1; } #endif -- cgit v1.1 From c04d68c69458526d30bd542ff2f8f83cc20ccfc5 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 21 Sep 2012 09:50:58 +0000 Subject: disk: part_efi: range-check partition number Enhance get_partition_info_efi() to range-check the partition number. This prevents invalid partitions being accessed, and prevents access beyond the end of the gpt_pte[] array. Signed-off-by: Stephen Warren --- disk/part_efi.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/disk/part_efi.c b/disk/part_efi.c index 02927a0..2962fd8 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -173,6 +173,13 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, return -1; } + if (part > le32_to_int(gpt_head->num_partition_entries) || + !is_pte_valid(&gpt_pte[part - 1])) { + printf("%s: *** ERROR: Invalid partition number %d ***\n", + __func__, part); + return -1; + } + /* The ulong casting limits the maximum disk size to 2 TB */ info->start = (ulong) le64_to_int(gpt_pte[part - 1].starting_lba); /* The ending LBA is inclusive, to calculate size, add 1 to it */ -- cgit v1.1 From 894bfbbfb772de2f8640f91aee322f3cb2577cb7 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 21 Sep 2012 09:50:59 +0000 Subject: disk: part_efi: parse and store partition UUID Each EFI partition table entry contains a UUID. Extend U-Boot's struct disk_partition to be able to store this information, and modify get_partition_info_efi() to fill it in. The implementation of uuid_string() was derived from the Linux kernel, tag v3.6-rc4 file lib/vsprintf.c function uuid_string(). Signed-off-by: Stephen Warren --- disk/part.c | 5 +++++ disk/part_efi.c | 25 +++++++++++++++++++++++++ include/part.h | 3 +++ 3 files changed, 33 insertions(+) diff --git a/disk/part.c b/disk/part.c index 0dd4b0f..64d76e8 100644 --- a/disk/part.c +++ b/disk/part.c @@ -391,6 +391,11 @@ int get_partition_info(block_dev_desc_t *dev_desc, int part defined(CONFIG_MMC) || \ defined(CONFIG_SYSTEMACE) +#ifdef CONFIG_PARTITION_UUIDS + /* The common case is no UUID support */ + info->uuid[0] = 0; +#endif + switch (dev_desc->part_type) { #ifdef CONFIG_MAC_PARTITION case PART_TYPE_MAC: diff --git a/disk/part_efi.c b/disk/part_efi.c index 2962fd8..264ea9c 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -154,6 +154,28 @@ void print_part_efi(block_dev_desc_t * dev_desc) return; } +#ifdef CONFIG_PARTITION_UUIDS +static void uuid_string(unsigned char *uuid, char *str) +{ + static const u8 le[16] = {3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, + 12, 13, 14, 15}; + int i; + + for (i = 0; i < 16; i++) { + sprintf(str, "%02x", uuid[le[i]]); + str += 2; + switch (i) { + case 3: + case 5: + case 7: + case 9: + *str++ = '-'; + break; + } + } +} +#endif + int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, disk_partition_t * info) { @@ -190,6 +212,9 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, sprintf((char *)info->name, "%s", print_efiname(&gpt_pte[part - 1])); sprintf((char *)info->type, "U-Boot"); +#ifdef CONFIG_PARTITION_UUIDS + uuid_string(gpt_pte[part - 1].unique_partition_guid.b, info->uuid); +#endif debug("%s: start 0x%lX, size 0x%lX, name %s", __func__, info->start, info->size, info->name); diff --git a/include/part.h b/include/part.h index 3f780a1..27ea283 100644 --- a/include/part.h +++ b/include/part.h @@ -94,6 +94,9 @@ typedef struct disk_partition { uchar name[32]; /* partition name */ uchar type[32]; /* string type description */ int bootable; /* Active/Bootable flag is set */ +#ifdef CONFIG_PARTITION_UUIDS + char uuid[37]; /* filesystem UUID as string, if exists */ +#endif } disk_partition_t; /* Misc _get_dev functions */ -- cgit v1.1 From d27b5f9398aba377ff2185fb4b8170eeca7c3b65 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 21 Sep 2012 09:51:00 +0000 Subject: disk: part_msdos: parse and store partition UUID The MSDOS/MBR partition table includes a 32-bit unique ID, often referred to as the NT disk signature. When combined with a partition number within the table, this can form a unique ID similar in concept to EFI/GPT's partition UUID. This patch generates UUIDs in the format 0002dd75-01, which matches the format expected by the Linux kernel. Signed-off-by: Stephen Warren --- disk/part_dos.c | 15 ++++++++++++--- disk/part_dos.h | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/disk/part_dos.c b/disk/part_dos.c index 24ac00c..c9a3e2b 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -169,7 +169,8 @@ static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_s */ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part_sector, int relative, int part_num, - int which_part, disk_partition_t *info) + int which_part, disk_partition_t *info, + unsigned int disksig) { ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); dos_partition_t *pt; @@ -188,6 +189,11 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part return -1; } +#ifdef CONFIG_PARTITION_UUIDS + if (!ext_part_sector) + disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]); +#endif + /* Print all primary/logical partitions */ pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); for (i = 0; i < 4; i++, pt++) { @@ -229,6 +235,9 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part /* sprintf(info->type, "%d, pt->sys_ind); */ sprintf ((char *)info->type, "U-Boot"); info->bootable = is_bootable(pt); +#ifdef CONFIG_PARTITION_UUIDS + sprintf(info->uuid, "%08x-%02x", disksig, part_num); +#endif return 0; } @@ -247,7 +256,7 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part return get_partition_info_extended (dev_desc, lba_start, ext_part_sector == 0 ? lba_start : relative, - part_num, which_part, info); + part_num, which_part, info, disksig); } } return -1; @@ -261,7 +270,7 @@ void print_part_dos (block_dev_desc_t *dev_desc) int get_partition_info_dos (block_dev_desc_t *dev_desc, int part, disk_partition_t * info) { - return get_partition_info_extended (dev_desc, 0, 0, 1, part, info); + return get_partition_info_extended(dev_desc, 0, 0, 1, part, info, 0); } diff --git a/disk/part_dos.h b/disk/part_dos.h index de75542..7b77c1d 100644 --- a/disk/part_dos.h +++ b/disk/part_dos.h @@ -24,7 +24,7 @@ #ifndef _DISK_PART_DOS_H #define _DISK_PART_DOS_H - +#define DOS_PART_DISKSIG_OFFSET 0x1b8 #define DOS_PART_TBL_OFFSET 0x1be #define DOS_PART_MAGIC_OFFSET 0x1fe #define DOS_PBR_FSTYPE_OFFSET 0x36 -- cgit v1.1 From 5cf41dccff9d1e8c297de6eae8422d3e322eebbc Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 21 Sep 2012 09:51:01 +0000 Subject: cmd_part: add partition-related command This implements the following: part uuid mmc 0:1 -> print partition UUID part uuid mmc 0:1 uuid -> set environment variable to partition UUID part list mmc 0 -> list the partitions on the specified device "part uuid" can be useful when writing a bootcmd which searches all known devices for something bootable, and then wants the kernel to use the same partition as the root device, e.g.: part uuid ${devtype} ${devnum}:${rootpart} uuid setenv bootargs root=PARTUUID=${uuid} ... Signed-off-by: Stephen Warren --- common/Makefile | 1 + common/cmd_part.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 common/cmd_part.c diff --git a/common/Makefile b/common/Makefile index 482795e..b56df1d 100644 --- a/common/Makefile +++ b/common/Makefile @@ -136,6 +136,7 @@ COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o COBJS-$(CONFIG_CMD_NET) += cmd_net.o COBJS-$(CONFIG_CMD_ONENAND) += cmd_onenand.o COBJS-$(CONFIG_CMD_OTP) += cmd_otp.o +COBJS-$(CONFIG_CMD_PART) += cmd_part.o ifdef CONFIG_PCI COBJS-$(CONFIG_CMD_PCI) += cmd_pci.o endif diff --git a/common/cmd_part.c b/common/cmd_part.c new file mode 100644 index 0000000..d997597 --- /dev/null +++ b/common/cmd_part.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * made from cmd_ext2, which was: + * + * (C) Copyright 2004 + * esd gmbh + * Reinhard Arlt + * + * made from cmd_reiserfs by + * + * (C) Copyright 2003 - 2004 + * Sysgo Real-Time Solutions, AG + * Pavel Bartusek + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#ifndef CONFIG_PARTITION_UUIDS +#error CONFIG_PARTITION_UUIDS must be enabled for CONFIG_CMD_PART to be enabled +#endif + +int do_part_uuid(int argc, char * const argv[]) +{ + int part; + block_dev_desc_t *dev_desc; + disk_partition_t info; + + if (argc < 2) + return CMD_RET_USAGE; + if (argc > 3) + return CMD_RET_USAGE; + + part = get_device_and_partition(argv[0], argv[1], &dev_desc, &info, 0); + if (part < 0) + return 1; + + if (argc > 2) + setenv(argv[2], info.uuid); + else + printf("%s\n", info.uuid); + + return 0; +} + +int do_part_list(int argc, char * const argv[]) +{ + int ret; + block_dev_desc_t *desc; + + if (argc != 2) + return CMD_RET_USAGE; + + ret = get_device(argv[0], argv[1], &desc); + if (ret < 0) + return 1; + + print_part(desc); + + return 0; +} + +int do_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc < 2) + return CMD_RET_USAGE; + + if (!strcmp(argv[1], "uuid")) + return do_part_uuid(argc - 2, argv + 2); + else if (!strcmp(argv[1], "list")) + return do_part_list(argc - 2, argv + 2); + + return CMD_RET_USAGE; +} + +U_BOOT_CMD( + part, 5, 1, do_part, + "disk partition related commands", + "part uuid :\n" + " - print partition UUID\n" + "part uuid : \n" + " - set environment variable to partition UUID\n" + "part list \n" + " - print a device's partition table" +); -- cgit v1.1 From e1dbdf9109a2739862ccd3c39be0b8ee37721cb6 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 22 Aug 2012 11:04:57 +0000 Subject: net: introduce transparent driver private in ueth_data Avoid clutter in ueth_data. Individual drivers should not mess with structures belonging to the core like this. Signed-off-by: Lucas Stach Reviewed-by: Marek Vasut Acked-by: Marek Vasut Acked-by: Joe Hershberger --- drivers/usb/eth/smsc95xx.c | 49 +++++++++++++++++++++++++++++++++------------- include/usb_ether.h | 8 ++------ 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c index c62a8c1..dc5ca65 100644 --- a/drivers/usb/eth/smsc95xx.c +++ b/drivers/usb/eth/smsc95xx.c @@ -25,6 +25,7 @@ #include #include #include "usb_ether.h" +#include /* SMSC LAN95xx based USB 2.0 Ethernet Devices */ @@ -146,6 +147,12 @@ /* local vars */ static int curr_eth_dev; /* index for name of next device detected */ +/* driver private */ +struct smsc95xx_private { + size_t rx_urb_size; /* maximum USB URB size */ + u32 mac_cr; /* MAC control register value */ + int have_hwaddr; /* 1 if we have a hardware MAC address */ +}; /* * Smsc95xx infrastructure commands @@ -377,6 +384,7 @@ static int smsc95xx_init_mac_address(struct eth_device *eth, static int smsc95xx_write_hwaddr(struct eth_device *eth) { struct ueth_data *dev = (struct ueth_data *)eth->priv; + struct smsc95xx_private *priv = dev->dev_priv; u32 addr_lo = __get_unaligned_le32(ð->enetaddr[0]); u32 addr_hi = __get_unaligned_le16(ð->enetaddr[4]); int ret; @@ -392,7 +400,7 @@ static int smsc95xx_write_hwaddr(struct eth_device *eth) return ret; debug("MAC %pM\n", eth->enetaddr); - dev->have_hwaddr = 1; + priv->have_hwaddr = 1; return 0; } @@ -425,19 +433,22 @@ static int smsc95xx_set_csums(struct ueth_data *dev, static void smsc95xx_set_multicast(struct ueth_data *dev) { + struct smsc95xx_private *priv = dev->dev_priv; + /* No multicast in u-boot */ - dev->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_); + priv->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_); } /* starts the TX path */ static void smsc95xx_start_tx_path(struct ueth_data *dev) { + struct smsc95xx_private *priv = dev->dev_priv; u32 reg_val; /* Enable Tx at MAC */ - dev->mac_cr |= MAC_CR_TXEN_; + priv->mac_cr |= MAC_CR_TXEN_; - smsc95xx_write_reg(dev, MAC_CR, dev->mac_cr); + smsc95xx_write_reg(dev, MAC_CR, priv->mac_cr); /* Enable Tx at SCSRs */ reg_val = TX_CFG_ON_; @@ -447,8 +458,10 @@ static void smsc95xx_start_tx_path(struct ueth_data *dev) /* Starts the Receive path */ static void smsc95xx_start_rx_path(struct ueth_data *dev) { - dev->mac_cr |= MAC_CR_RXEN_; - smsc95xx_write_reg(dev, MAC_CR, dev->mac_cr); + struct smsc95xx_private *priv = dev->dev_priv; + + priv->mac_cr |= MAC_CR_RXEN_; + smsc95xx_write_reg(dev, MAC_CR, priv->mac_cr); } /* @@ -462,6 +475,8 @@ static int smsc95xx_init(struct eth_device *eth, bd_t *bd) u32 burst_cap; int timeout; struct ueth_data *dev = (struct ueth_data *)eth->priv; + struct smsc95xx_private *priv = + (struct smsc95xx_private *)dev->dev_priv; #define TIMEOUT_RESOLUTION 50 /* ms */ int link_detected; @@ -504,9 +519,9 @@ static int smsc95xx_init(struct eth_device *eth, bd_t *bd) debug("timeout waiting for PHY Reset\n"); return -1; } - if (!dev->have_hwaddr && smsc95xx_init_mac_address(eth, dev) == 0) - dev->have_hwaddr = 1; - if (!dev->have_hwaddr) { + if (!priv->have_hwaddr && smsc95xx_init_mac_address(eth, dev) == 0) + priv->have_hwaddr = 1; + if (!priv->have_hwaddr) { puts("Error: SMSC95xx: No MAC address set - set usbethaddr\n"); return -1; } @@ -532,16 +547,16 @@ static int smsc95xx_init(struct eth_device *eth, bd_t *bd) #ifdef TURBO_MODE if (dev->pusb_dev->speed == USB_SPEED_HIGH) { burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE; - dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; + priv->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE; } else { burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE; - dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; + priv->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE; } #else burst_cap = 0; - dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE; + priv->rx_urb_size = MAX_SINGLE_PACKET_SIZE; #endif - debug("rx_urb_size=%ld\n", (ulong)dev->rx_urb_size); + debug("rx_urb_size=%ld\n", (ulong)priv->rx_urb_size); ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap); if (ret < 0) @@ -606,7 +621,7 @@ static int smsc95xx_init(struct eth_device *eth, bd_t *bd) if (ret < 0) return ret; - ret = smsc95xx_read_reg(dev, MAC_CR, &dev->mac_cr); + ret = smsc95xx_read_reg(dev, MAC_CR, &priv->mac_cr); if (ret < 0) return ret; @@ -857,6 +872,12 @@ int smsc95xx_eth_probe(struct usb_device *dev, unsigned int ifnum, return 0; } dev->privptr = (void *)ss; + + /* alloc driver private */ + ss->dev_priv = calloc(1, sizeof(struct smsc95xx_private)); + if (!ss->dev_priv) + return 0; + return 1; } diff --git a/include/usb_ether.h b/include/usb_ether.h index a7fb26b..7c7aecb 100644 --- a/include/usb_ether.h +++ b/include/usb_ether.h @@ -50,12 +50,8 @@ struct ueth_data { unsigned char protocol; /* .............. */ unsigned char irqinterval; /* Intervall for IRQ Pipe */ - /* private fields for each driver can go here if needed */ -#ifdef CONFIG_USB_ETHER_SMSC95XX - size_t rx_urb_size; /* maximum USB URB size */ - u32 mac_cr; /* MAC control register value */ - int have_hwaddr; /* 1 if we have a hardware MAC address */ -#endif + /* driver private */ + void *dev_priv; }; /* -- cgit v1.1 From 5fae53d0f1554d35f159a386cd16edf94838279d Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 22 Aug 2012 11:04:58 +0000 Subject: net: asix: split out basic reset function The basic device reset ensures that the device is ready to service commands and does not need to get redone before each network operation. Split out the basic reset from asix_init() and instead call it from asix_eth_get_info(), so that it only gets called once. Signed-off-by: Lucas Stach Acked-by: Joe Hershberger --- drivers/usb/eth/asix.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c index 8fb7fc8..50cbbbd 100644 --- a/drivers/usb/eth/asix.c +++ b/drivers/usb/eth/asix.c @@ -310,55 +310,60 @@ static int mii_nway_restart(struct ueth_data *dev) return r; } -/* - * Asix callbacks - */ -static int asix_init(struct eth_device *eth, bd_t *bd) +static int asix_basic_reset(struct ueth_data *dev) { int embd_phy; - ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN); u16 rx_ctl; - struct ueth_data *dev = (struct ueth_data *)eth->priv; - int timeout = 0; -#define TIMEOUT_RESOLUTION 50 /* ms */ - int link_detected; - - debug("** %s()\n", __func__); if (asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5) < 0) - goto out_err; + return -1; /* 0x10 is the phy id of the embedded 10/100 ethernet phy */ embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); if (asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL) < 0) { debug("Select PHY #1 failed\n"); - goto out_err; + return -1; } if (asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL) < 0) - goto out_err; + return -1; if (asix_sw_reset(dev, AX_SWRESET_CLEAR) < 0) - goto out_err; + return -1; if (embd_phy) { if (asix_sw_reset(dev, AX_SWRESET_IPRL) < 0) - goto out_err; + return -1; } else { if (asix_sw_reset(dev, AX_SWRESET_PRTE) < 0) - goto out_err; + return -1; } rx_ctl = asix_read_rx_ctl(dev); debug("RX_CTL is 0x%04x after software reset\n", rx_ctl); if (asix_write_rx_ctl(dev, 0x0000) < 0) - goto out_err; + return -1; rx_ctl = asix_read_rx_ctl(dev); debug("RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); + return 0; +} + +/* + * Asix callbacks + */ +static int asix_init(struct eth_device *eth, bd_t *bd) +{ + struct ueth_data *dev = (struct ueth_data *)eth->priv; + int timeout = 0; +#define TIMEOUT_RESOLUTION 50 /* ms */ + int link_detected; + + debug("** %s()\n", __func__); + /* Get the MAC address */ if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf) < 0) { @@ -635,5 +640,8 @@ int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss, eth->halt = asix_halt; eth->priv = ss; + if (asix_basic_reset(ss)) + return 0; + return 1; } -- cgit v1.1 From 58f8fab8a444424e9f0dcb8f6218350a736b5f62 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 22 Aug 2012 11:04:59 +0000 Subject: net: asix: add write_hwaddr function All ASIX chipsets aside from AX88172 are able to set the MAC address on the hardware level. Add a function to expose this ability. To differentiate between chip types we now carry flags as driver private data. Also while touching the asix_dongles array constify this. Signed-off-by: Lucas Stach Acked-by: Joe Hershberger --- drivers/usb/eth/asix.c | 63 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c index 50cbbbd..bbfa2d1 100644 --- a/drivers/usb/eth/asix.c +++ b/drivers/usb/eth/asix.c @@ -23,6 +23,7 @@ #include #include #include "usb_ether.h" +#include /* ASIX AX8817X based USB 2.0 Ethernet Devices */ @@ -35,6 +36,7 @@ #define AX_CMD_WRITE_RX_CTL 0x10 #define AX_CMD_WRITE_IPG0 0x12 #define AX_CMD_READ_NODE_ID 0x13 +#define AX_CMD_WRITE_NODE_ID 0x14 #define AX_CMD_READ_PHY_ID 0x19 #define AX_CMD_WRITE_MEDIUM_MODE 0x1b #define AX_CMD_WRITE_GPIOS 0x1f @@ -97,9 +99,19 @@ #define AX_RX_URB_SIZE 2048 #define PHY_CONNECT_TIMEOUT 5000 +/* asix_flags defines */ +#define FLAG_NONE 0 +#define FLAG_TYPE_AX88172 (1U << 0) +#define FLAG_TYPE_AX88772 (1U << 1) + /* local vars */ static int curr_eth_dev; /* index for name of next device detected */ +/* driver private */ +struct asix_private { + int flags; +}; + /* * Asix infrastructure commands */ @@ -284,6 +296,21 @@ static int asix_write_gpio(struct ueth_data *dev, u16 value, int sleep) return ret; } +static int asix_write_hwaddr(struct eth_device *eth) +{ + struct ueth_data *dev = (struct ueth_data *)eth->priv; + int ret; + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN); + + memcpy(buf, eth->enetaddr, ETH_ALEN); + + ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, buf); + if (ret < 0) + debug("Failed to set MAC address: %02x\n", ret); + + return ret; +} + /* * mii commands */ @@ -539,19 +566,22 @@ void asix_eth_before_probe(void) struct asix_dongle { unsigned short vendor; unsigned short product; + int flags; }; -static struct asix_dongle asix_dongles[] = { - { 0x05ac, 0x1402 }, /* Apple USB Ethernet Adapter */ - { 0x07d1, 0x3c05 }, /* D-Link DUB-E100 H/W Ver B1 */ - { 0x0b95, 0x772a }, /* Cables-to-Go USB Ethernet Adapter */ - { 0x0b95, 0x7720 }, /* Trendnet TU2-ET100 V3.0R */ - { 0x0b95, 0x1720 }, /* SMC */ - { 0x0db0, 0xa877 }, /* MSI - ASIX 88772a */ - { 0x13b1, 0x0018 }, /* Linksys 200M v2.1 */ - { 0x1557, 0x7720 }, /* 0Q0 cable ethernet */ - { 0x2001, 0x3c05 }, /* DLink DUB-E100 H/W Ver B1 Alternate */ - { 0x0000, 0x0000 } /* END - Do not remove */ +static const struct asix_dongle const asix_dongles[] = { + { 0x05ac, 0x1402, FLAG_TYPE_AX88772 }, /* Apple USB Ethernet Adapter */ + { 0x07d1, 0x3c05, FLAG_TYPE_AX88772 }, /* D-Link DUB-E100 H/W Ver B1 */ + /* Cables-to-Go USB Ethernet Adapter */ + { 0x0b95, 0x772a, FLAG_TYPE_AX88772 }, + { 0x0b95, 0x7720, FLAG_TYPE_AX88772 }, /* Trendnet TU2-ET100 V3.0R */ + { 0x0b95, 0x1720, FLAG_TYPE_AX88172 }, /* SMC */ + { 0x0db0, 0xa877, FLAG_TYPE_AX88772 }, /* MSI - ASIX 88772a */ + { 0x13b1, 0x0018, FLAG_TYPE_AX88172 }, /* Linksys 200M v2.1 */ + { 0x1557, 0x7720, FLAG_TYPE_AX88772 }, /* 0Q0 cable ethernet */ + /* DLink DUB-E100 H/W Ver B1 Alternate */ + { 0x2001, 0x3c05, FLAG_TYPE_AX88772 }, + { 0x0000, 0x0000, FLAG_NONE } /* END - Do not remove */ }; /* Probe to see if a new device is actually an asix device */ @@ -588,6 +618,13 @@ int asix_eth_probe(struct usb_device *dev, unsigned int ifnum, ss->subclass = iface_desc->bInterfaceSubClass; ss->protocol = iface_desc->bInterfaceProtocol; + /* alloc driver private */ + ss->dev_priv = calloc(1, sizeof(struct asix_private)); + if (!ss->dev_priv) + return 0; + + ((struct asix_private *)ss->dev_priv)->flags = asix_dongles[i].flags; + /* * We are expecting a minimum of 3 endpoints - in, out (bulk), and * int. We will ignore any others. @@ -629,6 +666,8 @@ int asix_eth_probe(struct usb_device *dev, unsigned int ifnum, int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss, struct eth_device *eth) { + struct asix_private *priv = (struct asix_private *)ss->dev_priv; + if (!eth) { debug("%s: missing parameter.\n", __func__); return 0; @@ -638,6 +677,8 @@ int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss, eth->send = asix_send; eth->recv = asix_recv; eth->halt = asix_halt; + if (!(priv->flags & FLAG_TYPE_AX88172)) + eth->write_hwaddr = asix_write_hwaddr; eth->priv = ss; if (asix_basic_reset(ss)) -- cgit v1.1 From 02c8d8cc6e52b29deabab179e365281131316cf1 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 22 Aug 2012 11:05:00 +0000 Subject: net: asix: add read_mac function Initial device MAC should be read while getting info about the device, so it's wrong to only read it in asix_init(). Add a dedicated function to read the initial MAC, which is also able to handle devices that have their initial MAC stored in EEPROM. Call this function inasix_eth_get_info(). Signed-off-by: Lucas Stach Reviewed-by: Marek Vasut Acked-by: Marek Vasut Acked-by: Joe Hershberger --- drivers/usb/eth/asix.c | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c index bbfa2d1..604d720 100644 --- a/drivers/usb/eth/asix.c +++ b/drivers/usb/eth/asix.c @@ -32,6 +32,7 @@ #define AX_CMD_READ_MII_REG 0x07 #define AX_CMD_WRITE_MII_REG 0x08 #define AX_CMD_SET_HW_MII 0x0a +#define AX_CMD_READ_EEPROM 0x0b #define AX_CMD_READ_RX_CTL 0x0f #define AX_CMD_WRITE_RX_CTL 0x10 #define AX_CMD_WRITE_IPG0 0x12 @@ -103,6 +104,7 @@ #define FLAG_NONE 0 #define FLAG_TYPE_AX88172 (1U << 0) #define FLAG_TYPE_AX88772 (1U << 1) +#define FLAG_EEPROM_MAC (1U << 2) /* initial mac address in eeprom */ /* local vars */ static int curr_eth_dev; /* index for name of next device detected */ @@ -337,6 +339,34 @@ static int mii_nway_restart(struct ueth_data *dev) return r; } +static int asix_read_mac(struct eth_device *eth) +{ + struct ueth_data *dev = (struct ueth_data *)eth->priv; + struct asix_private *priv = (struct asix_private *)dev->dev_priv; + int i; + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN); + + if (priv->flags & FLAG_EEPROM_MAC) { + for (i = 0; i < (ETH_ALEN >> 1); i++) { + if (asix_read_cmd(dev, AX_CMD_READ_EEPROM, + 0x04 + i, 0, 2, buf) < 0) { + debug("Failed to read SROM address 04h.\n"); + return -1; + } + memcpy((eth->enetaddr + i * 2), buf, 2); + } + } else { + if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf) + < 0) { + debug("Failed to read MAC address.\n"); + return -1; + } + memcpy(eth->enetaddr, buf, ETH_ALEN); + } + + return 0; +} + static int asix_basic_reset(struct ueth_data *dev) { int embd_phy; @@ -391,18 +421,6 @@ static int asix_init(struct eth_device *eth, bd_t *bd) debug("** %s()\n", __func__); - /* Get the MAC address */ - if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID, - 0, 0, ETH_ALEN, buf) < 0) { - debug("Failed to read MAC address.\n"); - goto out_err; - } - memcpy(eth->enetaddr, buf, ETH_ALEN); - debug("MAC %02x:%02x:%02x:%02x:%02x:%02x\n", - eth->enetaddr[0], eth->enetaddr[1], - eth->enetaddr[2], eth->enetaddr[3], - eth->enetaddr[4], eth->enetaddr[5]); - dev->phy_id = asix_get_phy_addr(dev); if (dev->phy_id < 0) debug("Failed to read phy id\n"); @@ -684,5 +702,10 @@ int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss, if (asix_basic_reset(ss)) return 0; + /* Get the MAC address */ + if (asix_read_mac(eth)) + return 0; + debug("MAC %pM\n", eth->enetaddr); + return 1; } -- cgit v1.1 From 1dff9d0f54a0cec2dfda6022862bbdc38ba97d77 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 22 Aug 2012 11:05:01 +0000 Subject: net: asix: add AX88772B support Add AX88772B ID together with two fixes needed to make this work. 1. The packet length check has to be adjusted, as all ASIX chips only use 11 bits to indicate the length. AX88772B uses the other bits to indicate unrelated things, which cause the check to fail. This fix is based on a fix for the Linux kernel by Marek Vasut. Linux upstream commit: bca0beb9363f8487ac902931a50eb00180a2d14a 2. AX88772B provides several bulk endpoints. Only the first IN/OUT endpoints work in the default configuration. So stop enumeration after we found them to avoid overwriting the endpoint config with a non-working one. Signed-off-by: Lucas Stach Reviewed-by: Marek Vasut Acked-by: Marek Vasut Acked-by: Joe Hershberger --- drivers/usb/eth/asix.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c index 604d720..75ec8f7 100644 --- a/drivers/usb/eth/asix.c +++ b/drivers/usb/eth/asix.c @@ -104,7 +104,8 @@ #define FLAG_NONE 0 #define FLAG_TYPE_AX88172 (1U << 0) #define FLAG_TYPE_AX88772 (1U << 1) -#define FLAG_EEPROM_MAC (1U << 2) /* initial mac address in eeprom */ +#define FLAG_TYPE_AX88772B (1U << 2) +#define FLAG_EEPROM_MAC (1U << 3) /* initial mac address in eeprom */ /* local vars */ static int curr_eth_dev; /* index for name of next device detected */ @@ -543,13 +544,13 @@ static int asix_recv(struct eth_device *eth) } memcpy(&packet_len, buf_ptr, sizeof(packet_len)); le32_to_cpus(&packet_len); - if (((packet_len >> 16) ^ 0xffff) != (packet_len & 0xffff)) { + if (((~packet_len >> 16) & 0x7ff) != (packet_len & 0x7ff)) { debug("Rx: malformed packet length: %#x (%#x:%#x)\n", - packet_len, (packet_len >> 16) ^ 0xffff, - packet_len & 0xffff); + packet_len, (~packet_len >> 16) & 0x7ff, + packet_len & 0x7ff); return -1; } - packet_len = packet_len & 0xffff; + packet_len = packet_len & 0x7ff; if (packet_len > actual_len - sizeof(packet_len)) { debug("Rx: too large packet: %d\n", packet_len); return -1; @@ -599,6 +600,8 @@ static const struct asix_dongle const asix_dongles[] = { { 0x1557, 0x7720, FLAG_TYPE_AX88772 }, /* 0Q0 cable ethernet */ /* DLink DUB-E100 H/W Ver B1 Alternate */ { 0x2001, 0x3c05, FLAG_TYPE_AX88772 }, + /* ASIX 88772B */ + { 0x0b95, 0x772b, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC }, { 0x0000, 0x0000, FLAG_NONE } /* END - Do not remove */ }; @@ -608,6 +611,7 @@ int asix_eth_probe(struct usb_device *dev, unsigned int ifnum, { struct usb_interface *iface; struct usb_interface_descriptor *iface_desc; + int ep_in_found = 0, ep_out_found = 0; int i; /* let's examine the device now */ @@ -651,13 +655,20 @@ int asix_eth_probe(struct usb_device *dev, unsigned int ifnum, /* is it an BULK endpoint? */ if ((iface->ep_desc[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) { - if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN) - ss->ep_in = iface->ep_desc[i].bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; - else - ss->ep_out = - iface->ep_desc[i].bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; + u8 ep_addr = iface->ep_desc[i].bEndpointAddress; + if (ep_addr & USB_DIR_IN) { + if (!ep_in_found) { + ss->ep_in = ep_addr & + USB_ENDPOINT_NUMBER_MASK; + ep_in_found = 1; + } + } else { + if (!ep_out_found) { + ss->ep_out = ep_addr & + USB_ENDPOINT_NUMBER_MASK; + ep_out_found = 1; + } + } } /* is it an interrupt endpoint? */ -- cgit v1.1 From 185f7d9afc9b5c77bbedc386a43019e07e5d0c04 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 13 Sep 2012 20:23:34 +0000 Subject: net: Add driver for Zynq Gem IP Device driver for Zynq Gem IP. Signed-off-by: Michal Simek CC: Joe Hershberger CC: Marek Vasut Acked-by: Marek Vasut --- drivers/net/Makefile | 1 + drivers/net/zynq_gem.c | 440 +++++++++++++++++++++++++++++++++++++++++++++++++ include/netdev.h | 2 +- 3 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 drivers/net/zynq_gem.c diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 011cd51..e4abac7 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -80,6 +80,7 @@ COBJS-$(CONFIG_XILINX_AXIEMAC) += xilinx_axi_emac.o COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o COBJS-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \ xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o +COBJS-$(CONFIG_ZYNQ_GEM) += zynq_gem.o COBJS := $(sort $(COBJS-y)) SRCS := $(COBJS:.o=.c) diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c new file mode 100644 index 0000000..3596065 --- /dev/null +++ b/drivers/net/zynq_gem.c @@ -0,0 +1,440 @@ +/* + * (C) Copyright 2011 Michal Simek + * + * Michal SIMEK + * + * Based on Xilinx gmac driver: + * (C) Copyright 2011 Xilinx + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(CONFIG_PHYLIB) +# error XILINX_GEM_ETHERNET requires PHYLIB +#endif + +/* Bit/mask specification */ +#define ZYNQ_GEM_PHYMNTNC_OP_MASK 0x40020000 /* operation mask bits */ +#define ZYNQ_GEM_PHYMNTNC_OP_R_MASK 0x20000000 /* read operation */ +#define ZYNQ_GEM_PHYMNTNC_OP_W_MASK 0x10000000 /* write operation */ +#define ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK 23 /* Shift bits for PHYAD */ +#define ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK 18 /* Shift bits for PHREG */ + +#define ZYNQ_GEM_RXBUF_EOF_MASK 0x00008000 /* End of frame. */ +#define ZYNQ_GEM_RXBUF_SOF_MASK 0x00004000 /* Start of frame. */ +#define ZYNQ_GEM_RXBUF_LEN_MASK 0x00003FFF /* Mask for length field */ + +#define ZYNQ_GEM_RXBUF_WRAP_MASK 0x00000002 /* Wrap bit, last BD */ +#define ZYNQ_GEM_RXBUF_NEW_MASK 0x00000001 /* Used bit.. */ +#define ZYNQ_GEM_RXBUF_ADD_MASK 0xFFFFFFFC /* Mask for address */ + +/* Wrap bit, last descriptor */ +#define ZYNQ_GEM_TXBUF_WRAP_MASK 0x40000000 +#define ZYNQ_GEM_TXBUF_LAST_MASK 0x00008000 /* Last buffer */ + +#define ZYNQ_GEM_TXSR_HRESPNOK_MASK 0x00000100 /* Transmit hresp not OK */ +#define ZYNQ_GEM_TXSR_URUN_MASK 0x00000040 /* Transmit underrun */ +/* Transmit buffs exhausted mid frame */ +#define ZYNQ_GEM_TXSR_BUFEXH_MASK 0x00000010 + +#define ZYNQ_GEM_NWCTRL_TXEN_MASK 0x00000008 /* Enable transmit */ +#define ZYNQ_GEM_NWCTRL_RXEN_MASK 0x00000004 /* Enable receive */ +#define ZYNQ_GEM_NWCTRL_MDEN_MASK 0x00000010 /* Enable MDIO port */ +#define ZYNQ_GEM_NWCTRL_STARTTX_MASK 0x00000200 /* Start tx (tx_go) */ + +#define ZYNQ_GEM_NWCFG_SPEED 0x00000001 /* 100 Mbps operation */ +#define ZYNQ_GEM_NWCFG_FDEN 0x00000002 /* Full Duplex mode */ +#define ZYNQ_GEM_NWCFG_FSREM 0x00020000 /* FCS removal */ +#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000080000 /* Div pclk by 32, 80MHz */ + +#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_NWCFG_SPEED | \ + ZYNQ_GEM_NWCFG_FDEN | \ + ZYNQ_GEM_NWCFG_FSREM | \ + ZYNQ_GEM_NWCFG_MDCCLKDIV) + +#define ZYNQ_GEM_NWSR_MDIOIDLE_MASK 0x00000004 /* PHY management idle */ + +#define ZYNQ_GEM_DMACR_BLENGTH 0x00000004 /* INCR4 AHB bursts */ +/* Use full configured addressable space (8 Kb) */ +#define ZYNQ_GEM_DMACR_RXSIZE 0x00000300 +/* Use full configured addressable space (4 Kb) */ +#define ZYNQ_GEM_DMACR_TXSIZE 0x00000400 +/* Set with binary 00011000 to use 1536 byte(1*max length frame/buffer) */ +#define ZYNQ_GEM_DMACR_RXBUF 0x00180000 + +#define ZYNQ_GEM_DMACR_INIT (ZYNQ_GEM_DMACR_BLENGTH | \ + ZYNQ_GEM_DMACR_RXSIZE | \ + ZYNQ_GEM_DMACR_TXSIZE | \ + ZYNQ_GEM_DMACR_RXBUF) + +/* Device registers */ +struct zynq_gem_regs { + u32 nwctrl; /* Network Control reg */ + u32 nwcfg; /* Network Config reg */ + u32 nwsr; /* Network Status reg */ + u32 reserved1; + u32 dmacr; /* DMA Control reg */ + u32 txsr; /* TX Status reg */ + u32 rxqbase; /* RX Q Base address reg */ + u32 txqbase; /* TX Q Base address reg */ + u32 rxsr; /* RX Status reg */ + u32 reserved2[2]; + u32 idr; /* Interrupt Disable reg */ + u32 reserved3; + u32 phymntnc; /* Phy Maintaince reg */ + u32 reserved4[18]; + u32 hashl; /* Hash Low address reg */ + u32 hashh; /* Hash High address reg */ +#define LADDR_LOW 0 +#define LADDR_HIGH 1 + u32 laddr[4][LADDR_HIGH + 1]; /* Specific1 addr low/high reg */ + u32 match[4]; /* Type ID1 Match reg */ + u32 reserved6[18]; + u32 stat[44]; /* Octects transmitted Low reg - stat start */ +}; + +/* BD descriptors */ +struct emac_bd { + u32 addr; /* Next descriptor pointer */ + u32 status; +}; + +#define RX_BUF 3 + +/* Initialized, rxbd_current, rx_first_buf must be 0 after init */ +struct zynq_gem_priv { + struct emac_bd tx_bd; + struct emac_bd rx_bd[RX_BUF]; + char rxbuffers[RX_BUF * PKTSIZE_ALIGN]; + u32 rxbd_current; + u32 rx_first_buf; + int phyaddr; + struct phy_device *phydev; + struct mii_dev *bus; +}; + +static inline int mdio_wait(struct eth_device *dev) +{ + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + u32 timeout = 200; + + /* Wait till MDIO interface is ready to accept a new transaction. */ + while (--timeout) { + if (readl(®s->nwsr) & ZYNQ_GEM_NWSR_MDIOIDLE_MASK) + break; + WATCHDOG_RESET(); + } + + if (!timeout) { + printf("%s: Timeout\n", __func__); + return 1; + } + + return 0; +} + +static u32 phy_setup_op(struct eth_device *dev, u32 phy_addr, u32 regnum, + u32 op, u16 *data) +{ + u32 mgtcr; + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + + if (mdio_wait(dev)) + return 1; + + /* Construct mgtcr mask for the operation */ + mgtcr = ZYNQ_GEM_PHYMNTNC_OP_MASK | op | + (phy_addr << ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK) | + (regnum << ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK) | *data; + + /* Write mgtcr and wait for completion */ + writel(mgtcr, ®s->phymntnc); + + if (mdio_wait(dev)) + return 1; + + if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK) + *data = readl(®s->phymntnc); + + return 0; +} + +static u32 phyread(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 *val) +{ + return phy_setup_op(dev, phy_addr, regnum, + ZYNQ_GEM_PHYMNTNC_OP_R_MASK, val); +} + +static u32 phywrite(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 data) +{ + return phy_setup_op(dev, phy_addr, regnum, + ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data); +} + +static int zynq_gem_setup_mac(struct eth_device *dev) +{ + u32 i, macaddrlow, macaddrhigh; + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + + /* Set the MAC bits [31:0] in BOT */ + macaddrlow = dev->enetaddr[0]; + macaddrlow |= dev->enetaddr[1] << 8; + macaddrlow |= dev->enetaddr[2] << 16; + macaddrlow |= dev->enetaddr[3] << 24; + + /* Set MAC bits [47:32] in TOP */ + macaddrhigh = dev->enetaddr[4]; + macaddrhigh |= dev->enetaddr[5] << 8; + + for (i = 0; i < 4; i++) { + writel(0, ®s->laddr[i][LADDR_LOW]); + writel(0, ®s->laddr[i][LADDR_HIGH]); + /* Do not use MATCHx register */ + writel(0, ®s->match[i]); + } + + writel(macaddrlow, ®s->laddr[0][LADDR_LOW]); + writel(macaddrhigh, ®s->laddr[0][LADDR_HIGH]); + + return 0; +} + +static int zynq_gem_init(struct eth_device *dev, bd_t * bis) +{ + u32 i; + struct phy_device *phydev; + const u32 stat_size = (sizeof(struct zynq_gem_regs) - + offsetof(struct zynq_gem_regs, stat)) / 4; + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + struct zynq_gem_priv *priv = dev->priv; + const u32 supported = SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full; + + /* Disable all interrupts */ + writel(0xFFFFFFFF, ®s->idr); + + /* Disable the receiver & transmitter */ + writel(0, ®s->nwctrl); + writel(0, ®s->txsr); + writel(0, ®s->rxsr); + writel(0, ®s->phymntnc); + + /* Clear the Hash registers for the mac address pointed by AddressPtr */ + writel(0x0, ®s->hashl); + /* Write bits [63:32] in TOP */ + writel(0x0, ®s->hashh); + + /* Clear all counters */ + for (i = 0; i <= stat_size; i++) + readl(®s->stat[i]); + + /* Setup RxBD space */ + memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd)); + /* Create the RxBD ring */ + memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers)); + + for (i = 0; i < RX_BUF; i++) { + priv->rx_bd[i].status = 0xF0000000; + priv->rx_bd[i].addr = (u32)((char *) &(priv->rxbuffers) + + (i * PKTSIZE_ALIGN)); + } + /* WRAP bit to last BD */ + priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; + /* Write RxBDs to IP */ + writel((u32) &(priv->rx_bd), ®s->rxqbase); + + /* MAC Setup */ + /* Setup Network Configuration register */ + writel(ZYNQ_GEM_NWCFG_INIT, ®s->nwcfg); + + /* Setup for DMA Configuration register */ + writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); + + /* Setup for Network Control register, MDIO, Rx and Tx enable */ + setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK | + ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK); + + /* interface - look at tsec */ + phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0); + + phydev->supported &= supported; + phydev->advertising = phydev->supported; + priv->phydev = phydev; + phy_config(phydev); + phy_startup(phydev); + + return 0; +} + +static int zynq_gem_send(struct eth_device *dev, void *ptr, int len) +{ + u32 status; + struct zynq_gem_priv *priv = dev->priv; + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + const u32 mask = ZYNQ_GEM_TXSR_HRESPNOK_MASK | \ + ZYNQ_GEM_TXSR_URUN_MASK | ZYNQ_GEM_TXSR_BUFEXH_MASK; + + /* setup BD */ + writel((u32)&(priv->tx_bd), ®s->txqbase); + + /* Setup Tx BD */ + memset((void *) &(priv->tx_bd), 0, sizeof(struct emac_bd)); + + priv->tx_bd.addr = (u32)ptr; + priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK | + ZYNQ_GEM_TXBUF_WRAP_MASK; + + /* Start transmit */ + setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK); + + /* Read the stat register to know if the packet has been transmitted */ + status = readl(®s->txsr); + if (status & mask) + printf("Something has gone wrong here!? Status is 0x%x.\n", + status); + + /* Clear Tx status register before leaving . */ + writel(status, ®s->txsr); + return 0; +} + +/* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */ +static int zynq_gem_recv(struct eth_device *dev) +{ + int frame_len; + struct zynq_gem_priv *priv = dev->priv; + struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current]; + struct emac_bd *first_bd; + + if (!(current_bd->addr & ZYNQ_GEM_RXBUF_NEW_MASK)) + return 0; + + if (!(current_bd->status & + (ZYNQ_GEM_RXBUF_SOF_MASK | ZYNQ_GEM_RXBUF_EOF_MASK))) { + printf("GEM: SOF or EOF not set for last buffer received!\n"); + return 0; + } + + frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK; + if (frame_len) { + NetReceive((u8 *) (current_bd->addr & + ZYNQ_GEM_RXBUF_ADD_MASK), frame_len); + + if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) + priv->rx_first_buf = priv->rxbd_current; + else { + current_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; + current_bd->status = 0xF0000000; /* FIXME */ + } + + if (current_bd->status & ZYNQ_GEM_RXBUF_EOF_MASK) { + first_bd = &priv->rx_bd[priv->rx_first_buf]; + first_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; + first_bd->status = 0xF0000000; + } + + if ((++priv->rxbd_current) >= RX_BUF) + priv->rxbd_current = 0; + + return frame_len; + } + + return 0; +} + +static void zynq_gem_halt(struct eth_device *dev) +{ + struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; + + /* Disable the receiver & transmitter */ + writel(0, ®s->nwctrl); +} + +static int zynq_gem_miiphyread(const char *devname, uchar addr, + uchar reg, ushort *val) +{ + struct eth_device *dev = eth_get_dev(); + int ret; + + ret = phyread(dev, addr, reg, val); + debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, *val); + return ret; +} + +static int zynq_gem_miiphy_write(const char *devname, uchar addr, + uchar reg, ushort val) +{ + struct eth_device *dev = eth_get_dev(); + + debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val); + return phywrite(dev, addr, reg, val); +} + +int zynq_gem_initialize(bd_t *bis, int base_addr) +{ + struct eth_device *dev; + struct zynq_gem_priv *priv; + + dev = calloc(1, sizeof(*dev)); + if (dev == NULL) + return -1; + + dev->priv = calloc(1, sizeof(struct zynq_gem_priv)); + if (dev->priv == NULL) { + free(dev); + return -1; + } + priv = dev->priv; + +#ifdef CONFIG_PHY_ADDR + priv->phyaddr = CONFIG_PHY_ADDR; +#else + priv->phyaddr = -1; +#endif + + sprintf(dev->name, "Gem.%x", base_addr); + + dev->iobase = base_addr; + + dev->init = zynq_gem_init; + dev->halt = zynq_gem_halt; + dev->send = zynq_gem_send; + dev->recv = zynq_gem_recv; + dev->write_hwaddr = zynq_gem_setup_mac; + + eth_register(dev); + + miiphy_register(dev->name, zynq_gem_miiphyread, zynq_gem_miiphy_write); + priv->bus = miiphy_get_dev_by_name(dev->name); + + return 1; +} diff --git a/include/netdev.h b/include/netdev.h index d1aaf0c..b8d303d 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -104,7 +104,7 @@ int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr, int txpp, int rxpp); int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags, unsigned long ctrl_addr); - +int zynq_gem_initialize(bd_t *bis, int base_addr); /* * As long as the Xilinx xps_ll_temac ethernet driver has not its own interface * exported by a public hader file, we need a global definition at this point. -- cgit v1.1 From 00d0d2ad4e875a70e212ec12d17ad5f872f6033d Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Sun, 3 Jun 2012 12:40:04 +0000 Subject: malloc: remove extern declarations of malloc_bin_reloc() in board.c files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declare malloc_bin_reloc() in malloc.h and remove all extern declarations in various board.c files to get rid of one checkpatch.pl warning. Signed-off-by: Daniel Schwierzeck Cc: Wolfgang Denk Cc: Andreas Bießmann Cc: Jason Jin Cc: Macpaul Lin Cc: Daniel Hellstrom Acked-by: Andreas Bießmann --- arch/avr32/lib/board.c | 1 - arch/m68k/lib/board.c | 1 - arch/mips/lib/board.c | 1 - arch/nds32/lib/board.c | 2 -- arch/sparc/lib/board.c | 1 - include/malloc.h | 1 + 6 files changed, 1 insertion(+), 6 deletions(-) diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index d7a64b4..9d3b76e 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -250,7 +250,6 @@ void board_init_f(ulong board_type) void board_init_r(gd_t *new_gd, ulong dest_addr) { - extern void malloc_bin_reloc (void); #ifndef CONFIG_ENV_IS_NOWHERE extern char * env_name_spec; #endif diff --git a/arch/m68k/lib/board.c b/arch/m68k/lib/board.c index 65a8595..2add630 100644 --- a/arch/m68k/lib/board.c +++ b/arch/m68k/lib/board.c @@ -389,7 +389,6 @@ void board_init_r (gd_t *id, ulong dest_addr) { char *s; bd_t *bd; - extern void malloc_bin_reloc (void); #ifndef CONFIG_ENV_IS_NOWHERE extern char * env_name_spec; diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c index 62d47a8..b14b33e 100644 --- a/arch/mips/lib/board.c +++ b/arch/mips/lib/board.c @@ -248,7 +248,6 @@ void board_init_r(gd_t *id, ulong dest_addr) #ifndef CONFIG_SYS_NO_FLASH ulong size; #endif - extern void malloc_bin_reloc(void); #ifndef CONFIG_ENV_IS_NOWHERE extern char *env_name_spec; #endif diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c index 2164a50..17d3ee0 100644 --- a/arch/nds32/lib/board.c +++ b/arch/nds32/lib/board.c @@ -306,8 +306,6 @@ void board_init_r(gd_t *id, ulong dest_addr) bd_t *bd; ulong malloc_start; - extern void malloc_bin_reloc(void); - gd = id; bd = gd->bd; diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c index 6f33666..ff0e0f2 100644 --- a/arch/sparc/lib/board.c +++ b/arch/sparc/lib/board.c @@ -62,7 +62,6 @@ DECLARE_GLOBAL_DATA_PTR; */ extern void timer_interrupt_init(void); -extern void malloc_bin_reloc(void); extern int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]); extern int prom_init(void); diff --git a/include/malloc.h b/include/malloc.h index 6295929..84ecf79 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -937,6 +937,7 @@ extern ulong mem_malloc_end; extern ulong mem_malloc_brk; void mem_malloc_init(ulong start, ulong size); +void malloc_bin_reloc(void); #ifdef __cplusplus }; /* end of extern "C" */ -- cgit v1.1 From 244e6f97055aa86e446ed3a925fdfa3f2b8f8207 Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Sat, 18 Aug 2012 07:46:04 +0000 Subject: patman: Use reverse order for changelog Specially when many revisions are need for a patchset, the most interesting information is about the last set of changes so we output the changelog in reverse order to easy identification of most recent change set. Signed-off-by: Otavio Salvador Acked-by: Simon Glass --- tools/patman/series.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/patman/series.py b/tools/patman/series.py index 27528bf..ce36b23 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -145,18 +145,18 @@ class Series(dict): Return: The change log as a list of strings, one per line + Changes in v2: + - Jog the dial back closer to the widget + Changes in v1: - Fix the widget - Jog the dial - Changes in v2: - - Jog the dial back closer to the widget - etc. """ final = [] need_blank = False - for change in sorted(self.changes): + for change in sorted(self.changes, reverse=True): out = [] for this_commit, text in self.changes[change]: if commit and this_commit != commit: -- cgit v1.1 From 2d1d65838eacd314b989701bd2f9e2b657bbf62b Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 20 Sep 2012 06:02:43 +0000 Subject: README.commands: Document what UNDEF_SYM does Changes in v2: - Reword a bit more Signed-off-by: Tom Rini --- doc/README.commands | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/README.commands b/doc/README.commands index 27815d2..125f077 100644 --- a/doc/README.commands +++ b/doc/README.commands @@ -22,6 +22,13 @@ This makes it possible for the final link to extract all commands compiled into any object code and construct a static array so the command can be found in an array starting at __u_boot_cmd_start. +To ensure that the linker does not discard these symbols when linking +full U-Boot we generate a list of all the commands we have built (based +on the sections mentioned above) and use that to force the linker to +first enter the symbol as undefined in the output object so that there +is then a need for the symbol to be kept (this is the UNDEF_SYM logic in +the Makefile). + If a new board is defined do not forget to define the command section by writing in u-boot.lds ($(TOPDIR)/board/boardname/u-boot.lds) these 3 lines: -- cgit v1.1 From 3bb89e5bd5c0d3a12129b01fbb706a18ee56557e Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Sun, 23 Sep 2012 04:39:16 +0000 Subject: env: remove duplicated env_get_char_spec() env_fat and env_remote have an implementation of env_get_char_spec() function that is not different than the default. Remove the duplicated code. Signed-off-by: Igor Grinberg --- common/env_fat.c | 5 ----- common/env_remote.c | 5 ----- 2 files changed, 10 deletions(-) diff --git a/common/env_fat.c b/common/env_fat.c index bad92aa..ca76967 100644 --- a/common/env_fat.c +++ b/common/env_fat.c @@ -40,11 +40,6 @@ env_t *env_ptr; DECLARE_GLOBAL_DATA_PTR; -uchar env_get_char_spec(int index) -{ - return *((uchar *)(gd->env_addr + index)); -} - int env_init(void) { /* use default */ diff --git a/common/env_remote.c b/common/env_remote.c index a7b147b..6c10c90 100644 --- a/common/env_remote.c +++ b/common/env_remote.c @@ -41,11 +41,6 @@ DECLARE_GLOBAL_DATA_PTR; #define CONFIG_ENV_OFFSET 0 #endif -uchar env_get_char_spec(int index) -{ - return *((uchar *)(gd->env_addr + index)); -} - int env_init(void) { if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) { -- cgit v1.1 From 9aa90c1df09d6c0a43a5e000ba9d66d6f13b29cb Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Sun, 23 Sep 2012 05:25:21 +0000 Subject: env: checkpatch clean env_fat env_fat has several checkpatch warnings - clean those up. Signed-off-by: Igor Grinberg --- common/env_fat.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/common/env_fat.c b/common/env_fat.c index ca76967..6ef5318 100644 --- a/common/env_fat.c +++ b/common/env_fat.c @@ -58,6 +58,7 @@ int saveenv(void) block_dev_desc_t *dev_desc = NULL; int dev = FAT_ENV_DEVICE; int part = FAT_ENV_PART; + int err; res = (char *)&env_new.data; len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL); @@ -67,7 +68,7 @@ int saveenv(void) } #ifdef CONFIG_MMC - if (strcmp (FAT_ENV_INTERFACE, "mmc") == 0) { + if (strcmp(FAT_ENV_INTERFACE, "mmc") == 0) { struct mmc *mmc = find_mmc_device(dev); if (!mmc) { @@ -86,14 +87,17 @@ int saveenv(void) FAT_ENV_INTERFACE, dev); return 1; } - if (fat_register_device(dev_desc, part) != 0) { + + err = fat_register_device(dev_desc, part); + if (err) { printf("Failed to register %s%d:%d\n", FAT_ENV_INTERFACE, dev, part); return 1; } env_new.crc = crc32(0, env_new.data, ENV_SIZE); - if (file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)) == -1) { + err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)); + if (err == -1) { printf("\n** Unable to write \"%s\" from %s%d:%d **\n", FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part); return 1; @@ -110,9 +114,10 @@ void env_relocate_spec(void) block_dev_desc_t *dev_desc = NULL; int dev = FAT_ENV_DEVICE; int part = FAT_ENV_PART; + int err; #ifdef CONFIG_MMC - if (strcmp (FAT_ENV_INTERFACE, "mmc") == 0) { + if (strcmp(FAT_ENV_INTERFACE, "mmc") == 0) { struct mmc *mmc = find_mmc_device(dev); if (!mmc) { @@ -133,14 +138,17 @@ void env_relocate_spec(void) set_default_env(NULL); return; } - if (fat_register_device(dev_desc, part) != 0) { + + err = fat_register_device(dev_desc, part); + if (err) { printf("Failed to register %s%d:%d\n", FAT_ENV_INTERFACE, dev, part); set_default_env(NULL); return; } - if (file_fat_read(FAT_ENV_FILE, (unsigned char *)&buf, CONFIG_ENV_SIZE) == -1) { + err = file_fat_read(FAT_ENV_FILE, (uchar *)&buf, CONFIG_ENV_SIZE); + if (err == -1) { printf("\n** Unable to read \"%s\" from %s%d:%d **\n", FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part); set_default_env(NULL); -- cgit v1.1 From 1170e634dd2a6fdd541ae2153fd3fd73919da8fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Tue, 18 Sep 2012 08:14:56 +0000 Subject: FAT: Make it possible to read from any file position MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When storage devices contain files larger than the embedded RAM, it is useful to be able to read these files by chunks, e.g. for a software update to the embedded NAND Flash from an external storage device (USB stick, SD card, etc.). Hence, this patch makes it possible by adding a new FAT API to read files from a given position. This patch also adds this feature to the fatload command. Signed-off-by: Benoît Thébaudeau Cc: Wolfgang Denk Signed-off-by: Tom Rini --- common/cmd_fat.c | 25 ++++++++------ fs/fat/fat.c | 98 +++++++++++++++++++++++++++++++++++++++++++----------- fs/fat/fat_write.c | 18 +++++----- include/fat.h | 2 ++ 4 files changed, 105 insertions(+), 38 deletions(-) diff --git a/common/cmd_fat.c b/common/cmd_fat.c index 01e02f5..55585c6 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -37,7 +37,8 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { long size; unsigned long offset; - unsigned long count; + unsigned long count = 0; + unsigned long pos = 0; char buf [12]; block_dev_desc_t *dev_desc=NULL; disk_partition_t info; @@ -45,7 +46,7 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc < 5) { printf("usage: fatload [] " - " [bytes]\n"); + " [bytes [pos]]\n"); return 1; } @@ -60,11 +61,11 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 1; } offset = simple_strtoul(argv[3], NULL, 16); - if (argc == 6) + if (argc >= 6) count = simple_strtoul(argv[5], NULL, 16); - else - count = 0; - size = file_fat_read(argv[4], (unsigned char *)offset, count); + if (argc >= 7) + pos = simple_strtoul(argv[6], NULL, 16); + size = file_fat_read_at(argv[4], pos, (unsigned char *)offset, count); if(size==-1) { printf("\n** Unable to read \"%s\" from %s %d:%d **\n", @@ -82,11 +83,15 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) U_BOOT_CMD( - fatload, 6, 0, do_fat_fsload, + fatload, 7, 0, do_fat_fsload, "load binary file from a dos filesystem", - " [] [bytes]\n" - " - load binary file 'filename' from 'dev' on 'interface'\n" - " to address 'addr' from dos filesystem" + " [] [bytes [pos]]\n" + " - Load binary file 'filename' from 'dev' on 'interface'\n" + " to address 'addr' from dos filesystem.\n" + " 'pos' gives the file position to start loading from.\n" + " If 'pos' is omitted, 0 is used. 'pos' requires 'bytes'.\n" + " 'bytes' gives the size to load. If 'bytes' is 0 or omitted,\n" + " the load stops on end of file." ); int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 19f6a8c..41ae15e 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -328,13 +328,16 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size) } /* - * Read at most 'maxsize' bytes from the file associated with 'dentptr' + * Read at most 'maxsize' bytes from 'pos' in the file associated with 'dentptr' * into 'buffer'. * Return the number of bytes read or -1 on fatal errors. */ +__u8 get_contents_vfatname_block[MAX_CLUSTSIZE] + __aligned(ARCH_DMA_MINALIGN); + static long -get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer, - unsigned long maxsize) +get_contents(fsdata *mydata, dir_entry *dentptr, unsigned long pos, + __u8 *buffer, unsigned long maxsize) { unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0; unsigned int bytesperclust = mydata->clust_size * mydata->sect_size; @@ -344,12 +347,59 @@ get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer, debug("Filesize: %ld bytes\n", filesize); - if (maxsize > 0 && filesize > maxsize) - filesize = maxsize; + if (pos >= filesize) { + debug("Read position past EOF: %lu\n", pos); + return gotsize; + } + + if (maxsize > 0 && filesize > pos + maxsize) + filesize = pos + maxsize; debug("%ld bytes\n", filesize); actsize = bytesperclust; + + /* go to cluster at pos */ + while (actsize <= pos) { + curclust = get_fatent(mydata, curclust); + if (CHECK_CLUST(curclust, mydata->fatsize)) { + debug("curclust: 0x%x\n", curclust); + debug("Invalid FAT entry\n"); + return gotsize; + } + actsize += bytesperclust; + } + + /* actsize > pos */ + actsize -= bytesperclust; + filesize -= actsize; + pos -= actsize; + + /* align to beginning of next cluster if any */ + if (pos) { + actsize = min(filesize, bytesperclust); + if (get_cluster(mydata, curclust, get_contents_vfatname_block, + (int)actsize) != 0) { + printf("Error reading cluster\n"); + return -1; + } + filesize -= actsize; + actsize -= pos; + memcpy(buffer, get_contents_vfatname_block + pos, actsize); + gotsize += actsize; + if (!filesize) + return gotsize; + buffer += actsize; + + curclust = get_fatent(mydata, curclust); + if (CHECK_CLUST(curclust, mydata->fatsize)) { + debug("curclust: 0x%x\n", curclust); + debug("Invalid FAT entry\n"); + return gotsize; + } + } + + actsize = bytesperclust; endclust = curclust; do { @@ -433,9 +483,6 @@ static int slot2str(dir_slot *slotptr, char *l_name, int *idx) * into 'retdent' * Return 0 on success, -1 otherwise. */ -__u8 get_vfatname_block[MAX_CLUSTSIZE] - __aligned(ARCH_DMA_MINALIGN); - static int get_vfatname(fsdata *mydata, int curclust, __u8 *cluster, dir_entry *retdent, char *l_name) @@ -474,13 +521,13 @@ get_vfatname(fsdata *mydata, int curclust, __u8 *cluster, return -1; } - if (get_cluster(mydata, curclust, get_vfatname_block, + if (get_cluster(mydata, curclust, get_contents_vfatname_block, mydata->clust_size * mydata->sect_size) != 0) { debug("Error: reading directory block\n"); return -1; } - slotptr2 = (dir_slot *)get_vfatname_block; + slotptr2 = (dir_slot *)get_contents_vfatname_block; while (counter > 0) { if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter) @@ -491,7 +538,7 @@ get_vfatname(fsdata *mydata, int curclust, __u8 *cluster, /* Save the real directory entry */ realdent = (dir_entry *)slotptr2; - while ((__u8 *)slotptr2 > get_vfatname_block) { + while ((__u8 *)slotptr2 > get_contents_vfatname_block) { slotptr2--; slot2str(slotptr2, l_name, &idx); } @@ -770,11 +817,12 @@ exit: return ret; } -__u8 do_fat_read_block[MAX_CLUSTSIZE] +__u8 do_fat_read_at_block[MAX_CLUSTSIZE] __aligned(ARCH_DMA_MINALIGN); long -do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) +do_fat_read_at(const char *filename, unsigned long pos, void *buffer, + unsigned long maxsize, int dols) { char fnamecopy[2048]; boot_sector bs; @@ -888,12 +936,12 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) (mydata->fatsize == 32) ? (mydata->clust_size) : PREFETCH_BLOCKS, - do_fat_read_block) < 0) { + do_fat_read_at_block) < 0) { debug("Error: reading rootdir block\n"); goto exit; } - dentptr = (dir_entry *) do_fat_read_block; + dentptr = (dir_entry *) do_fat_read_at_block; } for (i = 0; i < DIRENTSPERBLOCK; i++) { @@ -913,7 +961,7 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) get_vfatname(mydata, root_cluster, - do_fat_read_block, + do_fat_read_at_block, dentptr, l_name); if (dols == LS_ROOT) { @@ -1116,7 +1164,7 @@ rootdir_done: subname = nextname; } - ret = get_contents(mydata, dentptr, buffer, maxsize); + ret = get_contents(mydata, dentptr, pos, buffer, maxsize); debug("Size: %d, got: %ld\n", FAT2CPU32(dentptr->size), ret); exit: @@ -1124,6 +1172,12 @@ exit: return ret; } +long +do_fat_read(const char *filename, void *buffer, unsigned long maxsize, int dols) +{ + return do_fat_read_at(filename, 0, buffer, maxsize, dols); +} + int file_fat_detectfs(void) { boot_sector bs; @@ -1192,8 +1246,14 @@ int file_fat_ls(const char *dir) return do_fat_read(dir, NULL, 0, LS_YES); } -long file_fat_read(const char *filename, void *buffer, unsigned long maxsize) +long file_fat_read_at(const char *filename, unsigned long pos, void *buffer, + unsigned long maxsize) { printf("reading %s\n", filename); - return do_fat_read(filename, buffer, maxsize, LS_NO); + return do_fat_read_at(filename, pos, buffer, maxsize, LS_NO); +} + +long file_fat_read(const char *filename, void *buffer, unsigned long maxsize) +{ + return file_fat_read_at(filename, 0, buffer, maxsize); } diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index a6181e7..5829adf 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -328,7 +328,7 @@ static void flush_dir_table(fsdata *mydata, dir_entry **dentptr); static void fill_dir_slot(fsdata *mydata, dir_entry **dentptr, const char *l_name) { - dir_slot *slotptr = (dir_slot *)get_vfatname_block; + dir_slot *slotptr = (dir_slot *)get_contents_vfatname_block; __u8 counter = 0, checksum; int idx = 0, ret; char s_name[16]; @@ -373,7 +373,7 @@ static __u32 dir_curclust; * a slot) into 'l_name'. If successful also copy the real directory entry * into 'retdent' * If additional adjacent cluster for directory entries is read into memory, - * then 'get_vfatname_block' is copied into 'get_dentfromdir_block' and + * then 'get_contents_vfatname_block' is copied into 'get_dentfromdir_block' and * the location of the real directory entry is returned by 'retdent' * Return 0 on success, -1 otherwise. */ @@ -416,13 +416,13 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster, dir_curclust = curclust; - if (get_cluster(mydata, curclust, get_vfatname_block, + if (get_cluster(mydata, curclust, get_contents_vfatname_block, mydata->clust_size * mydata->sect_size) != 0) { debug("Error: reading directory block\n"); return -1; } - slotptr2 = (dir_slot *)get_vfatname_block; + slotptr2 = (dir_slot *)get_contents_vfatname_block; while (counter > 0) { if (((slotptr2->id & ~LAST_LONG_ENTRY_MASK) & 0xff) != counter) @@ -433,7 +433,7 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster, /* Save the real directory entry */ realdent = (dir_entry *)slotptr2; - while ((__u8 *)slotptr2 > get_vfatname_block) { + while ((__u8 *)slotptr2 > get_contents_vfatname_block) { slotptr2--; slot2str(slotptr2, l_name, &idx); } @@ -459,9 +459,9 @@ get_long_file_name(fsdata *mydata, int curclust, __u8 *cluster, *retdent = realdent; if (slotptr2) { - memcpy(get_dentfromdir_block, get_vfatname_block, + memcpy(get_dentfromdir_block, get_contents_vfatname_block, mydata->clust_size * mydata->sect_size); - cur_position = (__u8 *)realdent - get_vfatname_block; + cur_position = (__u8 *)realdent - get_contents_vfatname_block; *retdent = (dir_entry *) &get_dentfromdir_block[cur_position]; } @@ -980,11 +980,11 @@ static int do_fat_write(const char *filename, void *buffer, if (disk_read(cursect, (mydata->fatsize == 32) ? (mydata->clust_size) : - PREFETCH_BLOCKS, do_fat_read_block) < 0) { + PREFETCH_BLOCKS, do_fat_read_at_block) < 0) { debug("Error: reading rootdir block\n"); goto exit; } - dentptr = (dir_entry *) do_fat_read_block; + dentptr = (dir_entry *) do_fat_read_at_block; name_len = strlen(filename); if (name_len >= VFAT_MAXLEN_BYTES) diff --git a/include/fat.h b/include/fat.h index f1b4a0d..cc85b06 100644 --- a/include/fat.h +++ b/include/fat.h @@ -208,6 +208,8 @@ file_read_func file_fat_read; int file_cd(const char *path); int file_fat_detectfs(void); int file_fat_ls(const char *dir); +long file_fat_read_at(const char *filename, unsigned long pos, void *buffer, + unsigned long maxsize); long file_fat_read(const char *filename, void *buffer, unsigned long maxsize); const char *file_getfsname(int idx); int fat_register_device(block_dev_desc_t *dev_desc, int part_no); -- cgit v1.1 From 659e559d55fd72862d3374ce4453df13cc5a69ec Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 13 Aug 2012 12:18:34 -0700 Subject: Makefile: Move SPL files to clobber, remove from clean The 'clean' target has been removing all of spl but not u-boot itself. For consistency and ease of testing, only remove SPL binaries / maps in the clobber target, just like for full U-Boot Signed-off-by: Tom Rini --- Makefile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index cbab571..e193be0 100644 --- a/Makefile +++ b/Makefile @@ -791,10 +791,6 @@ clean: @rm -f $(obj)lib/asm-offsets.s @rm -f $(obj)include/generated/asm-offsets.h @rm -f $(obj)$(CPUDIR)/$(SOC)/asm-offsets.s - @rm -f $(obj)nand_spl/{u-boot.lds,u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map,System.map} - @rm -f $(ONENAND_BIN) - @rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.lds,u-boot-spl.map} - @rm -f $(obj)MLO @rm -f $(TIMESTAMP_FILE) $(VERSION_FILE) @find $(OBJTREE) -type f \ \( -name 'core' -o -name '*.bak' -o -name '*~' -o -name '*.su' \ @@ -820,6 +816,9 @@ clobber: tidy @rm -f $(obj)u-boot.dtb @rm -f $(obj)u-boot.sb @rm -f $(obj)u-boot.spr + @rm -f $(obj)nand_spl/{u-boot.lds,u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map,System.map} + @rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.lds,u-boot-spl.map} + @rm -f $(obj)MLO @rm -f $(obj)tools/xway-swap-bytes @rm -f $(obj)arch/powerpc/cpu/mpc824x/bedbug_603e.c @rm -f $(obj)arch/powerpc/cpu/mpc83xx/ddr-gen?.c -- cgit v1.1 From 0da113e9fd353ce08dda0ac9d79694b673174bda Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 10 Aug 2012 09:27:14 -0700 Subject: spl_mmc: Make FAT checks / calls guarded with CONFIG_SPL_FAT_SUPPORT Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/spl_mmc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/arch/arm/cpu/armv7/omap-common/spl_mmc.c index 2f921bb..7552f6c 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_mmc.c +++ b/arch/arm/cpu/armv7/omap-common/spl_mmc.c @@ -84,6 +84,7 @@ end: } } +#ifdef CONFIG_SPL_FAT_SUPPORT static void mmc_load_image_fat(struct mmc *mmc) { s32 err; @@ -116,6 +117,7 @@ end: hang(); } } +#endif void spl_mmc_load_image(void) { @@ -140,9 +142,11 @@ void spl_mmc_load_image(void) if (boot_mode == MMCSD_MODE_RAW) { debug("boot mode - RAW\n"); mmc_load_image_raw(mmc); +#ifdef CONFIG_SPL_FAT_SUPPORT } else if (boot_mode == MMCSD_MODE_FAT) { debug("boot mode - FAT\n"); mmc_load_image_fat(mmc); +#endif } else { puts("spl: wrong MMC boot mode\n"); hang(); -- cgit v1.1 From 861a86f46047c22af505d7fb27b2c68df0f54323 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 13 Aug 2012 11:37:56 -0700 Subject: omap-common: SPL: Add CONFIG_SPL_DISPLAY_PRINT / spl_display_print() Only omap4/5 currently have a meaningful set of display text and overo had been adding a function to display nothing. Change how this works to be opt-in and only turned on for omap4/5 now. Signed-off-by: Tom Rini --- README | 4 ++++ arch/arm/cpu/armv7/omap-common/hwinit-common.c | 5 +++++ arch/arm/cpu/armv7/omap-common/spl.c | 9 +++------ arch/arm/include/asm/arch-omap4/sys_proto.h | 1 - arch/arm/include/asm/arch-omap5/sys_proto.h | 1 - arch/arm/include/asm/omap_common.h | 2 +- board/overo/overo.c | 10 ---------- include/configs/omap4_common.h | 1 + include/configs/omap5_evm.h | 1 + 9 files changed, 15 insertions(+), 19 deletions(-) diff --git a/README b/README index 5793b0a..309d88d 100644 --- a/README +++ b/README @@ -2597,6 +2597,10 @@ FIT uImage format: CONFIG_SYS_SPL_MALLOC_SIZE The size of the malloc pool used in SPL. + CONFIG_SPL_DISPLAY_PRINT + For ARM, enable an optional function to print more information + about the running system. + CONFIG_SPL_LIBCOMMON_SUPPORT Support for common/libcommon.o in SPL binary diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index 459ebb5..4d7ef5c 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -92,6 +92,11 @@ static void init_boot_params(void) { boot_params_ptr = (u32 *) &boot_params; } + +void spl_display_print(void) +{ + omap_rev_string(); +} #endif /* diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 4d1ac85..b10832a 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -219,10 +219,7 @@ void preloader_console_init(void) printf("\nU-Boot SPL %s (%s - %s)\n", u_boot_rev, U_BOOT_DATE, U_BOOT_TIME); - omap_rev_string(); -} - -void __weak omap_rev_string() -{ - printf("Texas Instruments Revision detection unimplemented\n"); +#ifdef CONFIG_SPL_DISPLAY_PRINT + spl_display_print(); +#endif } diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h index d633573..b48f81d 100644 --- a/arch/arm/include/asm/arch-omap4/sys_proto.h +++ b/arch/arm/include/asm/arch-omap4/sys_proto.h @@ -42,7 +42,6 @@ void sr32(void *, u32, u32, u32); u32 wait_on_value(u32, u32, void *, u32); void sdelay(unsigned long); void set_pl310_ctrl_reg(u32 val); -void omap_rev_string(void); void setup_clocks_for_console(void); void prcm_init(void); void bypass_dpll(u32 *const base); diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h index 74feb90..72e9df7 100644 --- a/arch/arm/include/asm/arch-omap5/sys_proto.h +++ b/arch/arm/include/asm/arch-omap5/sys_proto.h @@ -42,7 +42,6 @@ void set_muxconf_regs_non_essential(void); void sr32(void *, u32, u32, u32); u32 wait_on_value(u32, u32, void *, u32); void sdelay(unsigned long); -void omap_rev_string(void); void setup_clocks_for_console(void); void prcm_init(void); void bypass_dpll(u32 *const base); diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 71ef9b0..65b566c 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -94,9 +94,9 @@ u32 omap_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); -void omap_rev_string(void); void spl_board_prepare_for_linux(void); int spl_start_uboot(void); +void spl_display_print(void); /* NAND SPL functions */ void spl_nand_load_image(void); diff --git a/board/overo/overo.c b/board/overo/overo.c index f973870..c6d50a0 100644 --- a/board/overo/overo.c +++ b/board/overo/overo.c @@ -101,16 +101,6 @@ int board_init(void) } /* - * Routine: omap_rev_string - * Description: For SPL builds output board rev - */ -#ifdef CONFIG_SPL_BUILD -void omap_rev_string(void) -{ -} -#endif - -/* * Routine: get_board_revision * Description: Returns the board revision */ diff --git a/include/configs/omap4_common.h b/include/configs/omap4_common.h index ee0c4b9..c1c2fa9 100644 --- a/include/configs/omap4_common.h +++ b/include/configs/omap4_common.h @@ -235,6 +235,7 @@ #define CONFIG_SPL_TEXT_BASE 0x40304350 #define CONFIG_SPL_MAX_SIZE (38 * 1024) #define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR +#define CONFIG_SPL_DISPLAY_PRINT /* * 64 bytes before this address should be set aside for u-boot.img's diff --git a/include/configs/omap5_evm.h b/include/configs/omap5_evm.h index 4f0a6c1..b4a237a 100644 --- a/include/configs/omap5_evm.h +++ b/include/configs/omap5_evm.h @@ -232,6 +232,7 @@ #define CONFIG_SPL_TEXT_BASE 0x40300350 #define CONFIG_SPL_MAX_SIZE 0x19000 /* 100K */ #define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR +#define CONFIG_SPL_DISPLAY_PRINT #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 /* address 0x60000 */ #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x200 /* 256 KB */ -- cgit v1.1 From 6abbe744d2f4ef76c00bcab7051285e5ff8c8659 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 14 Aug 2012 09:20:06 -0700 Subject: omap-common: Fix typo in save_boot_params() in lowlevel_init.S Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/lowlevel_init.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S index 1ece073..024dda1 100644 --- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S @@ -63,7 +63,7 @@ ENTRY(save_boot_params) blt 2f cmp r2, #7 bgt 2f - /* Store the boot mode (raw/FAT) in omap_boot_mode */ + /* Store the boot mode (raw/FAT) in omap_bootmode */ ldr r2, [r0, #DEV_DESC_PTR_OFFSET] @ get the device descriptor ptr ldr r2, [r2, #DEV_DATA_PTR_OFFSET] @ get the pDeviceData ptr ldr r2, [r2, #BOOT_MODE_OFFSET] @ get the boot mode -- cgit v1.1 From 9f8a6e7ae71cf38aa340a5055a56fd0c4bd5e913 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 30 Aug 2012 19:20:22 +0200 Subject: omap-common: SPL: Fix whitespace in omap-common/u-boot-spl.lds. Signed-off-by: Pavel Machek Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/u-boot-spl.lds | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds b/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds index 8867e06..1d8efb2 100644 --- a/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds +++ b/arch/arm/cpu/armv7/omap-common/u-boot-spl.lds @@ -37,9 +37,9 @@ SECTIONS { .text : { - __start = .; - arch/arm/cpu/armv7/start.o (.text) - *(.text*) + __start = .; + arch/arm/cpu/armv7/start.o (.text) + *(.text*) } >.sram . = ALIGN(4); -- cgit v1.1 From 8e1b836ec54846bedd0cabefc1cf6fbb1e3ae2e3 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 13 Aug 2012 12:53:23 -0700 Subject: ARM: SPL: Rename omap_boot_device to spl_boot_device Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/boot-common.c | 2 +- arch/arm/cpu/armv7/omap-common/lowlevel_init.S | 4 ++-- arch/arm/cpu/armv7/omap-common/spl.c | 2 +- arch/arm/cpu/armv7/omap-common/spl_mmc.c | 2 +- arch/arm/cpu/armv7/omap3/board.c | 4 ++-- arch/arm/include/asm/omap_common.h | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index f211f76..102a381 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -37,7 +37,7 @@ struct omap_boot_parameters boot_params __attribute__ ((section(".data"))); */ u32 omap_bootmode = MMCSD_MODE_FAT; -u32 omap_boot_device(void) +u32 spl_boot_device(void) { return (u32) (boot_params.omap_bootdevice); } diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S index 024dda1..9766563 100644 --- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S +++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S @@ -52,11 +52,11 @@ ENTRY(save_boot_params) ldr r1, =boot_params str r0, [r1] #ifdef CONFIG_SPL_BUILD - /* Store the boot device in omap_boot_device */ + /* Store the boot device in spl_boot_device */ ldrb r2, [r0, #BOOT_DEVICE_OFFSET] @ r1 <- value of boot device and r2, #BOOT_DEVICE_MASK ldr r3, =boot_params - strb r2, [r3, #BOOT_DEVICE_OFFSET] @ omap_boot_device <- r1 + strb r2, [r3, #BOOT_DEVICE_OFFSET] @ spl_boot_device <- r1 /* boot mode is passed only for devices that can raw/fat mode */ cmp r2, #2 diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index b10832a..4d33f99 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -156,7 +156,7 @@ void board_init_r(gd_t *id, ulong dummy) spl_board_init(); #endif - boot_device = omap_boot_device(); + boot_device = spl_boot_device(); debug("boot device - %d\n", boot_device); switch (boot_device) { #ifdef CONFIG_SPL_MMC_SUPPORT diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/arch/arm/cpu/armv7/omap-common/spl_mmc.c index 7552f6c..3ad382b 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_mmc.c +++ b/arch/arm/cpu/armv7/omap-common/spl_mmc.c @@ -37,7 +37,7 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_GENERIC_MMC int board_mmc_init(bd_t *bis) { - switch (omap_boot_device()) { + switch (spl_boot_device()) { case BOOT_DEVICE_MMC1: omap_mmc_init(0, 0, 0); break; diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index f2e52e9..b4f4fee 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -71,7 +71,7 @@ u32 omap3_boot_device = BOOT_DEVICE_NAND; /* auto boot mode detection is not possible for OMAP3 - hard code */ u32 omap_boot_mode(void) { - switch (omap_boot_device()) { + switch (spl_boot_device()) { case BOOT_DEVICE_MMC2: return MMCSD_MODE_RAW; case BOOT_DEVICE_MMC1: @@ -86,7 +86,7 @@ u32 omap_boot_mode(void) } } -u32 omap_boot_device(void) +u32 spl_boot_device(void) { return omap3_boot_device; } diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 65b566c..336ac39 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -89,7 +89,7 @@ struct spl_image_info { extern struct spl_image_info spl_image; extern u32* boot_params_ptr; -u32 omap_boot_device(void); +u32 spl_boot_device(void); u32 omap_boot_mode(void); /* SPL common function s*/ -- cgit v1.1 From 37189a19589794f8482a1c64dcebca2d6fbe96a5 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 14 Aug 2012 09:19:44 -0700 Subject: ARM: SPL: Rename omap_boot_mode to spl_boot_mode() Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/boot-common.c | 2 +- arch/arm/cpu/armv7/omap-common/spl_mmc.c | 2 +- arch/arm/cpu/armv7/omap-common/spl_nand.c | 2 +- arch/arm/cpu/armv7/omap3/board.c | 2 +- arch/arm/include/asm/omap_common.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index 102a381..53568ac 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -42,7 +42,7 @@ u32 spl_boot_device(void) return (u32) (boot_params.omap_bootdevice); } -u32 omap_boot_mode(void) +u32 spl_boot_mode(void) { return omap_bootmode; } diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/arch/arm/cpu/armv7/omap-common/spl_mmc.c index 3ad382b..62b308b 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_mmc.c +++ b/arch/arm/cpu/armv7/omap-common/spl_mmc.c @@ -138,7 +138,7 @@ void spl_mmc_load_image(void) printf("spl: mmc init failed: err - %d\n", err); hang(); } - boot_mode = omap_boot_mode(); + boot_mode = spl_boot_mode(); if (boot_mode == MMCSD_MODE_RAW) { debug("boot mode - RAW\n"); mmc_load_image_raw(mmc); diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 8cf55c9..ea7cc8a 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -35,7 +35,7 @@ void spl_nand_load_image(void) int *src __attribute__((unused)); int *dst __attribute__((unused)); - switch (omap_boot_mode()) { + switch (spl_boot_mode()) { case NAND_MODE_HW_ECC: debug("spl: nand - using hw ecc\n"); gpmc_init(); diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index b4f4fee..1640696 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -69,7 +69,7 @@ const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx; u32 omap3_boot_device = BOOT_DEVICE_NAND; /* auto boot mode detection is not possible for OMAP3 - hard code */ -u32 omap_boot_mode(void) +u32 spl_boot_mode(void) { switch (spl_boot_device()) { case BOOT_DEVICE_MMC2: diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 336ac39..f5b9dfe 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -90,7 +90,7 @@ extern struct spl_image_info spl_image; extern u32* boot_params_ptr; u32 spl_boot_device(void); -u32 omap_boot_mode(void); +u32 spl_boot_mode(void); /* SPL common function s*/ void spl_parse_image_header(const struct image_header *header); -- cgit v1.1 From 8082fda9fc6d6fb6ba1bc467fb117af3dbed928a Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 13 Aug 2012 14:11:06 -0700 Subject: ARM: SPL: Remove NAND_MODE_HW_ECC from spl_nand.c This detection code doesn't (and can't) do anything currently, so remove. Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/spl_nand.c | 13 +++---------- arch/arm/cpu/armv7/omap3/board.c | 3 --- arch/arm/include/asm/omap_common.h | 1 - 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index ea7cc8a..39221d5 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -35,16 +35,9 @@ void spl_nand_load_image(void) int *src __attribute__((unused)); int *dst __attribute__((unused)); - switch (spl_boot_mode()) { - case NAND_MODE_HW_ECC: - debug("spl: nand - using hw ecc\n"); - gpmc_init(); - nand_init(); - break; - default: - puts("spl: ERROR: This bootmode is not implemented - hanging"); - hang(); - } + debug("spl: nand - using hw ecc\n"); + gpmc_init(); + nand_init(); /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 1640696..a487374 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -77,9 +77,6 @@ u32 spl_boot_mode(void) case BOOT_DEVICE_MMC1: return MMCSD_MODE_FAT; break; - case BOOT_DEVICE_NAND: - return NAND_MODE_HW_ECC; - break; default: puts("spl: ERROR: unknown device - can't select boot mode\n"); hang(); diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index f5b9dfe..4d331fc 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -76,7 +76,6 @@ void preloader_console_init(void); #define MMCSD_MODE_UNDEFINED 0 #define MMCSD_MODE_RAW 1 #define MMCSD_MODE_FAT 2 -#define NAND_MODE_HW_ECC 3 struct spl_image_info { const char *name; -- cgit v1.1 From 24dafad5c42018ea11c0d12f747a7eb337229f5a Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 13 Aug 2012 14:13:07 -0700 Subject: ARM: SPL: Only call mem_malloc_init if configured We can only attempt to setup a malloc pool if CONFIG_SYS_SPL_MALLOC_START is defined, and not all boards require it. Make the call depend on the define. Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/spl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 4d33f99..71a467e 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -149,8 +149,10 @@ void board_init_r(gd_t *id, ulong dummy) u32 boot_device; debug(">>spl:board_init_r()\n"); +#ifdef CONFIG_SYS_SPL_MALLOC_START mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, CONFIG_SYS_SPL_MALLOC_SIZE); +#endif #ifdef CONFIG_SPL_BOARD_INIT spl_board_init(); -- cgit v1.1 From 55cdbb8d4e8508dcdb95400f6dfcb928220ffc70 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 14 Aug 2012 08:50:58 -0700 Subject: ARM: SPL: Add and Move the SPL prototypes from into and add for arch specific portions of CONFIG_SPL_FRAMEWORK. Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/am33xx/board.c | 2 +- arch/arm/cpu/armv7/omap-common/hwinit-common.c | 2 +- arch/arm/cpu/armv7/omap-common/spl.c | 2 +- arch/arm/cpu/armv7/omap-common/spl_mmc.c | 1 + arch/arm/cpu/armv7/omap-common/spl_nand.c | 2 +- arch/arm/cpu/armv7/omap-common/spl_ymodem.c | 2 +- arch/arm/cpu/armv7/omap3/board.c | 1 + arch/arm/include/asm/arch-am33xx/spl.h | 31 +++++++++++ arch/arm/include/asm/arch-omap3/spl.h | 34 ++++++++++++ arch/arm/include/asm/arch-omap4/spl.h | 35 +++++++++++++ arch/arm/include/asm/arch-omap5/spl.h | 35 +++++++++++++ arch/arm/include/asm/omap_common.h | 71 -------------------------- arch/arm/include/asm/spl.h | 61 ++++++++++++++++++++++ 13 files changed, 203 insertions(+), 76 deletions(-) create mode 100644 arch/arm/include/asm/arch-am33xx/spl.h create mode 100644 arch/arm/include/asm/arch-omap3/spl.h create mode 100644 arch/arm/include/asm/arch-omap4/spl.h create mode 100644 arch/arm/include/asm/arch-omap5/spl.h create mode 100644 arch/arm/include/asm/spl.h diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index ecc2671..e89df8e 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -27,9 +27,9 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index 4d7ef5c..d5fde38 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 71a467e..81991b2 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -23,6 +23,7 @@ * MA 02111-1307 USA */ #include +#include #include #include #include @@ -30,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/arch/arm/cpu/armv7/omap-common/spl_mmc.c index 62b308b..fe44538 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_mmc.c +++ b/arch/arm/cpu/armv7/omap-common/spl_mmc.c @@ -23,6 +23,7 @@ * MA 02111-1307 USA */ #include +#include #include #include #include diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 39221d5..6552a5d 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -21,13 +21,13 @@ * MA 02111-1307 USA */ #include +#include #include #include #include #include #include #include -#include void spl_nand_load_image(void) { diff --git a/arch/arm/cpu/armv7/omap-common/spl_ymodem.c b/arch/arm/cpu/armv7/omap-common/spl_ymodem.c index 47663f7..65565e3 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_ymodem.c +++ b/arch/arm/cpu/armv7/omap-common/spl_ymodem.c @@ -26,11 +26,11 @@ * MA 02111-1307 USA */ #include +#include #include #include #include #include -#include #define BUF_SIZE 1024 diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index a487374..45976f9 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/include/asm/arch-am33xx/spl.h b/arch/arm/include/asm/arch-am33xx/spl.h new file mode 100644 index 0000000..70f521d --- /dev/null +++ b/arch/arm/include/asm/arch-am33xx/spl.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NAND 5 +#define BOOT_DEVICE_MMC1 8 +#define BOOT_DEVICE_MMC2 9 /* eMMC or daughter card */ +#define BOOT_DEVICE_UART 65 +#define BOOT_DEVICE_MMC2_2 0xFF +#endif diff --git a/arch/arm/include/asm/arch-omap3/spl.h b/arch/arm/include/asm/arch-omap3/spl.h new file mode 100644 index 0000000..404e16a --- /dev/null +++ b/arch/arm/include/asm/arch-omap3/spl.h @@ -0,0 +1,34 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NONE 0 +#define BOOT_DEVICE_XIP 1 +#define BOOT_DEVICE_NAND 2 +#define BOOT_DEVICE_ONE_NAND 3 +#define BOOT_DEVICE_MMC2 5 /*emmc*/ +#define BOOT_DEVICE_MMC1 6 +#define BOOT_DEVICE_XIPWAIT 7 +#define BOOT_DEVICE_MMC2_2 0xFF +#endif diff --git a/arch/arm/include/asm/arch-omap4/spl.h b/arch/arm/include/asm/arch-omap4/spl.h new file mode 100644 index 0000000..cec84dc --- /dev/null +++ b/arch/arm/include/asm/arch-omap4/spl.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NONE 0 +#define BOOT_DEVICE_XIP 1 +#define BOOT_DEVICE_XIPWAIT 2 +#define BOOT_DEVICE_NAND 3 +#define BOOT_DEVICE_ONE_NAND 4 +#define BOOT_DEVICE_MMC1 5 +#define BOOT_DEVICE_MMC2 6 +#define BOOT_DEVICE_MMC2_2 0xFF + +#endif diff --git a/arch/arm/include/asm/arch-omap5/spl.h b/arch/arm/include/asm/arch-omap5/spl.h new file mode 100644 index 0000000..d125c61 --- /dev/null +++ b/arch/arm/include/asm/arch-omap5/spl.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NONE 0 +#define BOOT_DEVICE_XIP 1 +#define BOOT_DEVICE_XIPWAIT 2 +#define BOOT_DEVICE_NAND 3 +#define BOOT_DEVICE_ONE_NAND 4 +#define BOOT_DEVICE_MMC1 5 +#define BOOT_DEVICE_MMC2 6 +#define BOOT_DEVICE_MMC2_2 7 + +#endif diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 4d331fc..775ab6c 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -34,82 +34,11 @@ #define OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL 2 #define OMAP_INIT_CONTEXT_UBOOT_AFTER_CH 3 -void preloader_console_init(void); - -/* Boot device */ -#ifdef CONFIG_OMAP54XX -#define BOOT_DEVICE_NONE 0 -#define BOOT_DEVICE_XIP 1 -#define BOOT_DEVICE_XIPWAIT 2 -#define BOOT_DEVICE_NAND 3 -#define BOOT_DEVICE_ONE_NAND 4 -#define BOOT_DEVICE_MMC1 5 -#define BOOT_DEVICE_MMC2 6 -#define BOOT_DEVICE_MMC2_2 7 -#elif defined(CONFIG_OMAP44XX) /* OMAP4 */ -#define BOOT_DEVICE_NONE 0 -#define BOOT_DEVICE_XIP 1 -#define BOOT_DEVICE_XIPWAIT 2 -#define BOOT_DEVICE_NAND 3 -#define BOOT_DEVICE_ONE_NAND 4 -#define BOOT_DEVICE_MMC1 5 -#define BOOT_DEVICE_MMC2 6 -#define BOOT_DEVICE_MMC2_2 0xFF -#elif defined(CONFIG_OMAP34XX) /* OMAP3 */ -#define BOOT_DEVICE_NONE 0 -#define BOOT_DEVICE_XIP 1 -#define BOOT_DEVICE_NAND 2 -#define BOOT_DEVICE_ONE_NAND 3 -#define BOOT_DEVICE_MMC2 5 /*emmc*/ -#define BOOT_DEVICE_MMC1 6 -#define BOOT_DEVICE_XIPWAIT 7 -#define BOOT_DEVICE_MMC2_2 0xFF -#elif defined(CONFIG_AM33XX) /* AM33XX */ -#define BOOT_DEVICE_NAND 5 -#define BOOT_DEVICE_MMC1 8 -#define BOOT_DEVICE_MMC2 9 /* eMMC or daughter card */ -#define BOOT_DEVICE_UART 65 -#define BOOT_DEVICE_MMC2_2 0xFF -#endif - /* Boot type */ #define MMCSD_MODE_UNDEFINED 0 #define MMCSD_MODE_RAW 1 #define MMCSD_MODE_FAT 2 -struct spl_image_info { - const char *name; - u8 os; - u32 load_addr; - u32 entry_point; - u32 size; -}; - -extern struct spl_image_info spl_image; - -extern u32* boot_params_ptr; -u32 spl_boot_device(void); -u32 spl_boot_mode(void); - -/* SPL common function s*/ -void spl_parse_image_header(const struct image_header *header); -void spl_board_prepare_for_linux(void); -int spl_start_uboot(void); -void spl_display_print(void); - -/* NAND SPL functions */ -void spl_nand_load_image(void); - -/* MMC SPL functions */ -void spl_mmc_load_image(void); - -/* YMODEM SPL functions */ -void spl_ymodem_load_image(void); - -#ifdef CONFIG_SPL_BOARD_INIT -void spl_board_init(void); -#endif - static inline u32 omap_revision(void) { extern u32 *const omap_si_rev; diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h new file mode 100644 index 0000000..19e6c50 --- /dev/null +++ b/arch/arm/include/asm/spl.h @@ -0,0 +1,61 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _ASM_SPL_H_ +#define _ASM_SPL_H_ + +/* Platform-specific defines */ +#include + +struct spl_image_info { + const char *name; + u8 os; + u32 load_addr; + u32 entry_point; + u32 size; +}; + +extern struct spl_image_info spl_image; +extern u32 *boot_params_ptr; + +/* SPL common functions */ +void preloader_console_init(void); +u32 spl_boot_device(void); +u32 spl_boot_mode(void); +void spl_parse_image_header(const struct image_header *header); +void spl_board_prepare_for_linux(void); +int spl_start_uboot(void); +void spl_display_print(void); + +/* NAND SPL functions */ +void spl_nand_load_image(void); + +/* MMC SPL functions */ +void spl_mmc_load_image(void); + +/* YMODEM SPL functions */ +void spl_ymodem_load_image(void); + +#ifdef CONFIG_SPL_BOARD_INIT +void spl_board_init(void); +#endif +#endif -- cgit v1.1 From f0881250f9429a5c88e39e90c2d7100b0e10f7b9 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 14 Aug 2012 10:25:15 -0700 Subject: ARM: SPL: Make spl_mmc.c more generic Move the default omap/related-centric board_mmc_init to arch/arm/cpu/armv7/omap-common/boot-common.c and move the type defines to . Also use mmc->read_bl_len rather than MMCSD_SECTOR_SIZE Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/boot-common.c | 16 ++++++++++++++++ arch/arm/cpu/armv7/omap-common/spl_mmc.c | 23 ++--------------------- arch/arm/cpu/armv7/omap3/board.c | 15 +++++++++++++++ arch/arm/include/asm/omap_common.h | 5 ----- arch/arm/include/asm/spl.h | 5 +++++ 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index 53568ac..3406cfb 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -17,8 +17,10 @@ */ #include +#include #include #include +#include /* * This is used to verify if the configuration header @@ -46,4 +48,18 @@ u32 spl_boot_mode(void) { return omap_bootmode; } + +int board_mmc_init(bd_t *bis) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + omap_mmc_init(0, 0, 0); + break; + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + omap_mmc_init(1, 0, 0); + break; + } + return 0; +} #endif diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/arch/arm/cpu/armv7/omap-common/spl_mmc.c index fe44538..fdecf94 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_mmc.c +++ b/arch/arm/cpu/armv7/omap-common/spl_mmc.c @@ -26,31 +26,12 @@ #include #include #include -#include #include #include #include -#include -#include DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_GENERIC_MMC -int board_mmc_init(bd_t *bis) -{ - switch (spl_boot_device()) { - case BOOT_DEVICE_MMC1: - omap_mmc_init(0, 0, 0); - break; - case BOOT_DEVICE_MMC2: - case BOOT_DEVICE_MMC2_2: - omap_mmc_init(1, 0, 0); - break; - } - return 0; -} -#endif - static void mmc_load_image_raw(struct mmc *mmc) { u32 image_size_sectors, err; @@ -70,8 +51,8 @@ static void mmc_load_image_raw(struct mmc *mmc) spl_parse_image_header(header); /* convert size to sectors - round up */ - image_size_sectors = (spl_image.size + MMCSD_SECTOR_SIZE - 1) / - MMCSD_SECTOR_SIZE; + image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / + mmc->read_bl_len; /* Read the header too to avoid extra memcpy */ err = mmc->block_dev.block_read(0, diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 45976f9..3d74f09 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -89,6 +90,20 @@ u32 spl_boot_device(void) return omap3_boot_device; } +int board_mmc_init(bd_t *bis) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC1: + omap_mmc_init(0, 0, 0); + break; + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + omap_mmc_init(1, 0, 0); + break; + } + return 0; +} + void spl_board_init(void) { #ifdef CONFIG_SPL_I2C_SUPPORT diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 775ab6c..2a40b89 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -34,11 +34,6 @@ #define OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL 2 #define OMAP_INIT_CONTEXT_UBOOT_AFTER_CH 3 -/* Boot type */ -#define MMCSD_MODE_UNDEFINED 0 -#define MMCSD_MODE_RAW 1 -#define MMCSD_MODE_FAT 2 - static inline u32 omap_revision(void) { extern u32 *const omap_si_rev; diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h index 19e6c50..fdb78b5 100644 --- a/arch/arm/include/asm/spl.h +++ b/arch/arm/include/asm/spl.h @@ -26,6 +26,11 @@ /* Platform-specific defines */ #include +/* Boot type */ +#define MMCSD_MODE_UNDEFINED 0 +#define MMCSD_MODE_RAW 1 +#define MMCSD_MODE_FAT 2 + struct spl_image_info { const char *name; u8 os; -- cgit v1.1 From 026b2fe32c3d5658befb54521dcfed46444e6bf8 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 14 Aug 2012 12:06:43 -0700 Subject: ARM: SPL: Clean up spl.c / spl_nand.c slightly - Remove includes we don't need - Switch some printf statements to puts - Convert some printf statements to debug, introduce new puts statements - In most cases saying just "No mkimage signature, assuming u-boot.bin" or similar is sufficient. This also means the non-DEBUG case doesn't need printf, in the core of SPL. - The other case here is that PLAIN_VERSION provided what we wanted already, so just use it. Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/spl.c | 23 ++++++++--------------- arch/arm/cpu/armv7/omap-common/spl_nand.c | 1 - 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 81991b2..3a1029f 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -26,12 +26,9 @@ #include #include #include -#include #include -#include #include #include -#include #include #include #include @@ -78,8 +75,8 @@ void board_init_f(ulong dummy) #ifdef CONFIG_SPL_OS_BOOT __weak int spl_start_uboot(void) { - printf("SPL: Please implement spl_start_uboot() for your board\n"); - printf("SPL: Direct Linux boot not active!\n"); + puts("SPL: Please implement spl_start_uboot() for your board\n"); + puts("SPL: Direct Linux boot not active!\n"); return 1; } #endif @@ -99,9 +96,9 @@ void spl_parse_image_header(const struct image_header *header) spl_image.name, spl_image.load_addr, spl_image.size); } else { /* Signature not found - assume u-boot.bin */ - printf("mkimage signature not found - ih_magic = %x\n", + puts("mkimage signature not found, assuming u-boot.bin ..\n"); + debug("mkimage signature not found - ih_magic = %x\n", header->ih_magic); - debug("Assuming u-boot.bin ..\n"); /* Let's assume U-Boot will not be more than 200 KB */ spl_image.size = 200 * 1024; spl_image.entry_point = CONFIG_SYS_TEXT_BASE; @@ -179,7 +176,8 @@ void board_init_r(gd_t *id, ulong dummy) break; #endif default: - printf("SPL: Un-supported Boot Device - %d!!!\n", boot_device); + puts("SPL: Un-supported Boot Device\n"); + debug("Found: %d\n", boot_device); hang(); break; } @@ -205,8 +203,6 @@ void board_init_r(gd_t *id, ulong dummy) /* This requires UART clocks to be enabled */ void preloader_console_init(void) { - const char *u_boot_rev = U_BOOT_VERSION; - gd = &gdata; gd->bd = &bdata; gd->flags |= GD_FLG_RELOC; @@ -216,11 +212,8 @@ void preloader_console_init(void) gd->have_console = 1; - /* Avoid a second "U-Boot" coming from this string */ - u_boot_rev = &u_boot_rev[7]; - - printf("\nU-Boot SPL %s (%s - %s)\n", u_boot_rev, U_BOOT_DATE, - U_BOOT_TIME); + puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ + U_BOOT_TIME ")\n"); #ifdef CONFIG_SPL_DISPLAY_PRINT spl_display_print(); #endif diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 6552a5d..3e2f359 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include -- cgit v1.1 From d4c4e0e11710f26904c288ad1bf05d8b73abddf7 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 14 Aug 2012 12:25:23 -0700 Subject: ARM: SPL: Start hooking in the current SPI SPL support Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/spl.c | 5 +++++ arch/arm/include/asm/spl.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c index 3a1029f..dc26750 100644 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ b/arch/arm/cpu/armv7/omap-common/spl.c @@ -175,6 +175,11 @@ void board_init_r(gd_t *id, ulong dummy) spl_ymodem_load_image(); break; #endif +#ifdef CONFIG_SPL_SPI_SUPPORT + case BOOT_DEVICE_SPI: + spi_boot(); + break; +#endif default: puts("SPL: Un-supported Boot Device\n"); debug("Found: %d\n", boot_device); diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h index fdb78b5..47ca1b6 100644 --- a/arch/arm/include/asm/spl.h +++ b/arch/arm/include/asm/spl.h @@ -60,6 +60,9 @@ void spl_mmc_load_image(void); /* YMODEM SPL functions */ void spl_ymodem_load_image(void); +/* SPI SPL functions */ +void spi_boot(void); + #ifdef CONFIG_SPL_BOARD_INIT void spl_board_init(void); #endif -- cgit v1.1 From d7cb93b28a41237b689c9d84230d7d72a2048021 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 14 Aug 2012 12:26:08 -0700 Subject: ARM: SPL: Move gpmc_init() to spl_board_init() This is an OMAP/related-specific function, move calling it to spl_board_init() and turn on CONFIG_SPL_BOARD_INIT on the boards that enabled NAND and didn't enable this already. Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/boot-common.c | 7 +++++++ arch/arm/cpu/armv7/omap-common/spl_nand.c | 1 - arch/arm/cpu/armv7/omap3/board.c | 3 +++ include/configs/am3517_crane.h | 1 + include/configs/am3517_evm.h | 1 + include/configs/mcx.h | 1 + include/configs/tam3517-common.h | 1 + 7 files changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index 3406cfb..ed398fd 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -49,6 +49,13 @@ u32 spl_boot_mode(void) return omap_bootmode; } +void spl_board_init(void) +{ +#ifdef CONFIG_SPL_NAND_SUPPORT + gpmc_init(); +#endif +} + int board_mmc_init(bd_t *bis) { switch (spl_boot_device()) { diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 3e2f359..1e6b5f0 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -35,7 +35,6 @@ void spl_nand_load_image(void) int *dst __attribute__((unused)); debug("spl: nand - using hw ecc\n"); - gpmc_init(); nand_init(); /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 3d74f09..52196c8 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -106,6 +106,9 @@ int board_mmc_init(bd_t *bis) void spl_board_init(void) { +#ifdef CONFIG_SPL_NAND_SUPPORT + gpmc_init(); +#endif #ifdef CONFIG_SPL_I2C_SUPPORT i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); #endif diff --git a/include/configs/am3517_crane.h b/include/configs/am3517_crane.h index f24b44d..254ed57 100644 --- a/include/configs/am3517_crane.h +++ b/include/configs/am3517_crane.h @@ -314,6 +314,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) /* 8 KB for stack */ diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h index 95f8d78..ca39c72 100644 --- a/include/configs/am3517_evm.h +++ b/include/configs/am3517_evm.h @@ -313,6 +313,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) /* 8 KB for stack */ diff --git a/include/configs/mcx.h b/include/configs/mcx.h index 733022e..a841c70 100644 --- a/include/configs/mcx.h +++ b/include/configs/mcx.h @@ -359,6 +359,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_NAND_SOFTECC diff --git a/include/configs/tam3517-common.h b/include/configs/tam3517-common.h index a13fd93..b34cb78 100644 --- a/include/configs/tam3517-common.h +++ b/include/configs/tam3517-common.h @@ -239,6 +239,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_CONSOLE #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_NAND_SOFTECC -- cgit v1.1 From 47f7bcae8c0de8b2a8af7ca309744f041a6d1424 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 13 Aug 2012 12:03:19 -0700 Subject: SPL: Move the omap SPL framework to common/spl Add a new flag, CONFIG_SPL_FRAMEWORK to opt into the common/spl SPL framework, enable on all of the previously using boards. We move the spl_ymodem.c portion to common/ and spl_mmc.c to drivers/mmc/. We leave the NAND one in-place as we plan to replace it later in this series. We use common/spl to avoid linker problems with respect to merging constant strings in objects. Otherwise all strings in common/ will be linked in and kept which grows SPL in size too much. Signed-off-by: Tom Rini --- README | 5 + arch/arm/cpu/armv7/am33xx/board.c | 2 +- arch/arm/cpu/armv7/omap-common/Makefile | 7 - arch/arm/cpu/armv7/omap-common/boot-common.c | 2 +- arch/arm/cpu/armv7/omap-common/hwinit-common.c | 2 +- arch/arm/cpu/armv7/omap-common/spl.c | 225 ------------------------- arch/arm/cpu/armv7/omap-common/spl_mmc.c | 136 --------------- arch/arm/cpu/armv7/omap-common/spl_nand.c | 2 +- arch/arm/cpu/armv7/omap-common/spl_ymodem.c | 76 --------- arch/arm/cpu/armv7/omap3/board.c | 2 +- arch/arm/include/asm/spl.h | 40 ----- common/spl/Makefile | 37 ++++ common/spl/spl.c | 224 ++++++++++++++++++++++++ common/spl/spl_ymodem.c | 75 +++++++++ drivers/mmc/Makefile | 5 +- drivers/mmc/spl_mmc.c | 136 +++++++++++++++ include/configs/am335x_evm.h | 1 + include/configs/am3517_crane.h | 1 + include/configs/am3517_evm.h | 1 + include/configs/devkit8000.h | 1 + include/configs/igep00x0.h | 1 + include/configs/mcx.h | 1 + include/configs/omap3_beagle.h | 1 + include/configs/omap3_evm_common.h | 1 + include/configs/omap3_overo.h | 1 + include/configs/omap4_common.h | 1 + include/configs/omap5_evm.h | 1 + include/configs/tam3517-common.h | 1 + include/configs/tricorder.h | 1 + include/spl.h | 69 ++++++++ spl/Makefile | 1 + 31 files changed, 569 insertions(+), 490 deletions(-) delete mode 100644 arch/arm/cpu/armv7/omap-common/spl.c delete mode 100644 arch/arm/cpu/armv7/omap-common/spl_mmc.c delete mode 100644 arch/arm/cpu/armv7/omap-common/spl_ymodem.c create mode 100644 common/spl/Makefile create mode 100644 common/spl/spl.c create mode 100644 common/spl/spl_ymodem.c create mode 100644 drivers/mmc/spl_mmc.c create mode 100644 include/spl.h diff --git a/README b/README index 309d88d..c5e6a1a 100644 --- a/README +++ b/README @@ -2597,6 +2597,11 @@ FIT uImage format: CONFIG_SYS_SPL_MALLOC_SIZE The size of the malloc pool used in SPL. + CONFIG_SPL_FRAMEWORK + Enable the SPL framework under common/. This framework + supports MMC, NAND and YMODEM loading of U-Boot and NAND + NAND loading of the Linux Kernel. + CONFIG_SPL_DISPLAY_PRINT For ARM, enable an optional function to print more information about the running system. diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index e89df8e..c45b19b 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index d37b22d..6e815c6 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -43,16 +43,9 @@ SOBJS += lowlevel_init.o endif ifdef CONFIG_SPL_BUILD -COBJS += spl.o ifdef CONFIG_SPL_NAND_SUPPORT COBJS += spl_nand.o endif -ifdef CONFIG_SPL_MMC_SUPPORT -COBJS += spl_mmc.o -endif -ifdef CONFIG_SPL_YMODEM_SUPPORT -COBJS += spl_ymodem.o -endif endif ifndef CONFIG_SPL_BUILD diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index ed398fd..0f19141 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -17,7 +17,7 @@ */ #include -#include +#include #include #include #include diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index d5fde38..ad8b5ac 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -28,10 +28,10 @@ * MA 02111-1307 USA */ #include +#include #include #include #include -#include DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c deleted file mode 100644 index dc26750..0000000 --- a/arch/arm/cpu/armv7/omap-common/spl.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * (C) Copyright 2010 - * Texas Instruments, - * - * Aneesh V - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -u32* boot_params_ptr = NULL; -struct spl_image_info spl_image; - -/* Define global data structure pointer to it*/ -static gd_t gdata __attribute__ ((section(".data"))); -static bd_t bdata __attribute__ ((section(".data"))); - -inline void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;) - ; -} - -void board_init_f(ulong dummy) -{ - /* - * We call relocate_code() with relocation target same as the - * CONFIG_SYS_SPL_TEXT_BASE. This will result in relocation getting - * skipped. Instead, only .bss initialization will happen. That's - * all we need - */ - debug(">>board_init_f()\n"); - relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); -} - -/* - * Default function to determine if u-boot or the OS should - * be started. This implementation always returns 1. - * - * Please implement your own board specific funcion to do this. - * - * RETURN - * 0 to not start u-boot - * positive if u-boot should start - */ -#ifdef CONFIG_SPL_OS_BOOT -__weak int spl_start_uboot(void) -{ - puts("SPL: Please implement spl_start_uboot() for your board\n"); - puts("SPL: Direct Linux boot not active!\n"); - return 1; -} -#endif - -void spl_parse_image_header(const struct image_header *header) -{ - u32 header_size = sizeof(struct image_header); - - if (__be32_to_cpu(header->ih_magic) == IH_MAGIC) { - spl_image.size = __be32_to_cpu(header->ih_size) + header_size; - spl_image.entry_point = __be32_to_cpu(header->ih_load); - /* Load including the header */ - spl_image.load_addr = spl_image.entry_point - header_size; - spl_image.os = header->ih_os; - spl_image.name = (const char *)&header->ih_name; - debug("spl: payload image: %s load addr: 0x%x size: %d\n", - spl_image.name, spl_image.load_addr, spl_image.size); - } else { - /* Signature not found - assume u-boot.bin */ - puts("mkimage signature not found, assuming u-boot.bin ..\n"); - debug("mkimage signature not found - ih_magic = %x\n", - header->ih_magic); - /* Let's assume U-Boot will not be more than 200 KB */ - spl_image.size = 200 * 1024; - spl_image.entry_point = CONFIG_SYS_TEXT_BASE; - spl_image.load_addr = CONFIG_SYS_TEXT_BASE; - spl_image.os = IH_OS_U_BOOT; - spl_image.name = "U-Boot"; - } -} - -/* - * This function jumps to an image with argument. Normally an FDT or ATAGS - * image. - * arg: Pointer to paramter image in RAM - */ -#ifdef CONFIG_SPL_OS_BOOT -static void __noreturn jump_to_image_linux(void *arg) -{ - debug("Entering kernel arg pointer: 0x%p\n", arg); - typedef void (*image_entry_arg_t)(int, int, void *) - __attribute__ ((noreturn)); - image_entry_arg_t image_entry = - (image_entry_arg_t) spl_image.entry_point; - cleanup_before_linux(); - image_entry(0, CONFIG_MACH_TYPE, arg); -} -#endif - -static void __noreturn jump_to_image_no_args(void) -{ - typedef void __noreturn (*image_entry_noargs_t)(u32 *); - image_entry_noargs_t image_entry = - (image_entry_noargs_t) spl_image.entry_point; - - debug("image entry point: 0x%X\n", spl_image.entry_point); - /* Pass the saved boot_params from rom code */ -#if defined(CONFIG_VIRTIO) || defined(CONFIG_ZEBU) - image_entry = (image_entry_noargs_t)0x80100000; -#endif - u32 boot_params_ptr_addr = (u32)&boot_params_ptr; - image_entry((u32 *)boot_params_ptr_addr); -} - -void board_init_r(gd_t *id, ulong dummy) -{ - u32 boot_device; - debug(">>spl:board_init_r()\n"); - -#ifdef CONFIG_SYS_SPL_MALLOC_START - mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, - CONFIG_SYS_SPL_MALLOC_SIZE); -#endif - -#ifdef CONFIG_SPL_BOARD_INIT - spl_board_init(); -#endif - - boot_device = spl_boot_device(); - debug("boot device - %d\n", boot_device); - switch (boot_device) { -#ifdef CONFIG_SPL_MMC_SUPPORT - case BOOT_DEVICE_MMC1: - case BOOT_DEVICE_MMC2: - case BOOT_DEVICE_MMC2_2: - spl_mmc_load_image(); - break; -#endif -#ifdef CONFIG_SPL_NAND_SUPPORT - case BOOT_DEVICE_NAND: - spl_nand_load_image(); - break; -#endif -#ifdef CONFIG_SPL_YMODEM_SUPPORT - case BOOT_DEVICE_UART: - spl_ymodem_load_image(); - break; -#endif -#ifdef CONFIG_SPL_SPI_SUPPORT - case BOOT_DEVICE_SPI: - spi_boot(); - break; -#endif - default: - puts("SPL: Un-supported Boot Device\n"); - debug("Found: %d\n", boot_device); - hang(); - break; - } - - switch (spl_image.os) { - case IH_OS_U_BOOT: - debug("Jumping to U-Boot\n"); - jump_to_image_no_args(); - break; -#ifdef CONFIG_SPL_OS_BOOT - case IH_OS_LINUX: - debug("Jumping to Linux\n"); - spl_board_prepare_for_linux(); - jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); - break; -#endif - default: - puts("Unsupported OS image.. Jumping nevertheless..\n"); - jump_to_image_no_args(); - } -} - -/* This requires UART clocks to be enabled */ -void preloader_console_init(void) -{ - gd = &gdata; - gd->bd = &bdata; - gd->flags |= GD_FLG_RELOC; - gd->baudrate = CONFIG_BAUDRATE; - - serial_init(); /* serial communications setup */ - - gd->have_console = 1; - - puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ - U_BOOT_TIME ")\n"); -#ifdef CONFIG_SPL_DISPLAY_PRINT - spl_display_print(); -#endif -} diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/arch/arm/cpu/armv7/omap-common/spl_mmc.c deleted file mode 100644 index fdecf94..0000000 --- a/arch/arm/cpu/armv7/omap-common/spl_mmc.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * (C) Copyright 2010 - * Texas Instruments, - * - * Aneesh V - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static void mmc_load_image_raw(struct mmc *mmc) -{ - u32 image_size_sectors, err; - const struct image_header *header; - - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - - sizeof(struct image_header)); - - /* read image header to find the image size & load address */ - err = mmc->block_dev.block_read(0, - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1, - (void *)header); - - if (err <= 0) - goto end; - - spl_parse_image_header(header); - - /* convert size to sectors - round up */ - image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / - mmc->read_bl_len; - - /* Read the header too to avoid extra memcpy */ - err = mmc->block_dev.block_read(0, - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, - image_size_sectors, (void *)spl_image.load_addr); - -end: - if (err <= 0) { - printf("spl: mmc blk read err - %d\n", err); - hang(); - } -} - -#ifdef CONFIG_SPL_FAT_SUPPORT -static void mmc_load_image_fat(struct mmc *mmc) -{ - s32 err; - struct image_header *header; - - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - - sizeof(struct image_header)); - - err = fat_register_device(&mmc->block_dev, - CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION); - if (err) { - printf("spl: fat register err - %d\n", err); - hang(); - } - - err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, - (u8 *)header, sizeof(struct image_header)); - if (err <= 0) - goto end; - - spl_parse_image_header(header); - - err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, - (u8 *)spl_image.load_addr, 0); - -end: - if (err <= 0) { - printf("spl: error reading image %s, err - %d\n", - CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err); - hang(); - } -} -#endif - -void spl_mmc_load_image(void) -{ - struct mmc *mmc; - int err; - u32 boot_mode; - - mmc_initialize(gd->bd); - /* We register only one device. So, the dev id is always 0 */ - mmc = find_mmc_device(0); - if (!mmc) { - puts("spl: mmc device not found!!\n"); - hang(); - } - - err = mmc_init(mmc); - if (err) { - printf("spl: mmc init failed: err - %d\n", err); - hang(); - } - boot_mode = spl_boot_mode(); - if (boot_mode == MMCSD_MODE_RAW) { - debug("boot mode - RAW\n"); - mmc_load_image_raw(mmc); -#ifdef CONFIG_SPL_FAT_SUPPORT - } else if (boot_mode == MMCSD_MODE_FAT) { - debug("boot mode - FAT\n"); - mmc_load_image_fat(mmc); -#endif - } else { - puts("spl: wrong MMC boot mode\n"); - hang(); - } -} diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c index 1e6b5f0..9e9206c 100644 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c @@ -21,7 +21,7 @@ * MA 02111-1307 USA */ #include -#include +#include #include #include #include diff --git a/arch/arm/cpu/armv7/omap-common/spl_ymodem.c b/arch/arm/cpu/armv7/omap-common/spl_ymodem.c deleted file mode 100644 index 65565e3..0000000 --- a/arch/arm/cpu/armv7/omap-common/spl_ymodem.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2011 - * Texas Instruments, - * - * Matt Porter - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include - -#define BUF_SIZE 1024 - -static int getcymodem(void) { - if (tstc()) - return (getc()); - return -1; -} - -void spl_ymodem_load_image(void) -{ - int size = 0; - int err; - int res; - int ret; - connection_info_t info; - char buf[BUF_SIZE]; - ulong store_addr = ~0; - ulong addr = 0; - - info.mode = xyzModem_ymodem; - ret = xyzModem_stream_open(&info, &err); - - if (!ret) { - while ((res = - xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) { - if (addr == 0) - spl_parse_image_header((struct image_header *)buf); - store_addr = addr + spl_image.load_addr; - size += res; - addr += res; - memcpy((char *)(store_addr), buf, res); - } - } else { - printf("spl: ymodem err - %s\n", xyzModem_error(err)); - hang(); - } - - xyzModem_stream_close(&err); - xyzModem_stream_terminate(false, &getcymodem); - - printf("Loaded %d bytes\n", size); -} diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 52196c8..42e2fd9 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -33,13 +33,13 @@ * MA 02111-1307 USA */ #include +#include #include #include #include #include #include #include -#include #include #include #include diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h index 47ca1b6..ad61990 100644 --- a/arch/arm/include/asm/spl.h +++ b/arch/arm/include/asm/spl.h @@ -26,44 +26,4 @@ /* Platform-specific defines */ #include -/* Boot type */ -#define MMCSD_MODE_UNDEFINED 0 -#define MMCSD_MODE_RAW 1 -#define MMCSD_MODE_FAT 2 - -struct spl_image_info { - const char *name; - u8 os; - u32 load_addr; - u32 entry_point; - u32 size; -}; - -extern struct spl_image_info spl_image; -extern u32 *boot_params_ptr; - -/* SPL common functions */ -void preloader_console_init(void); -u32 spl_boot_device(void); -u32 spl_boot_mode(void); -void spl_parse_image_header(const struct image_header *header); -void spl_board_prepare_for_linux(void); -int spl_start_uboot(void); -void spl_display_print(void); - -/* NAND SPL functions */ -void spl_nand_load_image(void); - -/* MMC SPL functions */ -void spl_mmc_load_image(void); - -/* YMODEM SPL functions */ -void spl_ymodem_load_image(void); - -/* SPI SPL functions */ -void spi_boot(void); - -#ifdef CONFIG_SPL_BOARD_INIT -void spl_board_init(void); -#endif #endif diff --git a/common/spl/Makefile b/common/spl/Makefile new file mode 100644 index 0000000..b61b438 --- /dev/null +++ b/common/spl/Makefile @@ -0,0 +1,37 @@ +# +# (C) Copyright 2012 +# Texas Instruments Incorporated - http://www.ti.com/ +# Aneesh V +# +# This file is released under the terms of GPL v2 and any later version. +# See the file COPYING in the root directory of the source tree for details. +# +# Based on common/Makefile. +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)libspl.o + +ifdef CONFIG_SPL_BUILD +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o +COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o +endif + +COBJS := $(sort $(COBJS-y)) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/common/spl/spl.c b/common/spl/spl.c new file mode 100644 index 0000000..1562f2a --- /dev/null +++ b/common/spl/spl.c @@ -0,0 +1,224 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, + * + * Aneesh V + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +u32 *boot_params_ptr = NULL; +struct spl_image_info spl_image; + +/* Define global data structure pointer to it*/ +static gd_t gdata __attribute__ ((section(".data"))); +static bd_t bdata __attribute__ ((section(".data"))); + +inline void hang(void) +{ + puts("### ERROR ### Please RESET the board ###\n"); + for (;;) + ; +} + +void board_init_f(ulong dummy) +{ + /* + * We call relocate_code() with relocation target same as the + * CONFIG_SYS_SPL_TEXT_BASE. This will result in relocation getting + * skipped. Instead, only .bss initialization will happen. That's + * all we need + */ + debug(">>board_init_f()\n"); + relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); +} + +/* + * Default function to determine if u-boot or the OS should + * be started. This implementation always returns 1. + * + * Please implement your own board specific funcion to do this. + * + * RETURN + * 0 to not start u-boot + * positive if u-boot should start + */ +#ifdef CONFIG_SPL_OS_BOOT +__weak int spl_start_uboot(void) +{ + puts("SPL: Please implement spl_start_uboot() for your board\n"); + puts("SPL: Direct Linux boot not active!\n"); + return 1; +} +#endif + +void spl_parse_image_header(const struct image_header *header) +{ + u32 header_size = sizeof(struct image_header); + + if (__be32_to_cpu(header->ih_magic) == IH_MAGIC) { + spl_image.size = __be32_to_cpu(header->ih_size) + header_size; + spl_image.entry_point = __be32_to_cpu(header->ih_load); + /* Load including the header */ + spl_image.load_addr = spl_image.entry_point - header_size; + spl_image.os = header->ih_os; + spl_image.name = (const char *)&header->ih_name; + debug("spl: payload image: %s load addr: 0x%x size: %d\n", + spl_image.name, spl_image.load_addr, spl_image.size); + } else { + /* Signature not found - assume u-boot.bin */ + puts("mkimage signature not found, assuming u-boot.bin ..\n"); + debug("mkimage signature not found - ih_magic = %x\n", + header->ih_magic); + /* Let's assume U-Boot will not be more than 200 KB */ + spl_image.size = 200 * 1024; + spl_image.entry_point = CONFIG_SYS_TEXT_BASE; + spl_image.load_addr = CONFIG_SYS_TEXT_BASE; + spl_image.os = IH_OS_U_BOOT; + spl_image.name = "U-Boot"; + } +} + +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +static void __noreturn jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + cleanup_before_linux(); + image_entry(0, CONFIG_MACH_TYPE, arg); +} +#endif + +static void __noreturn jump_to_image_no_args(void) +{ + typedef void __noreturn (*image_entry_noargs_t)(u32 *); + image_entry_noargs_t image_entry = + (image_entry_noargs_t) spl_image.entry_point; + + debug("image entry point: 0x%X\n", spl_image.entry_point); + /* Pass the saved boot_params from rom code */ +#if defined(CONFIG_VIRTIO) || defined(CONFIG_ZEBU) + image_entry = (image_entry_noargs_t)0x80100000; +#endif + u32 boot_params_ptr_addr = (u32)&boot_params_ptr; + image_entry((u32 *)boot_params_ptr_addr); +} + +void board_init_r(gd_t *id, ulong dummy) +{ + u32 boot_device; + debug(">>spl:board_init_r()\n"); + +#ifdef CONFIG_SYS_SPL_MALLOC_START + mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, + CONFIG_SYS_SPL_MALLOC_SIZE); +#endif + +#ifdef CONFIG_SPL_BOARD_INIT + spl_board_init(); +#endif + + boot_device = spl_boot_device(); + debug("boot device - %d\n", boot_device); + switch (boot_device) { +#ifdef CONFIG_SPL_MMC_SUPPORT + case BOOT_DEVICE_MMC1: + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC2_2: + spl_mmc_load_image(); + break; +#endif +#ifdef CONFIG_SPL_NAND_SUPPORT + case BOOT_DEVICE_NAND: + spl_nand_load_image(); + break; +#endif +#ifdef CONFIG_SPL_YMODEM_SUPPORT + case BOOT_DEVICE_UART: + spl_ymodem_load_image(); + break; +#endif +#ifdef CONFIG_SPL_SPI_SUPPORT + case BOOT_DEVICE_SPI: + spi_boot(); + break; +#endif + default: + puts("SPL: Un-supported Boot Device\n"); + debug("Found: %d\n", boot_device); + hang(); + break; + } + + switch (spl_image.os) { + case IH_OS_U_BOOT: + debug("Jumping to U-Boot\n"); + jump_to_image_no_args(); + break; +#ifdef CONFIG_SPL_OS_BOOT + case IH_OS_LINUX: + debug("Jumping to Linux\n"); + spl_board_prepare_for_linux(); + jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); + break; +#endif + default: + puts("Unsupported OS image.. Jumping nevertheless..\n"); + jump_to_image_no_args(); + } +} + +/* This requires UART clocks to be enabled */ +void preloader_console_init(void) +{ + gd = &gdata; + gd->bd = &bdata; + gd->flags |= GD_FLG_RELOC; + gd->baudrate = CONFIG_BAUDRATE; + + serial_init(); /* serial communications setup */ + + gd->have_console = 1; + + puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ + U_BOOT_TIME ")\n"); +#ifdef CONFIG_SPL_DISPLAY_PRINT + spl_display_print(); +#endif +} diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c new file mode 100644 index 0000000..40e5035 --- /dev/null +++ b/common/spl/spl_ymodem.c @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2011 + * Texas Instruments, + * + * Matt Porter + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +#define BUF_SIZE 1024 + +static int getcymodem(void) { + if (tstc()) + return (getc()); + return -1; +} + +void spl_ymodem_load_image(void) +{ + int size = 0; + int err; + int res; + int ret; + connection_info_t info; + char buf[BUF_SIZE]; + ulong store_addr = ~0; + ulong addr = 0; + + info.mode = xyzModem_ymodem; + ret = xyzModem_stream_open(&info, &err); + + if (!ret) { + while ((res = + xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) { + if (addr == 0) + spl_parse_image_header((struct image_header *)buf); + store_addr = addr + spl_image.load_addr; + size += res; + addr += res; + memcpy((char *)(store_addr), buf, res); + } + } else { + printf("spl: ymodem err - %s\n", xyzModem_error(err)); + hang(); + } + + xyzModem_stream_close(&err); + xyzModem_stream_terminate(false, &getcymodem); + + printf("Loaded %d bytes\n", size); +} diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 2b96cdc..941a909 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -25,8 +25,11 @@ include $(TOPDIR)/config.mk LIB := $(obj)libmmc.o -ifdef CONFIG_SPL_MMC_LOAD +ifdef CONFIG_SPL_BUILD COBJS-$(CONFIG_SPL_MMC_LOAD) += spl_mmc_load.o +ifdef CONFIG_SPL_FRAMEWORK +COBJS-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o +endif endif COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o diff --git a/drivers/mmc/spl_mmc.c b/drivers/mmc/spl_mmc.c new file mode 100644 index 0000000..753c6a0 --- /dev/null +++ b/drivers/mmc/spl_mmc.c @@ -0,0 +1,136 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, + * + * Aneesh V + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static void mmc_load_image_raw(struct mmc *mmc) +{ + u32 image_size_sectors, err; + const struct image_header *header; + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + /* read image header to find the image size & load address */ + err = mmc->block_dev.block_read(0, + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1, + (void *)header); + + if (err <= 0) + goto end; + + spl_parse_image_header(header); + + /* convert size to sectors - round up */ + image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / + mmc->read_bl_len; + + /* Read the header too to avoid extra memcpy */ + err = mmc->block_dev.block_read(0, + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, + image_size_sectors, (void *)spl_image.load_addr); + +end: + if (err <= 0) { + printf("spl: mmc blk read err - %d\n", err); + hang(); + } +} + +#ifdef CONFIG_SPL_FAT_SUPPORT +static void mmc_load_image_fat(struct mmc *mmc) +{ + s32 err; + struct image_header *header; + + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct image_header)); + + err = fat_register_device(&mmc->block_dev, + CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION); + if (err) { + printf("spl: fat register err - %d\n", err); + hang(); + } + + err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, + (u8 *)header, sizeof(struct image_header)); + if (err <= 0) + goto end; + + spl_parse_image_header(header); + + err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, + (u8 *)spl_image.load_addr, 0); + +end: + if (err <= 0) { + printf("spl: error reading image %s, err - %d\n", + CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err); + hang(); + } +} +#endif + +void spl_mmc_load_image(void) +{ + struct mmc *mmc; + int err; + u32 boot_mode; + + mmc_initialize(gd->bd); + /* We register only one device. So, the dev id is always 0 */ + mmc = find_mmc_device(0); + if (!mmc) { + puts("spl: mmc device not found!!\n"); + hang(); + } + + err = mmc_init(mmc); + if (err) { + printf("spl: mmc init failed: err - %d\n", err); + hang(); + } + boot_mode = spl_boot_mode(); + if (boot_mode == MMCSD_MODE_RAW) { + debug("boot mode - RAW\n"); + mmc_load_image_raw(mmc); +#ifdef CONFIG_SPL_FAT_SUPPORT + } else if (boot_mode == MMCSD_MODE_FAT) { + debug("boot mode - FAT\n"); + mmc_load_image_fat(mmc); +#endif + } else { + puts("spl: wrong MMC boot mode\n"); + hang(); + } +} diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index a3752bc..263a5ad 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -193,6 +193,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_TEXT_BASE 0x402F0400 #define CONFIG_SPL_MAX_SIZE (46 * 1024) #define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR diff --git a/include/configs/am3517_crane.h b/include/configs/am3517_crane.h index 254ed57..8ddeff4 100644 --- a/include/configs/am3517_crane.h +++ b/include/configs/am3517_crane.h @@ -314,6 +314,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h index ca39c72..6980811 100644 --- a/include/configs/am3517_evm.h +++ b/include/configs/am3517_evm.h @@ -313,6 +313,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index de75daf..2d2ee5f 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -303,6 +303,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_LIBCOMMON_SUPPORT diff --git a/include/configs/igep00x0.h b/include/configs/igep00x0.h index 5468a1a..b1071e8 100644 --- a/include/configs/igep00x0.h +++ b/include/configs/igep00x0.h @@ -295,6 +295,7 @@ /* SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) diff --git a/include/configs/mcx.h b/include/configs/mcx.h index a841c70..359522a 100644 --- a/include/configs/mcx.h +++ b/include/configs/mcx.h @@ -359,6 +359,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_NAND_SOFTECC diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h index 782a4c5..f79f996 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -391,6 +391,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) /* 8 KB for stack */ diff --git a/include/configs/omap3_evm_common.h b/include/configs/omap3_evm_common.h index d9578f4..2ef3aaa 100644 --- a/include/configs/omap3_evm_common.h +++ b/include/configs/omap3_evm_common.h @@ -273,6 +273,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) /* 8 KB for stack */ #define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h index dd4b2c0..f6d6f75 100644 --- a/include/configs/omap3_overo.h +++ b/include/configs/omap3_overo.h @@ -293,6 +293,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_TEXT_BASE 0x40200800 #define CONFIG_SPL_MAX_SIZE (54 * 1024) /* 8 KB for stack */ diff --git a/include/configs/omap4_common.h b/include/configs/omap4_common.h index c1c2fa9..cbc9bdb 100644 --- a/include/configs/omap4_common.h +++ b/include/configs/omap4_common.h @@ -232,6 +232,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_TEXT_BASE 0x40304350 #define CONFIG_SPL_MAX_SIZE (38 * 1024) #define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR diff --git a/include/configs/omap5_evm.h b/include/configs/omap5_evm.h index b4a237a..743edfd 100644 --- a/include/configs/omap5_evm.h +++ b/include/configs/omap5_evm.h @@ -229,6 +229,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_TEXT_BASE 0x40300350 #define CONFIG_SPL_MAX_SIZE 0x19000 /* 100K */ #define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR diff --git a/include/configs/tam3517-common.h b/include/configs/tam3517-common.h index b34cb78..cbb6c7e 100644 --- a/include/configs/tam3517-common.h +++ b/include/configs/tam3517-common.h @@ -239,6 +239,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_CONSOLE #define CONFIG_SPL_NAND_SIMPLE diff --git a/include/configs/tricorder.h b/include/configs/tricorder.h index 63c98dc..00d02e8 100644 --- a/include/configs/tricorder.h +++ b/include/configs/tricorder.h @@ -271,6 +271,7 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK #define CONFIG_SPL_NAND_SIMPLE #define CONFIG_SPL_BOARD_INIT diff --git a/include/spl.h b/include/spl.h new file mode 100644 index 0000000..af9ef71 --- /dev/null +++ b/include/spl.h @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _SPL_H_ +#define _SPL_H_ + +/* Platform-specific defines */ +#include + +/* Boot type */ +#define MMCSD_MODE_UNDEFINED 0 +#define MMCSD_MODE_RAW 1 +#define MMCSD_MODE_FAT 2 + +struct spl_image_info { + const char *name; + u8 os; + u32 load_addr; + u32 entry_point; + u32 size; +}; + +extern struct spl_image_info spl_image; +extern u32 *boot_params_ptr; + +/* SPL common functions */ +void preloader_console_init(void); +u32 spl_boot_device(void); +u32 spl_boot_mode(void); +void spl_parse_image_header(const struct image_header *header); +void spl_board_prepare_for_linux(void); +int spl_start_uboot(void); +void spl_display_print(void); + +/* NAND SPL functions */ +void spl_nand_load_image(void); + +/* MMC SPL functions */ +void spl_mmc_load_image(void); + +/* YMODEM SPL functions */ +void spl_ymodem_load_image(void); + +/* SPI SPL functions */ +void spi_boot(void); + +#ifdef CONFIG_SPL_BOARD_INIT +void spl_board_init(void); +#endif +#endif diff --git a/spl/Makefile b/spl/Makefile index d4cb668..d9b1c2f 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -41,6 +41,7 @@ endif LIBS-y += board/$(BOARDDIR)/lib$(BOARD).o LIBS-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/lib$(VENDOR).o +LIBS-$(CONFIG_SPL_FRAMEWORK) += common/spl/libspl.o LIBS-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/libcommon.o LIBS-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/libdisk.o LIBS-$(CONFIG_SPL_I2C_SUPPORT) += drivers/i2c/libi2c.o -- cgit v1.1 From 6507f133f3201ed5fb22e4a3d73c33b47497539d Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 22 Aug 2012 15:31:05 -0700 Subject: SPL: Create arch/arm/lib/spl.c for board_init_f and jump_to_image_linux In SPL (CONFIG_SPL_FRAMEWORK) board_init_f must setup the stack pointer, clear the BSS and call board_init_r. We mark this as weak as some platforms may need to perform additional initalization at this point. We provide a gd that we know will be in a usable location, once the BSS has been cleared to help with this as well. Finally, we no longer call relocate_code so remove that from the armv7 version. Next, both board_init_f and jump_to_image_linux are going to be inherently arch-specific, so move these versions to arch/arm/lib/spl.c Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/am33xx/board.c | 2 + arch/arm/cpu/armv7/omap-common/hwinit-common.c | 3 ++ arch/arm/cpu/armv7/omap3/board.c | 4 ++ arch/arm/cpu/armv7/start.S | 13 +---- arch/arm/include/asm/spl.h | 5 ++ arch/arm/lib/Makefile | 2 + arch/arm/lib/spl.c | 72 ++++++++++++++++++++++++++ common/spl/spl.c | 41 +++------------ include/spl.h | 2 + 9 files changed, 98 insertions(+), 46 deletions(-) create mode 100644 arch/arm/lib/spl.c diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c index c45b19b..978b184 100644 --- a/arch/arm/cpu/armv7/am33xx/board.c +++ b/arch/arm/cpu/armv7/am33xx/board.c @@ -166,6 +166,8 @@ void s_init(void) regVal |= UART_SMART_IDLE_EN; writel(regVal, &uart_base->uartsyscfg); + gd = &gdata; + preloader_console_init(); /* Initalize the board header */ diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c index ad8b5ac..9ef10bd 100644 --- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c +++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c @@ -124,6 +124,9 @@ void s_init(void) set_mux_conf_regs(); #ifdef CONFIG_SPL_BUILD setup_clocks_for_console(); + + gd = &gdata; + preloader_console_init(); do_io_settings(); #endif diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c index 42e2fd9..9cee1d9 100644 --- a/arch/arm/cpu/armv7/omap3/board.c +++ b/arch/arm/cpu/armv7/omap3/board.c @@ -45,6 +45,8 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + /* Declarations */ extern omap3_sysinfo sysinfo; static void omap3_setup_aux_cr(void); @@ -252,6 +254,8 @@ void s_init(void) #endif #ifdef CONFIG_SPL_BUILD + gd = &gdata; + preloader_console_init(); timer_init(); diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 32658eb..f26308d 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -164,6 +164,7 @@ call_board_init_f: /*------------------------------------------------------------------------------*/ +#ifndef CONFIG_SPL_BUILD /* * void relocate_code (addr_sp, gd, addr_moni) * @@ -194,7 +195,6 @@ copy_loop: cmp r0, r2 /* until source end address [r2] */ blo copy_loop -#ifndef CONFIG_SPL_BUILD /* * fix .rel.dyn relocations */ @@ -241,20 +241,12 @@ _rel_dyn_end_ofs: _dynsym_start_ofs: .word __dynsym_start - _start -#endif /* #ifndef CONFIG_SPL_BUILD */ - clear_bss: -#ifdef CONFIG_SPL_BUILD - /* No relocation for SPL */ - ldr r0, =__bss_start - ldr r1, =__bss_end__ -#else ldr r0, _bss_start_ofs ldr r1, _bss_end_ofs mov r4, r6 /* reloc addr */ add r0, r0, r4 add r1, r1, r4 -#endif mov r2, #0x00000000 /* clear */ clbss_l:cmp r0, r1 /* clear loop... */ @@ -281,12 +273,10 @@ jump_2_ram: * Move vector table */ #if !defined(CONFIG_TEGRA20) -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) /* Set vector address in CP15 VBAR register */ ldr r0, =_start add r0, r0, r9 mcr p15, 0, r0, c12, c0, 0 @Set VBAR -#endif #endif /* !Tegra20 */ ldr r0, _board_init_r_ofs @@ -302,6 +292,7 @@ jump_2_ram: _board_init_r_ofs: .word board_init_r - _start ENDPROC(relocate_code) +#endif /************************************************************************* * diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h index ad61990..62011aa 100644 --- a/arch/arm/include/asm/spl.h +++ b/arch/arm/include/asm/spl.h @@ -26,4 +26,9 @@ /* Platform-specific defines */ #include +/* Linker symbols. */ +extern char __bss_start[], __bss_end__[]; + +extern gd_t gdata; + #endif diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index bd3b77f..3422ac1 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -44,6 +44,8 @@ COBJS-y += interrupts.o COBJS-y += reset.o SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o +else +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o endif COBJS-y += cache.o diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c new file mode 100644 index 0000000..f568f61 --- /dev/null +++ b/arch/arm/lib/spl.c @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2010-2012 + * Texas Instruments, + * + * Aneesh V + * Tom Rini + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +/* Pointer to as well as the global data structure for SPL */ +DECLARE_GLOBAL_DATA_PTR; +gd_t gdata __attribute__ ((section(".data"))); + +/* + * In the context of SPL, board_init_f must ensure that any clocks/etc for + * DDR are enabled, ensure that the stack pointer is valid, clear the BSS + * and call board_init_f. We provide this version by default but mark it + * as __weak to allow for platforms to do this in their own way if needed. + */ +void __weak board_init_f(ulong dummy) +{ + /* Set the stack pointer. */ + asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end__ - __bss_start); + + /* Set global data pointer. */ + gd = &gdata; + + board_init_r(NULL, 0); +} + +/* + * This function jumps to an image with argument. Normally an FDT or ATAGS + * image. + * arg: Pointer to paramter image in RAM + */ +#ifdef CONFIG_SPL_OS_BOOT +void __noreturn jump_to_image_linux(void *arg) +{ + debug("Entering kernel arg pointer: 0x%p\n", arg); + typedef void (*image_entry_arg_t)(int, int, void *) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t) spl_image.entry_point; + cleanup_before_linux(); + image_entry(0, CONFIG_MACH_TYPE, arg); +} +#endif diff --git a/common/spl/spl.c b/common/spl/spl.c index 1562f2a..3f41014 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -38,8 +38,7 @@ DECLARE_GLOBAL_DATA_PTR; u32 *boot_params_ptr = NULL; struct spl_image_info spl_image; -/* Define global data structure pointer to it*/ -static gd_t gdata __attribute__ ((section(".data"))); +/* Define board data structure */ static bd_t bdata __attribute__ ((section(".data"))); inline void hang(void) @@ -49,18 +48,6 @@ inline void hang(void) ; } -void board_init_f(ulong dummy) -{ - /* - * We call relocate_code() with relocation target same as the - * CONFIG_SYS_SPL_TEXT_BASE. This will result in relocation getting - * skipped. Instead, only .bss initialization will happen. That's - * all we need - */ - debug(">>board_init_f()\n"); - relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); -} - /* * Default function to determine if u-boot or the OS should * be started. This implementation always returns 1. @@ -107,24 +94,6 @@ void spl_parse_image_header(const struct image_header *header) } } -/* - * This function jumps to an image with argument. Normally an FDT or ATAGS - * image. - * arg: Pointer to paramter image in RAM - */ -#ifdef CONFIG_SPL_OS_BOOT -static void __noreturn jump_to_image_linux(void *arg) -{ - debug("Entering kernel arg pointer: 0x%p\n", arg); - typedef void (*image_entry_arg_t)(int, int, void *) - __attribute__ ((noreturn)); - image_entry_arg_t image_entry = - (image_entry_arg_t) spl_image.entry_point; - cleanup_before_linux(); - image_entry(0, CONFIG_MACH_TYPE, arg); -} -#endif - static void __noreturn jump_to_image_no_args(void) { typedef void __noreturn (*image_entry_noargs_t)(u32 *); @@ -140,7 +109,7 @@ static void __noreturn jump_to_image_no_args(void) image_entry((u32 *)boot_params_ptr_addr); } -void board_init_r(gd_t *id, ulong dummy) +void board_init_r(gd_t *dummy1, ulong dummy2) { u32 boot_device; debug(">>spl:board_init_r()\n"); @@ -204,10 +173,12 @@ void board_init_r(gd_t *id, ulong dummy) } } -/* This requires UART clocks to be enabled */ +/* + * This requires UART clocks to be enabled. In order for this to work the + * caller must ensure that the gd pointer is valid. + */ void preloader_console_init(void) { - gd = &gdata; gd->bd = &bdata; gd->flags |= GD_FLG_RELOC; gd->baudrate = CONFIG_BAUDRATE; diff --git a/include/spl.h b/include/spl.h index af9ef71..2923cd2 100644 --- a/include/spl.h +++ b/include/spl.h @@ -24,6 +24,7 @@ #define _SPL_H_ /* Platform-specific defines */ +#include #include /* Boot type */ @@ -48,6 +49,7 @@ u32 spl_boot_device(void); u32 spl_boot_mode(void); void spl_parse_image_header(const struct image_header *header); void spl_board_prepare_for_linux(void); +void __noreturn jump_to_image_linux(void *arg); int spl_start_uboot(void); void spl_display_print(void); -- cgit v1.1 From ae83d882f5fdf7aa7c5aec09cfafb593153c25d6 Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Thu, 23 Aug 2012 12:46:16 +0200 Subject: SPL: do not use fix value for u-boot size If an u-boot image is not found, SPL thinks to load a bare u-boot.bin image with a maximum size of 200KB. Use CONFIG_SYS_MONITOR_LEN instead. Signed-off-by: Stefan Roese Signed-off-by: Stefano Babic Signed-off-by: Tom Rini --- common/spl/spl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/spl/spl.c b/common/spl/spl.c index 3f41014..70c374a 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -35,6 +35,10 @@ DECLARE_GLOBAL_DATA_PTR; +#ifndef CONFIG_SYS_MONITOR_LEN +#define CONFIG_SYS_MONITOR_LEN (200 * 1024) +#endif + u32 *boot_params_ptr = NULL; struct spl_image_info spl_image; @@ -86,7 +90,7 @@ void spl_parse_image_header(const struct image_header *header) debug("mkimage signature not found - ih_magic = %x\n", header->ih_magic); /* Let's assume U-Boot will not be more than 200 KB */ - spl_image.size = 200 * 1024; + spl_image.size = CONFIG_SYS_MONITOR_LEN; spl_image.entry_point = CONFIG_SYS_TEXT_BASE; spl_image.load_addr = CONFIG_SYS_TEXT_BASE; spl_image.os = IH_OS_U_BOOT; -- cgit v1.1 From 77552b0633f0856f6bb73b8e1f75334601c6a5c9 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 27 Aug 2012 12:50:57 +0200 Subject: SPL: Use image_get_xxx() functions to access header values Signed-off-by: Stefan Roese Signed-off-by: Tom Rini --- common/spl/spl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/spl/spl.c b/common/spl/spl.c index 70c374a..3b4fcba 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -75,13 +75,13 @@ void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); - if (__be32_to_cpu(header->ih_magic) == IH_MAGIC) { - spl_image.size = __be32_to_cpu(header->ih_size) + header_size; - spl_image.entry_point = __be32_to_cpu(header->ih_load); + if (image_get_magic(header) == IH_MAGIC) { + spl_image.size = image_get_data_size(header) + header_size; + spl_image.entry_point = image_get_load(header); /* Load including the header */ spl_image.load_addr = spl_image.entry_point - header_size; - spl_image.os = header->ih_os; - spl_image.name = (const char *)&header->ih_name; + spl_image.os = image_get_os(header); + spl_image.name = image_get_name(header); debug("spl: payload image: %s load addr: 0x%x size: %d\n", spl_image.name, spl_image.load_addr, spl_image.size); } else { -- cgit v1.1 From d97b4ce8056ff01ca8f1a63a7c69fa5316d33830 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 14 Aug 2012 14:33:02 -0700 Subject: SPL: NAND: Move arch/arm/cpu/armv7/omap-common/spl_nand.c to common/spl We move the spl_nand_load_image function to common/spl. This will allow for easier integration of SPL-boots-Linux code on other arches. Signed-off-by: Tom Rini --- arch/arm/cpu/armv7/omap-common/Makefile | 6 -- arch/arm/cpu/armv7/omap-common/spl_nand.c | 102 ------------------------------ common/spl/Makefile | 1 + common/spl/spl_nand.c | 100 +++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 108 deletions(-) delete mode 100644 arch/arm/cpu/armv7/omap-common/spl_nand.c create mode 100644 common/spl/spl_nand.c diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index 6e815c6..1f2fa02 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -42,12 +42,6 @@ COBJS += boot-common.o SOBJS += lowlevel_init.o endif -ifdef CONFIG_SPL_BUILD -ifdef CONFIG_SPL_NAND_SUPPORT -COBJS += spl_nand.o -endif -endif - ifndef CONFIG_SPL_BUILD ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) COBJS += mem-common.o diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c deleted file mode 100644 index 9e9206c..0000000 --- a/arch/arm/cpu/armv7/omap-common/spl_nand.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2011 - * Corscience GmbH & Co. KG - Simon Schwarz - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include -#include - -void spl_nand_load_image(void) -{ - struct image_header *header; - int *src __attribute__((unused)); - int *dst __attribute__((unused)); - - debug("spl: nand - using hw ecc\n"); - nand_init(); - - /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); -#ifdef CONFIG_SPL_OS_BOOT - if (!spl_start_uboot()) { - /* - * load parameter image - * load to temp position since nand_spl_load_image reads - * a whole block which is typically larger than - * CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite - * following sections like BSS - */ - nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, - CONFIG_CMD_SPL_WRITE_SIZE, - (void *)CONFIG_SYS_TEXT_BASE); - /* copy to destintion */ - for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, - src = (int *)CONFIG_SYS_TEXT_BASE; - src < (int *)(CONFIG_SYS_TEXT_BASE + - CONFIG_CMD_SPL_WRITE_SIZE); - src++, dst++) { - writel(readl(src), dst); - } - - /* load linux */ - nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - if (header->ih_os == IH_OS_LINUX) { - /* happy - was a linux */ - nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, - spl_image.size, (void *)spl_image.load_addr); - nand_deselect(); - return; - } else { - printf("The Expected Linux image was not" - "found. Please check your NAND" - "configuration.\n"); - printf("Trying to start u-boot now...\n"); - } - } -#endif -#ifdef CONFIG_NAND_ENV_DST - nand_spl_load_image(CONFIG_ENV_OFFSET, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, - (void *)spl_image.load_addr); -#ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, - (void *)spl_image.load_addr); -#endif -#endif - /* Load u-boot */ - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); - spl_parse_image_header(header); - nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, - spl_image.size, (void *)spl_image.load_addr); - nand_deselect(); -} diff --git a/common/spl/Makefile b/common/spl/Makefile index b61b438..b9c9fd8 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -16,6 +16,7 @@ LIB = $(obj)libspl.o ifdef CONFIG_SPL_BUILD COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o +COBJS-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o endif COBJS := $(sort $(COBJS-y)) diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c new file mode 100644 index 0000000..61de5a4 --- /dev/null +++ b/common/spl/spl_nand.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + +void spl_nand_load_image(void) +{ + struct image_header *header; + int *src __attribute__((unused)); + int *dst __attribute__((unused)); + + debug("spl: nand - using hw ecc\n"); + nand_init(); + + /*use CONFIG_SYS_TEXT_BASE as temporary storage area */ + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_start_uboot()) { + /* + * load parameter image + * load to temp position since nand_spl_load_image reads + * a whole block which is typically larger than + * CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite + * following sections like BSS + */ + nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, + CONFIG_CMD_SPL_WRITE_SIZE, + (void *)CONFIG_SYS_TEXT_BASE); + /* copy to destintion */ + for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, + src = (int *)CONFIG_SYS_TEXT_BASE; + src < (int *)(CONFIG_SYS_TEXT_BASE + + CONFIG_CMD_SPL_WRITE_SIZE); + src++, dst++) { + writel(readl(src), dst); + } + + /* load linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + if (header->ih_os == IH_OS_LINUX) { + /* happy - was a linux */ + nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, + spl_image.size, (void *)spl_image.load_addr); + nand_deselect(); + return; + } else { + puts("The Expected Linux image was not " + "found. Please check your NAND " + "configuration.\n"); + puts("Trying to start u-boot now...\n"); + } + } +#endif +#ifdef CONFIG_NAND_ENV_DST + nand_spl_load_image(CONFIG_ENV_OFFSET, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, + (void *)spl_image.load_addr); +#ifdef CONFIG_ENV_OFFSET_REDUND + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, + (void *)spl_image.load_addr); +#endif +#endif + /* Load u-boot */ + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); + spl_parse_image_header(header); + nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); + nand_deselect(); +} -- cgit v1.1 From 460f949f897a401b40327be7a1a9cccd22762c77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Fri, 10 Aug 2012 07:56:21 +0000 Subject: net: eth_write_hwaddr: Return error for invalid MACs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If dev->enetaddr was supposed to be set with dev->write_hwaddr() but the MAC address was not valid, return an error. Signed-off-by: Benoît Thébaudeau Cc: Joe Hershberger Acked-by: Mike Frysinger --- net/eth.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/eth.c b/net/eth.c index 49458c8..321d5b1 100644 --- a/net/eth.c +++ b/net/eth.c @@ -218,9 +218,12 @@ int eth_write_hwaddr(struct eth_device *dev, const char *base_name, } if (dev->write_hwaddr && - !eth_mac_skip(eth_number) && - is_valid_ether_addr(dev->enetaddr)) + !eth_mac_skip(eth_number)) { + if (!is_valid_ether_addr(dev->enetaddr)) + return -1; + ret = dev->write_hwaddr(dev); + } return ret; } -- cgit v1.1 From b737337aaf7d266f0e5228d1129ac40e300878f8 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Thu, 16 Aug 2012 01:17:26 +0000 Subject: net/phy: support the mv88e6352 switch This patch add support for the configuration of an external switch from the 88E6xxx series from Marvell trough an MDIO link using indirect adressing. This can be used if we do not want to use an EEPROM for the configuration. This driver is not generic and was not tested on other switches than the 88e6352. This is proposed as a first implementation that is somewhat limited but works and that can be used as a basis for further developments for this switch family. Signed-off-by: Valentin Longchamp cc: Holger Brunck cc: Prafulla Wadaskar cc: Joe Hershberger --- drivers/net/phy/Makefile | 1 + drivers/net/phy/mv88e6352.c | 318 ++++++++++++++++++++++++++++++++++++++++++++ include/mv88e6352.h | 92 +++++++++++++ 3 files changed, 411 insertions(+) create mode 100644 drivers/net/phy/mv88e6352.c create mode 100644 include/mv88e6352.h diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index feced39..5e90d70 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -27,6 +27,7 @@ LIB := $(obj)libphy.o COBJS-$(CONFIG_BITBANGMII) += miiphybb.o COBJS-$(CONFIG_MV88E61XX_SWITCH) += mv88e61xx.o +COBJS-$(CONFIG_MV88E6352_SWITCH) += mv88e6352.o COBJS-$(CONFIG_PHYLIB) += phy.o COBJS-$(CONFIG_PHYLIB_10G) += generic_10g.o diff --git a/drivers/net/phy/mv88e6352.c b/drivers/net/phy/mv88e6352.c new file mode 100644 index 0000000..7269a6a --- /dev/null +++ b/drivers/net/phy/mv88e6352.c @@ -0,0 +1,318 @@ +/* + * (C) Copyright 2012 + * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#define SMI_HDR ((0x8 | 0x1) << 12) +#define SMI_BUSY_MASK (0x8000) +#define SMIRD_OP (0x2 << 10) +#define SMIWR_OP (0x1 << 10) +#define SMI_MASK 0x1f +#define PORT_SHIFT 5 + +#define COMMAND_REG 0 +#define DATA_REG 1 + +/* global registers */ +#define GLOBAL 0x1b + +#define GLOBAL_STATUS 0x00 +#define PPU_STATE 0x8000 + +#define GLOBAL_CTRL 0x04 +#define SW_RESET 0x8000 +#define PPU_ENABLE 0x4000 + +static int sw_wait_rdy(const char *devname, u8 phy_addr) +{ + u16 command; + u32 timeout = 100; + int ret; + + /* wait till the SMI is not busy */ + do { + /* read command register */ + ret = miiphy_read(devname, phy_addr, COMMAND_REG, &command); + if (ret < 0) { + printf("%s: Error reading command register\n", + __func__); + return ret; + } + if (timeout-- == 0) { + printf("Err..(%s) SMI busy timeout\n", __func__); + return -EFAULT; + } + } while (command & SMI_BUSY_MASK); + + return 0; +} + +static int sw_reg_read(const char *devname, u8 phy_addr, u8 port, + u8 reg, u16 *data) +{ + int ret; + u16 command; + + ret = sw_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + command = SMI_HDR | SMIRD_OP | ((port&SMI_MASK) << PORT_SHIFT) | + (reg & SMI_MASK); + debug("%s: write to command: %#x\n", __func__, command); + ret = miiphy_write(devname, phy_addr, COMMAND_REG, command); + if (ret) + return ret; + + ret = sw_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + ret = miiphy_read(devname, phy_addr, DATA_REG, data); + + return ret; +} + +static int sw_reg_write(const char *devname, u8 phy_addr, u8 port, + u8 reg, u16 data) +{ + int ret; + u16 value; + + ret = sw_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + debug("%s: write to data: %#x\n", __func__, data); + ret = miiphy_write(devname, phy_addr, DATA_REG, data); + if (ret) + return ret; + + value = SMI_HDR | SMIWR_OP | ((port & SMI_MASK) << PORT_SHIFT) | + (reg & SMI_MASK); + debug("%s: write to command: %#x\n", __func__, value); + ret = miiphy_write(devname, phy_addr, COMMAND_REG, value); + if (ret) + return ret; + + ret = sw_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + return 0; +} + +static int ppu_enable(const char *devname, u8 phy_addr) +{ + int i, ret = 0; + u16 reg; + + ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, ®); + if (ret) { + printf("%s: Error reading global ctrl reg\n", __func__); + return ret; + } + + reg |= PPU_ENABLE; + + ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg); + if (ret) { + printf("%s: Error writing global ctrl reg\n", __func__); + return ret; + } + + for (i = 0; i < 1000; i++) { + sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS, + ®); + if ((reg & 0xc000) == 0xc000) + return 0; + udelay(1000); + } + + return -ETIMEDOUT; +} + +static int ppu_disable(const char *devname, u8 phy_addr) +{ + int i, ret = 0; + u16 reg; + + ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, ®); + if (ret) { + printf("%s: Error reading global ctrl reg\n", __func__); + return ret; + } + + reg &= ~PPU_ENABLE; + + ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg); + if (ret) { + printf("%s: Error writing global ctrl reg\n", __func__); + return ret; + } + + for (i = 0; i < 1000; i++) { + sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS, + ®); + if ((reg & 0xc000) != 0xc000) + return 0; + udelay(1000); + } + + return -ETIMEDOUT; +} + +int mv88e_sw_program(const char *devname, u8 phy_addr, + struct mv88e_sw_reg *regs, int regs_nb) +{ + int i, ret = 0; + + /* first we need to disable the PPU */ + ret = ppu_disable(devname, phy_addr); + if (ret) { + printf("%s: Error disabling PPU\n", __func__); + return ret; + } + + for (i = 0; i < regs_nb; i++) { + ret = sw_reg_write(devname, phy_addr, regs[i].port, + regs[i].reg, regs[i].value); + if (ret) { + printf("%s: Error configuring switch\n", __func__); + ppu_enable(devname, phy_addr); + return ret; + } + } + + /* re-enable the PPU */ + ret = ppu_enable(devname, phy_addr); + if (ret) { + printf("%s: Error enabling PPU\n", __func__); + return ret; + } + + return 0; +} + +int mv88e_sw_reset(const char *devname, u8 phy_addr) +{ + int i, ret = 0; + u16 reg; + + ret = sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_CTRL, ®); + if (ret) { + printf("%s: Error reading global ctrl reg\n", __func__); + return ret; + } + + reg = SW_RESET | PPU_ENABLE | 0x0400; + + ret = sw_reg_write(devname, phy_addr, GLOBAL, GLOBAL_CTRL, reg); + if (ret) { + printf("%s: Error writing global ctrl reg\n", __func__); + return ret; + } + + for (i = 0; i < 1000; i++) { + sw_reg_read(devname, phy_addr, GLOBAL, GLOBAL_STATUS, + ®); + if ((reg & 0xc800) != 0xc800) + return 0; + udelay(1000); + } + + return -ETIMEDOUT; +} + +int do_mvsw_reg_read(const char *name, int argc, char * const argv[]) +{ + u16 value = 0, phyaddr, reg, port; + int ret; + + phyaddr = simple_strtoul(argv[1], NULL, 10); + port = simple_strtoul(argv[2], NULL, 10); + reg = simple_strtoul(argv[3], NULL, 10); + + ret = sw_reg_read(name, phyaddr, port, reg, &value); + printf("%#x\n", value); + + return ret; +} + +int do_mvsw_reg_write(const char *name, int argc, char * const argv[]) +{ + u16 value = 0, phyaddr, reg, port; + int ret; + + phyaddr = simple_strtoul(argv[1], NULL, 10); + port = simple_strtoul(argv[2], NULL, 10); + reg = simple_strtoul(argv[3], NULL, 10); + value = simple_strtoul(argv[4], NULL, 16); + + ret = sw_reg_write(name, phyaddr, port, reg, value); + + return ret; +} + + +int do_mvsw_reg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int ret; + const char *cmd, *ethname; + + if (argc < 2) + return cmd_usage(cmdtp); + + cmd = argv[1]; + --argc; + ++argv; + + if (strcmp(cmd, "read") == 0) { + if (argc < 5) + return cmd_usage(cmdtp); + ethname = argv[1]; + --argc; + ++argv; + ret = do_mvsw_reg_read(ethname, argc, argv); + } else if (strcmp(cmd, "write") == 0) { + if (argc < 6) + return cmd_usage(cmdtp); + ethname = argv[1]; + --argc; + ++argv; + ret = do_mvsw_reg_write(ethname, argc, argv); + } else + return cmd_usage(cmdtp); + + return ret; +} + +U_BOOT_CMD( + mvsw_reg, 7, 1, do_mvsw_reg, + "marvell 88e6352 switch register access", + "write ethname phyaddr port reg value\n" + "mvsw_reg read ethname phyaddr port reg\n" + ); diff --git a/include/mv88e6352.h b/include/mv88e6352.h new file mode 100644 index 0000000..cdc4db7 --- /dev/null +++ b/include/mv88e6352.h @@ -0,0 +1,92 @@ +/* + * (C) Copyright 2012 + * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __MV886352_H +#define __MV886352_H + +#include + +/* PHY registers */ +#define PHY(itf) (itf) + +#define PHY_CTRL 0x00 +#define PHY_100_MBPS 0x2000 +#define PHY_1_GBPS 0x0040 +#define AUTONEG_EN 0x1000 +#define AUTONEG_RST 0x0200 +#define FULL_DUPLEX 0x0100 +#define PHY_PWR_DOWN 0x0800 + +#define PHY_STATUS 0x01 +#define AN1000FIX 0x0001 + +#define PHY_SPEC_CTRL 0x10 +#define SPEC_PWR_DOWN 0x0004 +#define AUTO_MDIX_EN 0x0060 + +#define PHY_1000_CTRL 0x9 + +#define NO_ADV 0x0000 +#define ADV_1000_FDPX 0x0200 +#define ADV_1000_HDPX 0x0100 + +#define PHY_PAGE 0x16 + +#define AN1000FIX_PAGE 0x00fc + +/* PORT or MAC registers */ +#define PORT(itf) (itf+0x10) + +#define PORT_STATUS 0x00 +#define NO_PHY_DETECT 0x0000 + +#define PORT_PHY 0x01 +#define RX_RGMII_TIM 0x8000 +#define TX_RGMII_TIM 0x4000 +#define FLOW_CTRL_EN 0x0080 +#define FLOW_CTRL_FOR 0x0040 +#define LINK_VAL 0x0020 +#define LINK_FOR 0x0010 +#define FULL_DPX 0x0008 +#define FULL_DPX_FOR 0x0004 +#define NO_SPEED_FOR 0x0003 +#define SPEED_1000_FOR 0x0002 +#define SPEED_100_FOR 0x0001 +#define SPEED_10_FOR 0x0000 + +#define PORT_CTRL 0x04 +#define FORWARDING 0x0003 +#define EGRS_FLD_ALL 0x000c +#define PORT_DIS 0x0000 + +struct mv88e_sw_reg { + u8 port; + u8 reg; + u16 value; +}; + +int mv88e_sw_reset(const char *devname, u8 phy_addr); +int mv88e_sw_program(const char *devname, u8 phy_addr, + struct mv88e_sw_reg *regs, int regs_nb); + +#endif -- cgit v1.1 From f91ba0ecbc8232691856d2d7524fd53067ca91c9 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Fri, 17 Aug 2012 08:28:56 +0000 Subject: net: Add Vitesse VSC8662 PHY support -VSC8662 is Dual Port 10/100/1000Base-T Phy, 100Base-FX/1000/Base-X Gigabit Ethernt Transceiver Phy. -Its register set and features are similar to other Vitesse Phys Signed-off-by: Priyanka Jain Signed-off-by: York Sun --- drivers/net/phy/vitesse.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index d48d4fe..0a0f40d 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -1,6 +1,9 @@ /* * Vitesse PHY drivers * + * Copyright 2010-2012 Freescale Semiconductor, Inc. + * Author: Andy Fleming + * Add vsc8662 phy support - Priyanka Jain * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of @@ -15,10 +18,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA - * - * Copyright 2010-2011 Freescale Semiconductor, Inc. - * author Andy Fleming - * */ #include @@ -206,6 +205,16 @@ static struct phy_driver VSC8641_driver = { .shutdown = &genphy_shutdown, }; +static struct phy_driver VSC8662_driver = { + .name = "Vitesse VSC8662", + .uid = 0x70660, + .mask = 0xffff0, + .features = PHY_GBIT_FEATURES, + .config = &genphy_config_aneg, + .startup = &vitesse_startup, + .shutdown = &genphy_shutdown, +}; + /* Vitesse bought Cicada, so we'll put these here */ static struct phy_driver cis8201_driver = { .name = "CIS8201", @@ -235,6 +244,7 @@ int phy_vitesse_init(void) phy_register(&VSC8244_driver); phy_register(&VSC8211_driver); phy_register(&VSC8221_driver); + phy_register(&VSC8662_driver); phy_register(&cis8201_driver); phy_register(&cis8204_driver); -- cgit v1.1 From e2a66e609745470b1157fe6b6663c804ee44b0b9 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 26 Aug 2012 10:19:20 +0000 Subject: FEC: Do not pass unaligned buffer to network stack Do not pass unaligned RX buffer to the upper layers. The upper layer, especially in the ARP case, recycles the buffer and passes it back into the FEC, into it's TX path. With caches enabled, the FEC hangs on this from time to time. Signed-off-by: Marek Vasut Cc: Benoit Thebaudeau Cc: Eric Nelson Cc: Fabio Estevam Cc: Joe Hershberger Tested-by: Fabio Estevam --- drivers/net/fec_mxc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index fbfc842..7b6a997 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -31,6 +31,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -791,7 +792,7 @@ static int fec_recv(struct eth_device *dev) uint16_t bd_status; uint32_t addr, size; int i; - uchar buff[FEC_MAX_PKT_SIZE]; + uchar buff[FEC_MAX_PKT_SIZE] __aligned(ARCH_DMA_MINALIGN); /* * Check if any critical events have happened -- cgit v1.1 From efe24d2e17996f00b8803623c53cfe4baede9349 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 26 Aug 2012 10:19:21 +0000 Subject: FEC: Properly align address over the buffers for cache ops Align the address that's to be invalidated/flushed properly. Signed-off-by: Marek Vasut Cc: Benoit Thebaudeau Cc: Eric Nelson Cc: Fabio Estevam Cc: Joe Hershberger --- drivers/net/fec_mxc.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 7b6a997..bc44d38 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -695,7 +695,7 @@ static void fec_halt(struct eth_device *dev) static int fec_send(struct eth_device *dev, void *packet, int length) { unsigned int status; - uint32_t size; + uint32_t size, end; uint32_t addr; /* @@ -722,8 +722,9 @@ static int fec_send(struct eth_device *dev, void *packet, int length) #endif addr = (uint32_t)packet; - size = roundup(length, ARCH_DMA_MINALIGN); - flush_dcache_range(addr, addr + size); + end = roundup(addr + length, ARCH_DMA_MINALIGN); + addr &= ~(ARCH_DMA_MINALIGN - 1); + flush_dcache_range(addr, end); writew(length, &fec->tbd_base[fec->tbd_index].data_length); writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer); @@ -790,7 +791,7 @@ static int fec_recv(struct eth_device *dev) int frame_length, len = 0; struct nbuf *frame; uint16_t bd_status; - uint32_t addr, size; + uint32_t addr, size, end; int i; uchar buff[FEC_MAX_PKT_SIZE] __aligned(ARCH_DMA_MINALIGN); @@ -854,8 +855,9 @@ static int fec_recv(struct eth_device *dev) * Invalidate data cache over the buffer */ addr = (uint32_t)frame; - size = roundup(frame_length, ARCH_DMA_MINALIGN); - invalidate_dcache_range(addr, addr + size); + end = roundup(addr + frame_length, ARCH_DMA_MINALIGN); + addr &= ~(ARCH_DMA_MINALIGN - 1); + invalidate_dcache_range(addr, end); /* * Fill the buffer and pass it to upper layers -- cgit v1.1 From bc1ce150b95bc51390add7fb8b74c535d1b5673c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 29 Aug 2012 03:49:49 +0000 Subject: FEC: Remove endless loop in the FEC driver The FEC hardware sometimes errors out on data transfer and hangs in the tightloop adjusted by this patch. So add timeout into the tightloop to make such a hang recoverable. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Fabio Estevam Cc: Otavio Salvador Cc: Stefano Babic --- drivers/net/fec_mxc.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index bc44d38..6f071e9 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -35,6 +35,12 @@ DECLARE_GLOBAL_DATA_PTR; +/* + * Timeout the transfer after 5 mS. This is usually a bit more, since + * the code in the tightloops this timeout is used in adds some overhead. + */ +#define FEC_XFER_TIMEOUT 5000 + #ifndef CONFIG_MII #error "CONFIG_MII has to be defined!" #endif @@ -697,6 +703,8 @@ static int fec_send(struct eth_device *dev, void *packet, int length) unsigned int status; uint32_t size, end; uint32_t addr; + int timeout = FEC_XFER_TIMEOUT; + int ret = 0; /* * This routine transmits one frame. This routine only accepts @@ -764,6 +772,10 @@ static int fec_send(struct eth_device *dev, void *packet, int length) while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) { udelay(1); invalidate_dcache_range(addr, addr + size); + if (!timeout--) { + ret = -EINVAL; + break; + } } debug("fec_send: status 0x%x index %d\n", @@ -775,7 +787,7 @@ static int fec_send(struct eth_device *dev, void *packet, int length) else fec->tbd_index = 1; - return 0; + return ret; } /** -- cgit v1.1 From 67449098a86be18cbdb27345bebe8da57e5d8899 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 29 Aug 2012 03:49:50 +0000 Subject: FEC: Rework the TX wait mechanism The mechanism waiting for transmission to finish in fec_send() now relies on the E-bit being cleared in the TX buffer descriptor. In case of data cache being on, this means invalidation of data cache above this TX buffer descriptor on each test for the E-bit being cleared. Apparently, there is another way to check if the transmission did complete. This is by checking the TDAR bit in the X_DES_ACTIVE register. Reading a register does not need any data cache invalidation, which is beneficial. Rework the sequence that wait for completion of the transmission so that the TDAR bit is tested first and afterwards check the E-bit being clear. This cuts down the number of cache invalidation calls to one. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Fabio Estevam Cc: Otavio Salvador Cc: Stefano Babic --- drivers/net/fec_mxc.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 6f071e9..6ede464 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -768,19 +768,21 @@ static int fec_send(struct eth_device *dev, void *packet, int length) * invalidate data cache to see what's really in RAM. Also, we need * barrier here. */ - invalidate_dcache_range(addr, addr + size); - while (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) { - udelay(1); - invalidate_dcache_range(addr, addr + size); - if (!timeout--) { - ret = -EINVAL; + while (--timeout) { + if (!(readl(&fec->eth->x_des_active) & (1 << 24))) break; - } } - debug("fec_send: status 0x%x index %d\n", + if (!timeout) + ret = -EINVAL; + + invalidate_dcache_range(addr, addr + size); + if (readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_READY) + ret = -EINVAL; + + debug("fec_send: status 0x%x index %d ret %i\n", readw(&fec->tbd_base[fec->tbd_index].status), - fec->tbd_index); + fec->tbd_index, ret); /* for next transmission use the other buffer */ if (fec->tbd_index) fec->tbd_index = 0; -- cgit v1.1 From c0b5a3bbb0cd40a6b23b7b07e2182a5bcdc8c31c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 29 Aug 2012 03:49:51 +0000 Subject: FEC: Replace magic contants Replace the magic contant 1 << 24 with properly defined bits. Signed-off-by: Marek Vasut Cc: Joe Hershberger Cc: Fabio Estevam Cc: Otavio Salvador Cc: Stefano Babic --- drivers/net/fec_mxc.c | 6 +++--- drivers/net/fec_mxc.h | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 6ede464..3e232c7 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -256,7 +256,7 @@ static int miiphy_wait_aneg(struct eth_device *dev) static int fec_rx_task_enable(struct fec_priv *fec) { - writel(1 << 24, &fec->eth->r_des_active); + writel(FEC_R_DES_ACTIVE_RDAR, &fec->eth->r_des_active); return 0; } @@ -267,7 +267,7 @@ static int fec_rx_task_disable(struct fec_priv *fec) static int fec_tx_task_enable(struct fec_priv *fec) { - writel(1 << 24, &fec->eth->x_des_active); + writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->x_des_active); return 0; } @@ -769,7 +769,7 @@ static int fec_send(struct eth_device *dev, void *packet, int length) * barrier here. */ while (--timeout) { - if (!(readl(&fec->eth->x_des_active) & (1 << 24))) + if (!(readl(&fec->eth->x_des_active) & FEC_X_DES_ACTIVE_TDAR)) break; } diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index 852b2e0..203285a 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -213,6 +213,9 @@ struct ethernet_regs { #define FEC_X_WMRK_STRFWD 0x00000100 +#define FEC_X_DES_ACTIVE_TDAR 0x01000000 +#define FEC_R_DES_ACTIVE_RDAR 0x01000000 + #if defined(CONFIG_MX25) || defined(CONFIG_MX53) /* defines for MIIGSK */ /* RMII frequency control: 0=50MHz, 1=5MHz */ -- cgit v1.1 From a655938a93410a468f8e2288edc20d20a272a6d4 Mon Sep 17 00:00:00 2001 From: Chander Kashyap Date: Thu, 6 Sep 2012 19:36:31 +0000 Subject: PXE: FDT: Add support for fdt in PXE Now DT support is becoming common for all new SoC's. Hence it is better to have option for getting specific FDT from the remote server. This patch adds support for new label i.e. 'fdt'. This will allow to retrieve 'fdt blob' from the remote server. This patch take care for the following scenarios. The usage of fdt is optional. The 'fdt blob' can be retrieved from tftp or can be available locally or can be absent. If 'fdt_addr_r' environment variable is set and 'fdt' label is defined retrieve 'fdt blob' from tftp. 'fdt_addr_r' is then passed along bootm command. If 'fdt_addr' is set and 'fdt blob' is not retrieved from the tftp pass 'fdt_addr' to bootm command. In this case 'fdt blob' will be available at 'fdt_addr'. If 'fdt_addr' is not set and 'fdt blob' is not retrieve from tftp pass NULL to boot command. In this case 'fdt blob' is not required and absent. Signed-off-by: Chander Kashyap Acked-by: Jason Hobbs --- common/cmd_pxe.c | 39 ++++++++++++++++++++++++++++++++++++--- doc/README.pxe | 14 ++++++++++++-- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c index 6b31dea..ee75db9 100644 --- a/common/cmd_pxe.c +++ b/common/cmd_pxe.c @@ -450,6 +450,7 @@ struct pxe_label { char *kernel; char *append; char *initrd; + char *fdt; int attempted; int localboot; struct list_head list; @@ -517,6 +518,9 @@ static void label_destroy(struct pxe_label *label) if (label->initrd) free(label->initrd); + if (label->fdt) + free(label->fdt); + free(label); } @@ -541,6 +545,9 @@ static void label_print(void *data) if (label->initrd) printf("\t\tinitrd: %s\n", label->initrd); + + if (label->fdt) + printf("\tfdt: %s\n", label->fdt); } /* @@ -628,10 +635,29 @@ static void label_boot(struct pxe_label *label) bootm_argv[1] = getenv("kernel_addr_r"); /* - * fdt usage is optional. If there is an fdt_addr specified, we will - * pass it along to bootm, and adjust argc appropriately. + * fdt usage is optional: + * It handles the following scenarios. All scenarios are exclusive + * + * Scenario 1: If fdt_addr_r specified and "fdt" label is defined in + * pxe file, retrieve fdt blob from server. Pass fdt_addr_r to bootm, + * and adjust argc appropriately. + * + * Scenario 2: If there is an fdt_addr specified, pass it along to + * bootm, and adjust argc appropriately. + * + * Scenario 3: fdt blob is not available. */ - bootm_argv[3] = getenv("fdt_addr"); + bootm_argv[3] = getenv("fdt_addr_r"); + + /* if fdt label is defined then get fdt from server */ + if (bootm_argv[3] && label->fdt) { + if (get_relfile_envaddr(label->fdt, "fdt_addr_r") < 0) { + printf("Skipping %s for failure retrieving fdt\n", + label->name); + return; + } + } else + bootm_argv[3] = getenv("fdt_addr"); if (bootm_argv[3]) bootm_argc = 4; @@ -658,6 +684,7 @@ enum token_type { T_DEFAULT, T_PROMPT, T_INCLUDE, + T_FDT, T_INVALID }; @@ -685,6 +712,7 @@ static const struct token keywords[] = { {"append", T_APPEND}, {"initrd", T_INITRD}, {"include", T_INCLUDE}, + {"fdt", T_FDT}, {NULL, T_INVALID} }; @@ -1074,6 +1102,11 @@ static int parse_label(char **c, struct pxe_menu *cfg) err = parse_sliteral(c, &label->initrd); break; + case T_FDT: + if (!label->fdt) + err = parse_sliteral(c, &label->fdt); + break; + case T_LOCALBOOT: err = parse_integer(c, &label->localboot); break; diff --git a/doc/README.pxe b/doc/README.pxe index 2bbf53d..f00f280 100644 --- a/doc/README.pxe +++ b/doc/README.pxe @@ -93,8 +93,13 @@ pxe boot be passed to the bootm command to boot the kernel. These environment variables are required to be set. - fdt_addr - the location of a fdt blob. If this is set, it will be passed - to bootm when booting a kernel. + fdt_addr_r - location in RAM at which 'pxe boot' will store the fdt blob it + retrieves from tftp. The retrieval is possible if 'fdt' label is defined in + pxe file and 'fdt_addr_r' is set. If retrieval is possible, 'fdt_addr_r' + will be passed to bootm command to boot the kernel. + + fdt_addr - the location of a fdt blob. 'fdt_addr' will be passed to bootm + command if it is set and 'fdt_addr_r' is not passed to bootm command. pxe file format =============== @@ -156,6 +161,11 @@ initrd - if this label is chosen, use tftp to retrieve the initrd the initrd_addr_r environment variable, and that address will be passed to bootm. +fdt - if this label is chosen, use tftp to retrieve the fdt blob + at . it will be stored at the address indicated in + the fdt_addr_r environment variable, and that address will + be passed to bootm. + localboot - Run the command defined by "localcmd" in the environment. is ignored and is only here to match the syntax of PXELINUX config files. -- cgit v1.1 From ee0f60df0b71092cd632fc6651f4157a2d252598 Mon Sep 17 00:00:00 2001 From: Brian Rzycki Date: Tue, 11 Sep 2012 09:22:53 +0000 Subject: net: Quietly ignore DHCP Option 28 (Broadcast Address) Some DHCP servers (notably dnsmasq) always transmit DHCP Option 28, Broadcast Address as specified in RFC 2132. Without this patch u-boot displays the warning: *** Unhandled DHCP Option in OFFER/ACK: 28 The patch suppresses the warning and ignores DHCP Option 28. There is no environment variable to set the broadcast address into and if for some reason u-boot needs the broadcast it can be calculated from ipaddr and netmask. Signed-off-by: Brian Rzycki --- net/bootp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/bootp.c b/net/bootp.c index c9b8349..661e371 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -728,6 +728,8 @@ static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp) memcpy(&NetOurRootPath, popt + 2, size); NetOurRootPath[size] = 0; break; + case 28: /* Ignore Broadcast Address Option */ + break; #if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER) case 42: /* NTP server IP */ NetCopyIP(&NetNtpServerIP, (popt + 2)); -- cgit v1.1 From 3f7f2414efecc4e738961767a411bd0143835377 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 14 Aug 2012 12:27:13 -0700 Subject: ARM: SPL: Convert davinci to CONFIG_SPL_FRAMEWORK - Convert the non-relocation part of board_init_f to spl_board_init, turn on CONFIG_SPL_BOARD_INIT in the configs. - Remove duplicated code. - Add spl_boot_device() that returns the statically chosen boot device. Signed-off-by: Tom Rini --- Makefile | 4 +- arch/arm/cpu/arm926ejs/davinci/Makefile | 2 +- arch/arm/cpu/arm926ejs/davinci/config.mk | 16 +++++++ arch/arm/cpu/arm926ejs/davinci/spl.c | 72 ++++++++++++++------------------ arch/arm/cpu/arm926ejs/start.S | 2 + arch/arm/include/asm/arch-davinci/spl.h | 32 ++++++++++++++ drivers/mmc/Makefile | 3 -- drivers/mmc/spl_mmc_load.c | 62 --------------------------- include/configs/cam_enc_4xx.h | 3 +- include/configs/da850evm.h | 15 +++++-- include/configs/hawkboard.h | 3 +- 11 files changed, 101 insertions(+), 113 deletions(-) create mode 100644 arch/arm/cpu/arm926ejs/davinci/config.mk create mode 100644 arch/arm/include/asm/arch-davinci/spl.h delete mode 100644 drivers/mmc/spl_mmc_load.c diff --git a/Makefile b/Makefile index e193be0..956eaaa 100644 --- a/Makefile +++ b/Makefile @@ -457,7 +457,7 @@ $(obj)u-boot.ubl: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin rm $(obj)u-boot-ubl.bin rm $(obj)spl/u-boot-spl-pad.bin -$(obj)u-boot.ais: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin +$(obj)u-boot.ais: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img $(obj)tools/mkimage -s -n $(if $(CONFIG_AIS_CONFIG_FILE),$(CONFIG_AIS_CONFIG_FILE),"/dev/null") \ -T aisimage \ -e $(CONFIG_SPL_TEXT_BASE) \ @@ -466,7 +466,7 @@ $(obj)u-boot.ais: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin $(OBJCOPY) ${OBJCFLAGS} -I binary \ --pad-to=$(CONFIG_SPL_MAX_SIZE) -O binary \ $(obj)spl/u-boot-spl.ais $(obj)spl/u-boot-spl-pad.ais - cat $(obj)spl/u-boot-spl-pad.ais $(obj)u-boot.bin > \ + cat $(obj)spl/u-boot-spl-pad.ais $(obj)u-boot.img > \ $(obj)u-boot.ais # Specify the target for use in elftosb call diff --git a/arch/arm/cpu/arm926ejs/davinci/Makefile b/arch/arm/cpu/arm926ejs/davinci/Makefile index c91928e..dec7bfb 100644 --- a/arch/arm/cpu/arm926ejs/davinci/Makefile +++ b/arch/arm/cpu/arm926ejs/davinci/Makefile @@ -37,7 +37,7 @@ COBJS-$(CONFIG_SOC_DA850) += da850_pinmux.o COBJS-$(CONFIG_DRIVER_TI_EMAC) += lxt972.o dp83848.o et1011c.o ksz8873.o ifdef CONFIG_SPL_BUILD -COBJS-y += spl.o +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o COBJS-$(CONFIG_SOC_DM365) += dm365_lowlevel.o COBJS-$(CONFIG_SOC_DA8XX) += da850_lowlevel.o endif diff --git a/arch/arm/cpu/arm926ejs/davinci/config.mk b/arch/arm/cpu/arm926ejs/davinci/config.mk new file mode 100644 index 0000000..7452315 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/davinci/config.mk @@ -0,0 +1,16 @@ +# +# Copyright (C) 2012, Texas Instruments, Incorporated - http://www.ti.com/ +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed "as is" WITHOUT ANY WARRANTY of any +# kind, whether express or implied; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +ifndef CONFIG_SPL_BUILD +ALL-$(CONFIG_SPL_FRAMEWORK) += $(obj)u-boot.ais +endif diff --git a/arch/arm/cpu/arm926ejs/davinci/spl.c b/arch/arm/cpu/arm926ejs/davinci/spl.c index 03c85c8..714fa92 100644 --- a/arch/arm/cpu/arm926ejs/davinci/spl.c +++ b/arch/arm/cpu/arm926ejs/davinci/spl.c @@ -21,6 +21,8 @@ * MA 02111-1307 USA */ #include +#include +#include #include #include #include @@ -30,15 +32,9 @@ #include #include -#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT - DECLARE_GLOBAL_DATA_PTR; -/* Define global data structure pointer to it*/ -static gd_t gdata __attribute__ ((section(".data"))); -static bd_t bdata __attribute__ ((section(".data"))); - -#else +#ifndef CONFIG_SPL_LIBCOMMON_SUPPORT void puts(const char *str) { while (*str) @@ -52,53 +48,49 @@ void putc(char c) NS16550_putc((NS16550_t)(CONFIG_SYS_NS16550_COM1), c); } - #endif /* CONFIG_SPL_LIBCOMMON_SUPPORT */ -inline void hang(void) -{ - puts("### ERROR ### Please RESET the board ###\n"); - for (;;) - ; -} - void board_init_f(ulong dummy) { + /* First, setup our stack pointer. */ + asm volatile("mov sp, %0\n" : : "r"(CONFIG_SPL_STACK)); + + /* Second, perform our low-level init. */ #ifdef CONFIG_SOC_DM365 dm36x_lowlevel_init(0); #endif #ifdef CONFIG_SOC_DA8XX arch_cpu_init(); #endif - relocate_code(CONFIG_SPL_STACK, NULL, CONFIG_SPL_TEXT_BASE); -} -void board_init_r(gd_t *id, ulong dummy) -{ -#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT - mem_malloc_init(CONFIG_SYS_TEXT_BASE - CONFIG_SYS_MALLOC_LEN, - CONFIG_SYS_MALLOC_LEN); + /* Third, we clear the BSS. */ + memset(__bss_start, 0, __bss_end__ - __bss_start); + /* Finally, setup gd and move to the next step. */ gd = &gdata; - gd->bd = &bdata; - gd->flags |= GD_FLG_RELOC; - gd->baudrate = CONFIG_BAUDRATE; - serial_init(); /* serial communications setup */ - gd->have_console = 1; + board_init_r(NULL, 0); +} -#endif +void spl_board_init(void) +{ + preloader_console_init(); +} -#ifdef CONFIG_SPL_NAND_LOAD - nand_init(); - puts("Nand boot...\n"); - nand_boot(); -#endif -#ifdef CONFIG_SPL_SPI_LOAD - puts("SPI boot...\n"); - spi_boot(); -#endif -#ifdef CONFIG_SPL_MMC_LOAD - puts("MMC boot...\n"); - spl_mmc_load(); +u32 spl_boot_mode(void) +{ + return MMCSD_MODE_RAW; +} + +u32 spl_boot_device(void) +{ +#ifdef CONFIG_SPL_NAND_SIMPLE + return BOOT_DEVICE_NAND; +#elif defined(CONFIG_SPL_SPI_LOAD) + return BOOT_DEVICE_SPI; +#elif defined(CONFIG_SPL_MMC_LOAD) + return BOOT_DEVICE_MMC1; +#else + puts("Unknown boot device\n"); + hang(); #endif } diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S index 6f05f1a..521d462 100644 --- a/arch/arm/cpu/arm926ejs/start.S +++ b/arch/arm/cpu/arm926ejs/start.S @@ -215,6 +215,7 @@ call_board_init_f: /*------------------------------------------------------------------------------*/ +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_NAND_SPL) /* * void relocate_code (addr_sp, gd, addr_moni) * @@ -344,6 +345,7 @@ _rel_dyn_end_ofs: .word __rel_dyn_end - _start _dynsym_start_ofs: .word __dynsym_start - _start +#endif /* ************************************************************************* diff --git a/arch/arm/include/asm/arch-davinci/spl.h b/arch/arm/include/asm/arch-davinci/spl.h new file mode 100644 index 0000000..fb01db0 --- /dev/null +++ b/arch/arm/include/asm/arch-davinci/spl.h @@ -0,0 +1,32 @@ +/* + * (C) Copyright 2012 + * Texas Instruments, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_NAND 1 +#define BOOT_DEVICE_SPI 2 +#define BOOT_DEVICE_MMC1 3 +#define BOOT_DEVICE_MMC2 4 /* dummy */ +#define BOOT_DEVICE_MMC2_2 5 /* dummy */ + +#endif diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 941a909..565ba6a 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -26,11 +26,8 @@ include $(TOPDIR)/config.mk LIB := $(obj)libmmc.o ifdef CONFIG_SPL_BUILD -COBJS-$(CONFIG_SPL_MMC_LOAD) += spl_mmc_load.o -ifdef CONFIG_SPL_FRAMEWORK COBJS-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o endif -endif COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o COBJS-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o diff --git a/drivers/mmc/spl_mmc_load.c b/drivers/mmc/spl_mmc_load.c deleted file mode 100644 index 79a68fb..0000000 --- a/drivers/mmc/spl_mmc_load.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -static void mmc_load_image(struct mmc *mmc) -{ - s32 err; - void (*uboot)(void) __noreturn; - - err = mmc->block_dev.block_read(0, CONFIG_SYS_MMC_U_BOOT_OFFS, - CONFIG_SYS_MMC_U_BOOT_SIZE/512, - (u32 *)CONFIG_SYS_TEXT_BASE); - - if (err <= 0) { - printf("spl: error reading image %s, err - %d\n", - "u-boot.img", err); - hang(); - } - uboot = (void *) CONFIG_SYS_TEXT_BASE; - (*uboot)(); -} - -void spl_mmc_load(void) -{ - struct mmc *mmc; - int err; - void (mmc_load_image)(struct mmc *mmc) __noreturn; - - mmc_initialize(gd->bd); - mmc = find_mmc_device(0); - if (!mmc) { - puts("spl: mmc device not found!!\n"); - hang(); - } else { - puts("spl: mmc device found\n"); - } - err = mmc_init(mmc); - if (err) { - printf("spl: mmc init failed: err - %d\n", err); - hang(); - } - mmc_load_image(mmc); -} diff --git a/include/configs/cam_enc_4xx.h b/include/configs/cam_enc_4xx.h index 91ab812..9b56e02 100644 --- a/include/configs/cam_enc_4xx.h +++ b/include/configs/cam_enc_4xx.h @@ -215,10 +215,11 @@ /* Defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_LIBGENERIC_SUPPORT #define CONFIG_SPL_NAND_SUPPORT #define CONFIG_SPL_NAND_SIMPLE -#define CONFIG_SPL_NAND_LOAD #define CONFIG_SYS_NAND_HW_ECC_OOBFIRST #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_POST_MEM_SUPPORT diff --git a/include/configs/da850evm.h b/include/configs/da850evm.h index 09a9660..ddd6155 100644 --- a/include/configs/da850evm.h +++ b/include/configs/da850evm.h @@ -380,6 +380,16 @@ #ifndef CONFIG_DIRECT_NOR_BOOT /* defines for SPL */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT +#define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SYS_TEXT_BASE - \ + CONFIG_SYS_MALLOC_LEN) +#define CONFIG_SYS_SPL_MALLOC_SIZE CONFIG_SYS_MALLOC_LEN +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SPL_SPI_BUS 0 +#define CONFIG_SPL_SPI_CS 0 #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_LIBCOMMON_SUPPORT #define CONFIG_SPL_LIBGENERIC_SUPPORT @@ -392,10 +402,9 @@ /* Load U-Boot Image From MMC */ #ifdef CONFIG_SPL_MMC_LOAD #define CONFIG_SPL_MMC_SUPPORT -#define CONFIG_SPL_FAT_SUPPORT #define CONFIG_SPL_LIBDISK_SUPPORT -#define CONFIG_SYS_MMC_U_BOOT_OFFS 0x75 -#define CONFIG_SYS_MMC_U_BOOT_SIZE 0x30000 +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x75 +#undef CONFIG_SPL_SPI_SUPPORT #undef CONFIG_SPL_SPI_LOAD #endif diff --git a/include/configs/hawkboard.h b/include/configs/hawkboard.h index 73ab4c8..9ea200a 100644 --- a/include/configs/hawkboard.h +++ b/include/configs/hawkboard.h @@ -60,9 +60,10 @@ /* Spl */ #define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT #define CONFIG_SPL_NAND_SUPPORT #define CONFIG_SPL_NAND_SIMPLE -#define CONFIG_SPL_NAND_LOAD #define CONFIG_SPL_LIBGENERIC_SUPPORT /* for udelay and __div64_32 for NAND */ #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_LDSCRIPT "board/$(BOARDDIR)/u-boot-spl-hawk.lds" -- cgit v1.1 From d79f3a6860e239d04d1c259bdbcad675649d0ecb Mon Sep 17 00:00:00 2001 From: Sughosh Ganu Date: Tue, 28 Aug 2012 00:53:37 +0530 Subject: hawkboard: Update config file to work with common spl framework The common spl framework expects the u-boot payload size through CONFIG_SYS_MONITOR_LEN. Define the macro with the u-boot's size. With this change, CONFIG_SYS_NAND_U_BOOT_SIZE is no longer required. Delete the same. Signed-off-by: Tom Rini Signed-off-by: Sughosh Ganu --- include/configs/hawkboard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/hawkboard.h b/include/configs/hawkboard.h index 9ea200a..c0e3ed3 100644 --- a/include/configs/hawkboard.h +++ b/include/configs/hawkboard.h @@ -80,6 +80,7 @@ #define CONFIG_MAX_RAM_BANK_SIZE (512 << 20) #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 -\ GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_MONITOR_LEN 0x60000 /* memtest start addr */ #define CONFIG_SYS_MEMTEST_START (PHYS_SDRAM_1) @@ -137,7 +138,6 @@ #define CONFIG_SYS_NAND_PAGE_SIZE (2 << 10) #define CONFIG_SYS_NAND_BLOCK_SIZE (128 << 10) #define CONFIG_SYS_NAND_U_BOOT_OFFS 0xe0000 -#define CONFIG_SYS_NAND_U_BOOT_SIZE 0x60000 #define CONFIG_SYS_NAND_U_BOOT_DST 0xc1180000 #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_NAND_U_BOOT_DST #define CONFIG_SYS_NAND_U_BOOT_RELOC_SP (CONFIG_SYS_NAND_U_BOOT_DST - \ -- cgit v1.1 From 95a372b83685f99b6c947a6e0da55a6c474ab870 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 20 Aug 2012 09:31:52 -0700 Subject: da850: Add README.da850 This file documents when to build for da850evm and when to build for da850_am18xxevm. It also documents how to write the u-boot.ais file to persistent storage (such as SPI), in some cases as well as how to write a recovery image. Signed-off-by: Tom Rini Acked-by: Christian Riesch Acked-by: Prabhakar Lad --- board/davinci/da8xxevm/README.da850 | 68 +++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 board/davinci/da8xxevm/README.da850 diff --git a/board/davinci/da8xxevm/README.da850 b/board/davinci/da8xxevm/README.da850 new file mode 100644 index 0000000..313a1ef --- /dev/null +++ b/board/davinci/da8xxevm/README.da850 @@ -0,0 +1,68 @@ +Summary +======= +The README is for the boot procedure used for various DA850 (or compatible +parts such as the AM1808) based boards. + +In the context of U-Boot, the board is booted in three stages. The initial +bootloader which executes upon reset is the ROM Boot Loader (RBL) and sits +in the internal ROM. The RBL initializes the internal memory and then +depending on the exact board and pin configurations will initialize another +controller (such as SPI or NAND) to continue the boot process by loading +the secondary program loader (SPL). The SPL will initialize the system +further (some clocks, SDRAM) and then load the full u-boot from a +predefined location in persistent storage to DDR and jumps to the u-boot +entry point. + +AIS is an image format defined by TI for the images that are to be loaded +to memory by the RBL. The image is divided into a series of sections and +the image's entry point is specified. Each section comes with meta data +like the target address the section is to be copied to and the size of the +section, which is used by the RBL to load the image. At the end of the +image the RBL jumps to the image entry point. The AIS format allows for +other things such as programming the clocks and SDRAM if the header is +programmed for it. We do not take advantage of this and instead use SPL as +it allows for additional flexibility (run-time detect of board revision, +loading the next image from a different media, etc). + + +Compilation +=========== +The exact build target you need will depend on the board you have. For +Logic PD boards, or other boards which store the ethernet MAC address at +the end of SPI flash, run 'make da850evm'. For boards which store the +ethernet MAC address in the i2c EEPROM located at 0x50, run +'make da850_am18xxevm'. Once this build completes you will have a +u-boot.ais file that needs to be written to the correct persistent +storage. + + +Flashing the images to SPI +========================== +The AIS image can be written to SPI flash using the following commands. +Assuming that the network is configured and enabled and the u-boot.ais file +is tftp'able. + +U-Boot > sf probe 0 +U-Boot > sf erase 0 +320000 +U-Boot > tftp u-boot.ais +U-Boot > sf write c0700000 0 $filesize + + +Recovery +======== + +In the case of a "bricked" board, you need to use the TI tools found +here[1] to write the u-boot.ais file. An example of recovering to the SPI +flash of an AM1808 would be: + +$ mono sfh_OMAP-L138.exe -targetType AM1808 -p /dev/ttyUSB0 \ + -flash_noubl /path/to/u-boot.ais + +For other target types and flash locations: + +$ mono sfh_OMAP-L138.exe -h + +Links +===== +[1] + http://processors.wiki.ti.com/index.php/Serial_Boot_and_Flash_Loading_Utility_for_OMAP-L138 -- cgit v1.1 From 33d346464adb8dc206d1f9adf73bdfe2ed959502 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 27 Aug 2012 12:50:59 +0200 Subject: SPL: Add NOR flash booting support SPL NOR flash booting support is quite simple. Only copying of the images is needed. On MPC5xxx we need to make sure to only use the standard memcpy() implementation and not the MPC5xxx specific one. As the MPC5xxx version has some complexity which is not needed for this SPL booting. Signed-off-by: Stefan Roese Signed-off-by: Tom Rini --- common/spl/Makefile | 1 + common/spl/spl.c | 5 +++++ common/spl/spl_nor.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/spl.h | 3 +++ 4 files changed, 71 insertions(+) create mode 100644 common/spl/spl_nor.c diff --git a/common/spl/Makefile b/common/spl/Makefile index b9c9fd8..7cf01ad 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -15,6 +15,7 @@ LIB = $(obj)libspl.o ifdef CONFIG_SPL_BUILD COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o +COBJS-$(CONFIG_SPL_NOR_SUPPORT) += spl_nor.o COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o COBJS-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o endif diff --git a/common/spl/spl.c b/common/spl/spl.c index 3b4fcba..3156401 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -142,6 +142,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2) spl_nand_load_image(); break; #endif +#ifdef CONFIG_SPL_NOR_SUPPORT + case BOOT_DEVICE_NOR: + spl_nor_load_image(); + break; +#endif #ifdef CONFIG_SPL_YMODEM_SUPPORT case BOOT_DEVICE_UART: spl_ymodem_load_image(); diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c new file mode 100644 index 0000000..976e865 --- /dev/null +++ b/common/spl/spl_nor.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2012 Stefan Roese + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +void spl_nor_load_image(void) +{ + /* + * Loading of the payload to SDRAM is done with skipping of + * the mkimage header in this SPL NOR driver + */ + spl_image.flags |= SPL_COPY_PAYLOAD_ONLY; + + if (spl_start_uboot()) { + /* + * Load real U-Boot from its location in NOR flash to its + * defined location in SDRAM + */ + spl_parse_image_header( + (const struct image_header *)CONFIG_SYS_UBOOT_BASE); + + memcpy((void *)spl_image.load_addr, + (void *)(CONFIG_SYS_UBOOT_BASE + + sizeof(struct image_header)), + spl_image.size); + } else { + /* + * Load Linux from its location in NOR flash to its defined + * location in SDRAM + */ + spl_parse_image_header( + (const struct image_header *)CONFIG_SYS_OS_BASE); + + memcpy((void *)spl_image.load_addr, + (void *)(CONFIG_SYS_OS_BASE + + sizeof(struct image_header)), + spl_image.size); + + /* + * Copy DT blob (fdt) to SDRAM. Passing pointer to flash + * doesn't work (16 KiB should be enough for DT) + */ + memcpy((void *)CONFIG_SYS_SPL_ARGS_ADDR, + (void *)(CONFIG_SYS_FDT_BASE), + (16 << 10)); + } +} diff --git a/include/spl.h b/include/spl.h index 2923cd2..e405386 100644 --- a/include/spl.h +++ b/include/spl.h @@ -56,6 +56,9 @@ void spl_display_print(void); /* NAND SPL functions */ void spl_nand_load_image(void); +/* NOR SPL functions */ +void spl_nor_load_image(void); + /* MMC SPL functions */ void spl_mmc_load_image(void); -- cgit v1.1 From 022b4975c8dd304fa9f949594784f78601ae07c2 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 27 Aug 2012 12:50:58 +0200 Subject: SPL: Add option to skip copying of the mkimage header On some system (e.g. powerpc), the load-address and entry-point is located at address 0. So the current approach to load the image (payload) including the header to the address "load-address - 64" can't work here. This patch adds an flag to skip this copying including header to the SPL framework. By setting SPL_COPY_PAYLOAD_ONLY, only the playload will be copied. This will be used by the SPL NOR flash driver on powerpc. Signed-off-by: Stefan Roese Signed-off-by: Tom Rini --- common/spl/spl.c | 21 +++++++++++++++++---- include/spl.h | 3 +++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/common/spl/spl.c b/common/spl/spl.c index 3156401..95dd9d5 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -76,10 +76,23 @@ void spl_parse_image_header(const struct image_header *header) u32 header_size = sizeof(struct image_header); if (image_get_magic(header) == IH_MAGIC) { - spl_image.size = image_get_data_size(header) + header_size; - spl_image.entry_point = image_get_load(header); - /* Load including the header */ - spl_image.load_addr = spl_image.entry_point - header_size; + if (spl_image.flags & SPL_COPY_PAYLOAD_ONLY) { + /* + * On some system (e.g. powerpc), the load-address and + * entry-point is located at address 0. We can't load + * to 0-0x40. So skip header in this case. + */ + spl_image.load_addr = image_get_load(header); + spl_image.entry_point = image_get_ep(header); + spl_image.size = image_get_data_size(header); + } else { + spl_image.entry_point = image_get_load(header); + /* Load including the header */ + spl_image.load_addr = spl_image.entry_point - + header_size; + spl_image.size = image_get_data_size(header) + + header_size; + } spl_image.os = image_get_os(header); spl_image.name = image_get_name(header); debug("spl: payload image: %s load addr: 0x%x size: %d\n", diff --git a/include/spl.h b/include/spl.h index e405386..cf441a1 100644 --- a/include/spl.h +++ b/include/spl.h @@ -38,8 +38,11 @@ struct spl_image_info { u32 load_addr; u32 entry_point; u32 size; + u32 flags; }; +#define SPL_COPY_PAYLOAD_ONLY 1 + extern struct spl_image_info spl_image; extern u32 *boot_params_ptr; -- cgit v1.1 From a4cc1c487757fe71ee13adead888c8010191c961 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 14 Aug 2012 14:34:10 -0700 Subject: SPL: SPI: Enhance spi_spl_load to match the other load functions Signed-off-by: Tom Rini --- common/spl/spl.c | 4 ++-- drivers/mtd/spi/spi_spl_load.c | 23 ++++++++++++----------- include/spl.h | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/common/spl/spl.c b/common/spl/spl.c index 95dd9d5..40de454 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -167,8 +167,8 @@ void board_init_r(gd_t *dummy1, ulong dummy2) #endif #ifdef CONFIG_SPL_SPI_SUPPORT case BOOT_DEVICE_SPI: - spi_boot(); - break; + spl_spi_load_image(); + break; #endif default: puts("SPL: Un-supported Boot Device\n"); diff --git a/drivers/mtd/spi/spi_spl_load.c b/drivers/mtd/spi/spi_spl_load.c index 1aa30ac..d4f81f2 100644 --- a/drivers/mtd/spi/spi_spl_load.c +++ b/drivers/mtd/spi/spi_spl_load.c @@ -24,16 +24,17 @@ #include #include +#include /* * The main entry for SPI booting. It's necessary that SDRAM is already * configured and available since this code loads the main U-Boot image * from SPI into SDRAM and starts it from there. */ -void spi_boot(void) +void spl_spi_load_image(void) { struct spi_flash *flash; - void (*uboot)(void) __noreturn; + struct image_header *header; /* * Load U-Boot image from SPI flash into RAM @@ -42,17 +43,17 @@ void spi_boot(void) flash = spi_flash_probe(CONFIG_SPL_SPI_BUS, CONFIG_SPL_SPI_CS, CONFIG_SF_DEFAULT_SPEED, SPI_MODE_3); if (!flash) { - puts("failed.\n"); + puts("SPI probe failed.\n"); hang(); } - spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, - CONFIG_SYS_SPI_U_BOOT_SIZE, - (void *) CONFIG_SYS_TEXT_BASE); + /* use CONFIG_SYS_TEXT_BASE as temporary storage area */ + header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); - /* - * Jump to U-Boot image - */ - uboot = (void *) CONFIG_SYS_TEXT_BASE; - (*uboot)(); + /* Load u-boot, mkimage header is 64 bytes. */ + spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40, + (void *) header); + spl_parse_image_header(header); + spi_flash_read(flash, CONFIG_SYS_SPI_U_BOOT_OFFS, + spl_image.size, (void *)spl_image.load_addr); } diff --git a/include/spl.h b/include/spl.h index cf441a1..af94a82 100644 --- a/include/spl.h +++ b/include/spl.h @@ -69,7 +69,7 @@ void spl_mmc_load_image(void); void spl_ymodem_load_image(void); /* SPI SPL functions */ -void spi_boot(void); +void spl_spi_load_image(void); #ifdef CONFIG_SPL_BOARD_INIT void spl_board_init(void); -- cgit v1.1 From 3c6f8a0d19c0c8e2cee3dae933dbc5a75e29906d Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Tue, 28 Aug 2012 10:50:59 +0200 Subject: SPL: Enable use of custom defined U-Boot entry point By setting CONFIG_SYS_UBOOT_START boards can now use a different entry point for their U-Boot image. So the U-Boot entry point is not fixed to CONFIG_SYS_TEXT_BASE any more. Signed-off-by: Stefan Roese Signed-off-by: Tom Rini --- common/spl/spl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/spl/spl.c b/common/spl/spl.c index 40de454..14f7bdb 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -35,6 +35,9 @@ DECLARE_GLOBAL_DATA_PTR; +#ifndef CONFIG_SYS_UBOOT_START +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE +#endif #ifndef CONFIG_SYS_MONITOR_LEN #define CONFIG_SYS_MONITOR_LEN (200 * 1024) #endif @@ -104,7 +107,7 @@ void spl_parse_image_header(const struct image_header *header) header->ih_magic); /* Let's assume U-Boot will not be more than 200 KB */ spl_image.size = CONFIG_SYS_MONITOR_LEN; - spl_image.entry_point = CONFIG_SYS_TEXT_BASE; + spl_image.entry_point = CONFIG_SYS_UBOOT_START; spl_image.load_addr = CONFIG_SYS_TEXT_BASE; spl_image.os = IH_OS_U_BOOT; spl_image.name = "U-Boot"; -- cgit v1.1 From 1292eaf3530257e24c77979295892718662eda4b Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 27 Aug 2012 14:57:26 -0700 Subject: SPL: Make un-supported boot device puts a debug instead Signed-off-by: Tom Rini --- common/spl/spl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/common/spl/spl.c b/common/spl/spl.c index 14f7bdb..3aa0703 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -174,10 +174,8 @@ void board_init_r(gd_t *dummy1, ulong dummy2) break; #endif default: - puts("SPL: Un-supported Boot Device\n"); - debug("Found: %d\n", boot_device); + debug("SPL: Un-supported Boot Device\n"); hang(); - break; } switch (spl_image.os) { -- cgit v1.1 From 4212098181ac91e14374c1207b1e98595f1cc717 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Mon, 27 Aug 2012 14:58:28 -0700 Subject: SPL: Rework how we inform about un-headered images First, remove the puts from the case where we don't have an mkimage header as this is somewhat common and intentional for no-arg target images. Second, rework the final switch statement in board_init_r to, in the case of !CONFIG_SPL_OS_BOOT be only about doing debug prints about if we know what the magic is or not (the CONFIG_SPL_OS_BOOT case is unchanged). Then we call jump_to_image_no_args(). This gives us the same behavior as before but with slightly smaller code. Signed-off-by: Tom Rini --- common/spl/spl.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/common/spl/spl.c b/common/spl/spl.c index 3aa0703..f2f6de7 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -102,7 +102,6 @@ void spl_parse_image_header(const struct image_header *header) spl_image.name, spl_image.load_addr, spl_image.size); } else { /* Signature not found - assume u-boot.bin */ - puts("mkimage signature not found, assuming u-boot.bin ..\n"); debug("mkimage signature not found - ih_magic = %x\n", header->ih_magic); /* Let's assume U-Boot will not be more than 200 KB */ @@ -181,19 +180,17 @@ void board_init_r(gd_t *dummy1, ulong dummy2) switch (spl_image.os) { case IH_OS_U_BOOT: debug("Jumping to U-Boot\n"); - jump_to_image_no_args(); break; #ifdef CONFIG_SPL_OS_BOOT case IH_OS_LINUX: debug("Jumping to Linux\n"); spl_board_prepare_for_linux(); jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); - break; #endif default: - puts("Unsupported OS image.. Jumping nevertheless..\n"); - jump_to_image_no_args(); + debug("Unsupported OS image.. Jumping nevertheless..\n"); } + jump_to_image_no_args(); } /* -- cgit v1.1 From c57b953da923c6402afc1c890c21fdc7d5a2cc4a Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 30 Aug 2012 22:42:11 +0200 Subject: SPL: Add support for loading image from ram in SPL. Signed-off-by: Pavel Machek Signed-off-by: Tom Rini --- README | 3 +++ common/spl/spl.c | 22 ++++++++++++++++++++++ doc/README.SPL | 1 + 3 files changed, 26 insertions(+) diff --git a/README b/README index c5e6a1a..a745d0b 100644 --- a/README +++ b/README @@ -2669,6 +2669,9 @@ FIT uImage format: CONFIG_SPL_SPI_SUPPORT Support for drivers/spi/libspi.o in SPL binary + CONFIG_SPL_RAM_DEVICE + Support for running image already present in ram, in SPL binary + CONFIG_SPL_LIBGENERIC_SUPPORT Support for lib/libgeneric.o in SPL binary diff --git a/common/spl/spl.c b/common/spl/spl.c index f2f6de7..c640f87 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -128,6 +128,23 @@ static void __noreturn jump_to_image_no_args(void) image_entry((u32 *)boot_params_ptr_addr); } +#ifdef CONFIG_SPL_RAM_DEVICE +static void spl_ram_load_image(void) +{ + const struct image_header *header; + + /* + * Get the header. It will point to an address defined by handoff + * which will tell where the image located inside the flash. For + * now, it will temporary fixed to address pointed by U-Boot. + */ + header = (struct image_header *) + (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); + + spl_parse_image_header(header); +} +#endif + void board_init_r(gd_t *dummy1, ulong dummy2) { u32 boot_device; @@ -145,6 +162,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2) boot_device = spl_boot_device(); debug("boot device - %d\n", boot_device); switch (boot_device) { +#ifdef CONFIG_SPL_RAM_DEVICE + case BOOT_DEVICE_RAM: + spl_ram_load_image(); + break; +#endif #ifdef CONFIG_SPL_MMC_SUPPORT case BOOT_DEVICE_MMC1: case BOOT_DEVICE_MMC2: diff --git a/doc/README.SPL b/doc/README.SPL index 5368586..4e1cb28 100644 --- a/doc/README.SPL +++ b/doc/README.SPL @@ -66,6 +66,7 @@ CONFIG_SPL_DMA_SUPPORT (drivers/dma/libdma.o) CONFIG_SPL_POST_MEM_SUPPORT (post/drivers/memory.o) CONFIG_SPL_NAND_LOAD (drivers/mtd/nand/nand_spl_load.o) CONFIG_SPL_SPI_LOAD (drivers/mtd/spi/spi_spl_load.o) +CONFIG_SPL_RAM_DEVICE (common/spl/spl.c) Normally CPU is assumed to be the same between the SPL and normal -- cgit v1.1 From a10973e7fac1e0338c9c0bb79ae114d869b6200f Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 28 Sep 2012 05:34:09 +0000 Subject: disk: allow - or empty string to fall back to $bootdevice Commit 10a37fd "disk: get_device_and_partition() "auto" partition" prevented the use of "-" on the command-line to request fallback to the $bootdevice environment variable instead. This patch allows that, or an empty string "" to be used. Tested: setenv bootfile /boot/zImage setenv bootdevice 0:1 ext2load mmc 0:1 ext2load mmc - ext2load mmc "" Signed-off-by: Stephen Warren --- disk/part.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/disk/part.c b/disk/part.c index 64d76e8..3022969 100644 --- a/disk/part.c +++ b/disk/part.c @@ -489,7 +489,8 @@ int get_device_and_partition(const char *ifname, const char *dev_part_str, disk_partition_t tmpinfo; /* If no dev_part_str, use bootdevice environment variable */ - if (!dev_part_str) + if (!dev_part_str || !strlen(dev_part_str) || + !strcmp(dev_part_str, "-")) dev_part_str = getenv("bootdevice"); /* If still no dev_part_str, it's an error */ -- cgit v1.1 From b726a01b76ed06a0aec3a24879f8efce2d7f7005 Mon Sep 17 00:00:00 2001 From: Pavel Herrmann Date: Thu, 27 Sep 2012 23:18:03 +0000 Subject: remove unnecessary code in ata_piix We set sata_curr_device to 0 right after returning from init_sata(), so there's no point in setting it to the last scanned driver at this point. Note: there are more duplicities with cmd_sata, but those might be required, as the code seems to reset the entire controller on every scan, ignoring the requested port number. Signed-off-by: Pavel Herrmann --- drivers/block/ata_piix.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/block/ata_piix.c b/drivers/block/ata_piix.c index c81d11a..1c3ab8a 100644 --- a/drivers/block/ata_piix.c +++ b/drivers/block/ata_piix.c @@ -204,9 +204,6 @@ init_sata (int dev) dev_print (&sata_dev_desc[devno]); /* initialize partition type */ init_part (&sata_dev_desc[devno]); - if (sata_curr_device < 0) - sata_curr_device = - i * CONFIG_SYS_SATA_DEVS_PER_BUS + j; } } } -- cgit v1.1 From 8a5f34effa2a2dd6ed1b57894e9b395094066504 Mon Sep 17 00:00:00 2001 From: Lei Wen Date: Fri, 28 Sep 2012 04:26:42 +0000 Subject: lib: zlib: import deflate source file from 1.2.5 Signed-off-by: Lei Wen --- lib/zlib/deflate.c | 1834 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/zlib/deflate.h | 342 ++++++++++ 2 files changed, 2176 insertions(+) create mode 100644 lib/zlib/deflate.c create mode 100644 lib/zlib/deflate.h diff --git a/lib/zlib/deflate.c b/lib/zlib/deflate.c new file mode 100644 index 0000000..5c4022f --- /dev/null +++ b/lib/zlib/deflate.c @@ -0,0 +1,1834 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local block_state deflate_rle OF((deflate_state *s, int flush)); +local block_state deflate_huff OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > s->w_size) { + length = s->w_size; + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_BLOCK); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong complen, wraplen; + Bytef *str; + + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (strm == Z_NULL || strm->state == Z_NULL) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } + + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; + + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_BLOCK || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != Z_NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + (s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush)); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0L; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ + +#else /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for FASTEST only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#endif /* FASTEST */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s->match_length = longest_match (s, hash_head); + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, s->match_length); + + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +local block_state deflate_huff(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + fill_window(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff --git a/lib/zlib/deflate.h b/lib/zlib/deflate.h new file mode 100644 index 0000000..cbf0d1e --- /dev/null +++ b/lib/zlib/deflate.h @@ -0,0 +1,342 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2010 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ -- cgit v1.1 From e9a128d8e907071d45f08c878ddacc6362554eee Mon Sep 17 00:00:00 2001 From: Lei Wen Date: Fri, 28 Sep 2012 04:26:43 +0000 Subject: lib: zlib: import trees file from 1.2.5 Signed-off-by: Lei Wen --- lib/zlib/trees.c | 1244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/zlib/trees.h | 127 ++++++ 2 files changed, 1371 insertions(+) create mode 100644 lib/zlib/trees.c create mode 100644 lib/zlib/trees.h diff --git a/lib/zlib/trees.c b/lib/zlib/trees.c new file mode 100644 index 0000000..56e9bb1 --- /dev/null +++ b/lib/zlib/trees.c @@ -0,0 +1,1244 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2010 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/lib/zlib/trees.h b/lib/zlib/trees.h new file mode 100644 index 0000000..45a749f --- /dev/null +++ b/lib/zlib/trees.h @@ -0,0 +1,127 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; -- cgit v1.1 From 7a32b98dacfa2da6dace2ae1d9eff08932eec61a Mon Sep 17 00:00:00 2001 From: Lei Wen Date: Fri, 28 Sep 2012 04:26:44 +0000 Subject: lib: zlib: include deflate into zlib build Add a new config CONFIG_GZIP_ENABLED, if enabled, the uboot bin would include zlib's deflate method which could be used for compressing. Signed-off-by: Lei Wen --- include/u-boot/zlib.h | 40 +++++++++++++++++++++++++++++++++++----- lib/zlib/trees.c | 8 ++++---- lib/zlib/zlib.c | 8 ++++++++ lib/zlib/zutil.h | 4 ++++ 4 files changed, 51 insertions(+), 9 deletions(-) diff --git a/include/u-boot/zlib.h b/include/u-boot/zlib.h index fbb08a3..b611fe7 100644 --- a/include/u-boot/zlib.h +++ b/include/u-boot/zlib.h @@ -513,11 +513,41 @@ typedef gz_header FAR *gz_headerp; If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. - */ - -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, const char *version, - int stream_size)); - + */ + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); + + +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input diff --git a/lib/zlib/trees.c b/lib/zlib/trees.c index 56e9bb1..a0078d0 100644 --- a/lib/zlib/trees.c +++ b/lib/zlib/trees.c @@ -1168,14 +1168,14 @@ local int detect_data_type(s) * method would use a table) * IN assertion: 1 <= len <= 15 */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ +local unsigned bi_reverse(value, len) + unsigned value; /* the value to invert */ int len; /* its bit length */ { register unsigned res = 0; do { - res |= code & 1; - code >>= 1, res <<= 1; + res |= value & 1; + value >>= 1, res <<= 1; } while (--len > 0); return res >> 1; } diff --git a/lib/zlib/zlib.c b/lib/zlib/zlib.c index 230d0df..7e15702 100644 --- a/lib/zlib/zlib.c +++ b/lib/zlib/zlib.c @@ -12,6 +12,14 @@ * - added inflateIncomp */ +#include + +#ifdef CONFIG_GZIP_COMPRESSED +#define NO_DUMMY_DECL +#include "deflate.c" +#include "trees.c" +#endif + #include "zutil.h" #include "inftrees.h" #include "inflate.h" diff --git a/lib/zlib/zutil.h b/lib/zlib/zutil.h index 114cb74..7e05c3b 100644 --- a/lib/zlib/zutil.h +++ b/lib/zlib/zutil.h @@ -83,6 +83,10 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* The minimum and maximum match lengths */ /* functions */ +#ifdef CONFIG_GZIP_COMPRESSED +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ +# define OS_CODE 0x03 /* assume Unix */ +#endif #include #define zmemcpy memcpy -- cgit v1.1 From 869c2abbaf98e91e7c9ef71806f6c8eef91206ae Mon Sep 17 00:00:00 2001 From: Lei Wen Date: Fri, 28 Sep 2012 04:26:45 +0000 Subject: lib: zlib: remove the limitation for cannot using 0 as start We often need the requirement that compressing those memory range start from 0, but the default deflate code in zlib prevent us to do this. Considering the special case of uboot, that it could access all memory range, it is reasonable to be able to also take the address space from 0 into compression. Signed-off-by: Lei Wen --- lib/zlib/deflate.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/zlib/deflate.c b/lib/zlib/deflate.c index 5c4022f..9a20b70 100644 --- a/lib/zlib/deflate.c +++ b/lib/zlib/deflate.c @@ -592,9 +592,7 @@ int ZEXPORT deflate (strm, flush) } s = strm->state; - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { + if (s->status == FINISH_STATE && flush != Z_FINISH) { ERR_RETURN(strm, Z_STREAM_ERROR); } if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); -- cgit v1.1 From 88d52c6affa69971caad651e26dcac88a1484a4b Mon Sep 17 00:00:00 2001 From: Lei Wen Date: Fri, 28 Sep 2012 04:26:46 +0000 Subject: lib: add gzip lib function callback Signed-off-by: Lei Wen --- include/common.h | 7 +++ lib/Makefile | 1 + lib/gzip.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 lib/gzip.c diff --git a/include/common.h b/include/common.h index 55025c0..a7fb05e 100644 --- a/include/common.h +++ b/include/common.h @@ -829,6 +829,13 @@ void fputc(int file, const char c); int ftstc(int file); int fgetc(int file); +/* lib/gzip.c */ +int gzip(void *dst, unsigned long *lenp, + unsigned char *src, unsigned long srclen); +int zzip(void *dst, unsigned long *lenp, unsigned char *src, + unsigned long srclen, int stoponerr, + int (*func)(unsigned long, unsigned long)); + /* lib/net_utils.c */ #include static inline IPaddr_t getenv_IPaddr(char *var) diff --git a/lib/Makefile b/lib/Makefile index c60c380..45798de 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -42,6 +42,7 @@ COBJS-y += errno.o COBJS-$(CONFIG_OF_CONTROL) += fdtdec.o COBJS-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o COBJS-$(CONFIG_GZIP) += gunzip.o +COBJS-$(CONFIG_GZIP_COMPRESSED) += gzip.o COBJS-y += hashtable.o COBJS-$(CONFIG_LMB) += lmb.o COBJS-y += ldiv.o diff --git a/lib/gzip.c b/lib/gzip.c new file mode 100644 index 0000000..a83f4af --- /dev/null +++ b/lib/gzip.c @@ -0,0 +1,142 @@ +/* + * (C) Copyright 2012 + * Lei Wen , Marvell Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include "zlib/zutil.h" + +#ifndef CONFIG_GZIP_COMPRESS_DEF_SZ +#define CONFIG_GZIP_COMPRESS_DEF_SZ 0x200 +#endif +#define ZALLOC_ALIGNMENT 16 + +static void *zalloc(void *x, unsigned items, unsigned size) +{ + void *p; + + size *= items; + size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1); + + p = malloc (size); + + return (p); +} + +static void zfree(void *x, void *addr, unsigned nb) +{ + free (addr); +} + +int gzip(void *dst, unsigned long *lenp, + unsigned char *src, unsigned long srclen) +{ + return zzip(dst, lenp, src, srclen, 1, NULL); +} + +/* + * Compress blocks with zlib + */ +int zzip(void *dst, unsigned long *lenp, unsigned char *src, + unsigned long srclen, int stoponerr, + int (*func)(unsigned long, unsigned long)) +{ + z_stream s; + int r, flush, orig, window; + unsigned long comp_len, left_len; + + if (!srclen) + return 0; + +#ifndef CONFIG_GZIP + window = MAX_WBITS; +#else + window = 2 * MAX_WBITS; +#endif + orig = *lenp; + s.zalloc = zalloc; + s.zfree = zfree; + s.opaque = Z_NULL; + + r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED, window, + DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + ZLIB_VERSION, sizeof(z_stream)); + if (r != Z_OK) { + printf ("Error: deflateInit2_() returned %d\n", r); + return -1; + } + + while (srclen > 0) { + comp_len = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ) ? + CONFIG_GZIP_COMPRESS_DEF_SZ : srclen; + + s.next_in = src; + s.avail_in = comp_len; + flush = (srclen > CONFIG_GZIP_COMPRESS_DEF_SZ)? + Z_NO_FLUSH : Z_FINISH; + + do { + left_len = (*lenp > CONFIG_GZIP_COMPRESS_DEF_SZ) ? + CONFIG_GZIP_COMPRESS_DEF_SZ : *lenp; + s.next_out = dst; + s.avail_out = left_len; + r = deflate(&s, flush); + if (r == Z_STREAM_ERROR && stoponerr == 1) { + printf("Error: deflate() returned %d\n", r); + r = -1; + goto bail; + } + if (!func) { + dst += (left_len - s.avail_out); + *lenp -= (left_len - s.avail_out); + } else if (left_len - s.avail_out > 0) { + r = func((unsigned long)dst, + left_len - s.avail_out); + if (r < 0) + goto bail; + } + } while (s.avail_out == 0 && (*lenp > 0)); + if (s.avail_in) { + printf("Deflate failed to consume %u bytes", s.avail_in); + r = -1; + goto bail; + } + if (*lenp == 0) { + printf("Deflate need more space to compress " + "left %lu bytes\n", srclen); + r = -1; + goto bail; + } + srclen -= comp_len; + src += comp_len; + } + + r = 0; +bail: + deflateEnd(&s); + *lenp = orig - *lenp; + return r; +} -- cgit v1.1 From f2b96dfbbcd0636e31ebf26bfa9ca91c656660d2 Mon Sep 17 00:00:00 2001 From: Lei Wen Date: Fri, 28 Sep 2012 04:26:47 +0000 Subject: common: add zip command support Signed-off-by: Lei Wen --- README | 6 ++++++ common/Makefile | 1 + common/cmd_zip.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 common/cmd_zip.c diff --git a/README b/README index a745d0b..af76b0c 100644 --- a/README +++ b/README @@ -1483,6 +1483,12 @@ The following options need to be configured: can be displayed via the splashscreen support or the bmp command. +- Do compresssing for memory range: + CONFIG_CMD_ZIP + + If this option is set, it would use zlib deflate method + to compress the specified memory at its best effort. + - Compression support: CONFIG_BZIP2 diff --git a/common/Makefile b/common/Makefile index b56df1d..125b2be 100644 --- a/common/Makefile +++ b/common/Makefile @@ -170,6 +170,7 @@ endif COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o +COBJS-$(CONFIG_CMD_ZIP) += cmd_zip.o COBJS-$(CONFIG_CMD_ZFS) += cmd_zfs.o # others diff --git a/common/cmd_zip.c b/common/cmd_zip.c new file mode 100644 index 0000000..a73c86d --- /dev/null +++ b/common/cmd_zip.c @@ -0,0 +1,60 @@ +/* + * (C) Copyright 2012 + * Lei Wen , Marvell Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +static int do_zip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + unsigned long src, dst; + unsigned long src_len, dst_len = ~0UL; + char buf[32]; + + switch (argc) { + case 5: + dst_len = simple_strtoul(argv[4], NULL, 16); + /* fall through */ + case 4: + src = simple_strtoul(argv[1], NULL, 16); + src_len = simple_strtoul(argv[2], NULL, 16); + dst = simple_strtoul(argv[3], NULL, 16); + break; + default: + return cmd_usage(cmdtp); + } + + if (gzip((void *) dst, &dst_len, (void *) src, src_len) != 0) + return 1; + + printf("Compressed size: %ld = 0x%lX\n", dst_len, dst_len); + sprintf(buf, "%lX", dst_len); + setenv("filesize", buf); + + return 0; +} + +U_BOOT_CMD( + zip, 5, 1, do_zip, + "zip a memory region", + "srcaddr srcsize dstaddr [dstsize]" +); -- cgit v1.1 From e5acb883aee6dbe5894f066216dbf9a18951113d Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Sat, 29 Sep 2012 00:52:55 +0000 Subject: cmd_fat.c: fix build warning Commit cfda5aeab89d73779e26f0d34cf10f64caa67431 (cmd_fat: use common get_device_and_partition function) introduced a warning: cmd_fat.c: In function 'do_fat_fswrite': cmd_fat.c:178:8: warning: unused variable 'ep' [-Wunused-variable] Fix it. Signed-off-by: Anatolij Gustschin Reported-by: Albert ARIBAUD Tested-by: Albert ARIBAUD --- common/cmd_fat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/common/cmd_fat.c b/common/cmd_fat.c index 55585c6..5a5698b 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -175,7 +175,6 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag, disk_partition_t info; int dev = 0; int part = 1; - char *ep; if (argc < 5) return cmd_usage(cmdtp); -- cgit v1.1 From 4668a086bb0a769b741e3a4ffab85f1c41c7cdb8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 28 Sep 2012 08:23:45 +0000 Subject: sandbox: Add asm/errno.h This file is required for all archs. Fixes a sandbox build break on ext4. Signed-off-by: Simon Glass --- arch/sandbox/include/asm/errno.h | 1 + 1 file changed, 1 insertion(+) create mode 100644 arch/sandbox/include/asm/errno.h diff --git a/arch/sandbox/include/asm/errno.h b/arch/sandbox/include/asm/errno.h new file mode 100644 index 0000000..4c82b50 --- /dev/null +++ b/arch/sandbox/include/asm/errno.h @@ -0,0 +1 @@ +#include -- cgit v1.1