diff options
Diffstat (limited to 'package/system/utils')
30 files changed, 3901 insertions, 0 deletions
diff --git a/package/system/utils/e2fsprogs/Makefile b/package/system/utils/e2fsprogs/Makefile new file mode 100644 index 0000000000..ebc21c9067 --- /dev/null +++ b/package/system/utils/e2fsprogs/Makefile @@ -0,0 +1,169 @@ +# +# Copyright (C) 2006-2012 OpenWrt.org +# Copyright 2010 Vertical Communications +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=e2fsprogs +PKG_VERSION:=1.42.4 +PKG_MD5SUM:=b6e296f210d642361b7394437ff0f318 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@SF/e2fsprogs + +PKG_BUILD_DEPENDS:=util-linux +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/e2fsprogs/Default + URL:=http://e2fsprogs.sourceforge.net/ + SUBMENU:=Filesystem +endef + +define Package/e2fsprogs +$(call Package/e2fsprogs/Default) + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Ext2/3/4 filesystem utilities + DEPENDS:=+libblkid +libuuid +libext2fs +endef + +define Package/e2fsprogs/description + This package contains essential ext2 filesystem utilities which consists of + e2fsck, mke2fs, tune2fs, and most of the other core ext2 + filesystem utilities. +endef + +define Package/libext2fs +$(call Package/e2fsprogs/Default) + DEPENDS:=+libcom_err + SECTION:=libs + CATEGORY:=Libraries + TITLE:=ext2/3/4 filesystem library +endef + +define Package/libext2fs/description + libext2fs is a library which can access ext2, ext3 and ext4 filesystems. +endef + +define Package/libcom_err +$(call Package/e2fsprogs/Default) + DEPENDS:=+libpthread + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Common error description library +endef + +define Package/libcom_err/description + libcom_err is a library providing common error descriptions +endef + +define Package/tune2fs +$(call Package/e2fsprogs) + TITLE:=Ext2 Filesystem tune utility + DEPENDS:= +e2fsprogs +endef + +define Package/resize2fs +$(call Package/e2fsprogs) + TITLE:=Ext2 Filesystem resize utility + DEPENDS:= +e2fsprogs +endef + +define Package/badblocks +$(call Package/e2fsprogs) + TITLE:=Ext2 Filesystem badblocks utility + DEPENDS:= +e2fsprogs +endef + +TARGET_CFLAGS += $(FPIC) + +CONFIGURE_ARGS += \ + --enable-elf-shlibs \ + --disable-libuuid \ + --disable-libblkid \ + --disable-uuidd \ + --disable-tls \ + --disable-nls \ + --disable-rpath + +define Build/Prepare + $(call Build/Prepare/Default) + $(CP) $(SCRIPT_DIR)/config.{guess,sub} $(PKG_BUILD_DIR)/config/ +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR)/util \ + BUILDCC="$(HOSTCC)" \ + CFLAGS="" \ + CPPFLAGS="" \ + LDFLAGS="" \ + subst + $(MAKE) -C $(PKG_BUILD_DIR) \ + BUILDCC="$(HOSTCC)" \ + DESTDIR="$(PKG_INSTALL_DIR)" \ + all +endef + +define Build/InstallDev + $(MAKE) -C $(PKG_BUILD_DIR) \ + BUILDCC="$(HOSTCC)" \ + DESTDIR="$(1)" \ + install-libs + $(MAKE) -C $(PKG_BUILD_DIR)/lib/ext2fs \ + BUILDCC="$(HOSTCC)" \ + DESTDIR="$(1)" \ + install +endef + +define Package/e2fsprogs/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/e2fsck $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/mke2fs $(1)/usr/sbin/ + ln -sf mke2fs $(1)/usr/sbin/mkfs.ext2 + ln -sf mke2fs $(1)/usr/sbin/mkfs.ext3 + ln -sf mke2fs $(1)/usr/sbin/mkfs.ext4 + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libe2p.so.* $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/lib/functions/fsck + $(INSTALL_DATA) ./files/e2fsck.sh $(1)/lib/functions/fsck/ + $(INSTALL_DATA) ./files/e2fsck.conf $(1)/etc/e2fsck.conf +endef + +define Package/libcom_err/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libcom_err.so.* $(1)/usr/lib/ +endef + +define Package/libext2fs/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libext2fs.so.* $(1)/usr/lib/ +endef + +define Package/tune2fs/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/tune2fs $(1)/usr/sbin/ +endef + +define Package/resize2fs/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/resize2fs $(1)/usr/sbin/ +endef + +define Package/badblocks/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/badblocks $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,e2fsprogs)) +$(eval $(call BuildPackage,libext2fs)) +$(eval $(call BuildPackage,libcom_err)) +$(eval $(call BuildPackage,tune2fs)) +$(eval $(call BuildPackage,resize2fs)) +$(eval $(call BuildPackage,badblocks)) diff --git a/package/system/utils/e2fsprogs/files/e2fsck.conf b/package/system/utils/e2fsprogs/files/e2fsck.conf new file mode 100644 index 0000000000..9c96b49585 --- /dev/null +++ b/package/system/utils/e2fsprogs/files/e2fsck.conf @@ -0,0 +1,3 @@ +[options] +broken_system_clock = true + diff --git a/package/system/utils/e2fsprogs/files/e2fsck.sh b/package/system/utils/e2fsprogs/files/e2fsck.sh new file mode 100644 index 0000000000..22031edb67 --- /dev/null +++ b/package/system/utils/e2fsprogs/files/e2fsck.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# Copyright 2010 Vertical Communications +# Copyright 2012 OpenWrt.org +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +fsck_e2fsck() { + set -o pipefail + e2fsck -p "$device" 2>&1 | logger -t "fstab: e2fsck ($device)" + local status="$?" + set +o pipefail + case "$status" in + 0|1) ;; #success + 2) reboot;; + 4) echo "e2fsck ($device): Warning! Uncorrected errors."| logger -t fstab + return 1 + ;; + *) echo "e2fsck ($device): Error $status. Check not complete."| logger -t fstab;; + esac + return 0 +} + +fsck_ext2() { + fsck_e2fsck "$@" +} + +fsck_ext3() { + fsck_e2fsck "$@" +} + +fsck_ext4() { + fsck_e2fsck "$@" +} + +append libmount_known_fsck "ext2" +append libmount_known_fsck "ext3" +append libmount_known_fsck "ext4" diff --git a/package/system/utils/e2fsprogs/patches/001-link-against-libuuid.patch b/package/system/utils/e2fsprogs/patches/001-link-against-libuuid.patch new file mode 100644 index 0000000000..e0564dc355 --- /dev/null +++ b/package/system/utils/e2fsprogs/patches/001-link-against-libuuid.patch @@ -0,0 +1,38 @@ +--- a/configure ++++ b/configure +@@ -5038,7 +5038,7 @@ if test "${ac_cv_lib_blkid_blkid_get_cac + $as_echo_n "(cached) " >&6 + else + ac_check_lib_save_LIBS=$LIBS +-LIBS="-lblkid $LIBBLKID $LIBS" ++LIBS="-lblkid $LIBBLKID $LIBUUID $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + +--- a/misc/Makefile.in ++++ b/misc/Makefile.in +@@ -146,10 +146,10 @@ partinfo: partinfo.o + $(E) " LD $@" + $(Q) $(CC) $(ALL_LDFLAGS) -o partinfo partinfo.o + +-e2initrd_helper: e2initrd_helper.o $(DEPLIBS) $(DEPLIBBLKID) $(LIBEXT2FS) ++e2initrd_helper: e2initrd_helper.o $(DEPLIBS) $(DEPLIBBLKID) $(DEPLIBUUID) $(LIBEXT2FS) + $(E) " LD $@" + $(Q) $(CC) $(ALL_LDFLAGS) -o e2initrd_helper e2initrd_helper.o $(LIBS) \ +- $(LIBBLKID) $(LIBEXT2FS) $(LIBINTL) ++ $(LIBBLKID) $(LIBUUID) $(LIBEXT2FS) $(LIBINTL) + + tune2fs: $(TUNE2FS_OBJS) $(DEPLIBS) $(DEPLIBS_E2P) $(DEPLIBBLKID) \ + $(DEPLIBUUID) $(DEPLIBQUOTA) $(LIBEXT2FS) +@@ -289,9 +289,9 @@ dumpe2fs.profiled: $(PROFILED_DUMPE2FS_O + $(PROFILED_DUMPE2FS_OBJS) $(PROFILED_LIBS) \ + $(PROFILED_LIBE2P) $(PROFILED_LIBUUID) $(LIBINTL) + +-fsck: $(FSCK_OBJS) $(DEPLIBBLKID) ++fsck: $(FSCK_OBJS) $(DEPLIBBLKID) $(DEPLIBUUID) + $(E) " LD $@" +- $(Q) $(CC) $(ALL_LDFLAGS) -o fsck $(FSCK_OBJS) $(LIBBLKID) $(LIBINTL) ++ $(Q) $(CC) $(ALL_LDFLAGS) -o fsck $(FSCK_OBJS) $(LIBBLKID) $(LIBUUID) $(LIBINTL) + + fsck.profiled: $(PROFILED_FSCK_OBJS) $(PROFILED_DEPLIBBLKID) + $(E) " LD $@" diff --git a/package/system/utils/e2fsprogs/patches/002-no_malloc_h.patch b/package/system/utils/e2fsprogs/patches/002-no_malloc_h.patch new file mode 100644 index 0000000000..209b47c1cc --- /dev/null +++ b/package/system/utils/e2fsprogs/patches/002-no_malloc_h.patch @@ -0,0 +1,10 @@ +--- a/util/symlinks.c ++++ b/util/symlinks.c +@@ -8,7 +8,6 @@ + #endif + #include <stdio.h> + #include <stdlib.h> +-#include <malloc.h> + #include <string.h> + #include <fcntl.h> + #include <sys/param.h> diff --git a/package/system/utils/fbtest/Makefile b/package/system/utils/fbtest/Makefile new file mode 100644 index 0000000000..05e67cb63a --- /dev/null +++ b/package/system/utils/fbtest/Makefile @@ -0,0 +1,44 @@ +# +# Copyright (C) 2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=fbtest +PKG_RELEASE:=1 + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/fbtest + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Frame buffer device testing tool + DEPENDS:=@DISPLAY_SUPPORT +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Configure +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS) -Wall" \ + LDFLAGS="$(TARGET_LDFLAGS)" +endef + +define Package/fbtest/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/fbtest $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,fbtest)) diff --git a/package/system/utils/fbtest/src/Makefile b/package/system/utils/fbtest/src/Makefile new file mode 100644 index 0000000000..075bc0ecbf --- /dev/null +++ b/package/system/utils/fbtest/src/Makefile @@ -0,0 +1,14 @@ +CC = gcc +CFLAGS = -Wall +OBJS = fbtest.o + +all: fbtest + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +fbtest: $(OBJS) + $(CC) -o $@ $(OBJS) + +clean: + rm -f rbcfg *.o diff --git a/package/system/utils/fbtest/src/fbtest.c b/package/system/utils/fbtest/src/fbtest.c new file mode 100644 index 0000000000..6e9c2f85fa --- /dev/null +++ b/package/system/utils/fbtest/src/fbtest.c @@ -0,0 +1,448 @@ +/****************************************************************************** + * fbtest - fbtest.c + * test program for the tuxbox-framebuffer device + * tests all GTX/eNX supported modes + * + * (c) 2003 Carsten Juttner (carjay@gmx.net) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * The Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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. + * + ****************************************************************************** + * $Id: fbtest.c,v 1.5 2005/01/14 23:14:41 carjay Exp $ + ******************************************************************************/ + +// TODO: - should restore the colour map and mode to what it was before +// - is colour map handled correctly? + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <fcntl.h> + +#include <linux/fb.h> + +#include <error.h> + +#define FBDEV "/dev/fb0" + +struct vidsize{ + int width; + int height; +}; +static +const struct vidsize vidsizetable[]={ // all supported sizes + {720,576},{720,480},{720,288},{720,240}, + {640,576},{640,480},{640,288},{640,240}, + {360,576},{360,480},{360,288},{360,240}, + {320,576},{320,480},{320,288},{320,240} +}; +#define VIDSIZENUM (sizeof(vidsizetable)/sizeof(struct vidsize)) + +enum pixenum{ // keep in sync with pixname ! + CLUT4=0, + CLUT8, + RGB565, + ARGB1555, + ARGB +}; +const char *pixname[] = { + "CLUT4", + "CLUT8", + "RGB565", + "ARGB1555", + "ARGB" +}; + +struct pixelformat{ + char *name; + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; + char bpp; + char pixenum; +}; + +static // so far these are all modes supported by the eNX (only partially by GTX) +const struct pixelformat pixelformattable[] = { + { .name = "CLUT4 ARGB8888", // CLUT4 (ARGB8888) + .bpp = 4, .pixenum = CLUT4, + .red = { .offset = 0, .length=8, .msb_right =0 }, + .green = { .offset = 0, .length=8, .msb_right =0 }, + .blue = { .offset = 0, .length=8, .msb_right =0 }, + .transp= { .offset = 0, .length=8, .msb_right =0 } + }, + { .name = "CLUT4 ARGB1555", // CLUT4 (ARGB1555) + .bpp = 4, .pixenum = CLUT4, + .red = { .offset = 0, .length=5, .msb_right =0 }, + .green = { .offset = 0, .length=5, .msb_right =0 }, + .blue = { .offset = 0, .length=5, .msb_right =0 }, + .transp= { .offset = 0, .length=1, .msb_right =0 } + }, + { .name = "CLUT8 ARGB8888", // CLUT8 (ARGB8888) + .bpp = 8, .pixenum = CLUT8, + .red = { .offset = 0, .length=8, .msb_right =0 }, + .green = { .offset = 0, .length=8, .msb_right =0 }, + .blue = { .offset = 0, .length=8, .msb_right =0 }, + .transp= { .offset = 0, .length=8, .msb_right =0 } + }, + { .name = "CLUT8 ARGB1555", // CLUT8 (ARGB1555) + .bpp = 8, .pixenum = CLUT8, + .red = { .offset = 0, .length=5, .msb_right =0 }, + .green = { .offset = 0, .length=5, .msb_right =0 }, + .blue = { .offset = 0, .length=5, .msb_right =0 }, + .transp= { .offset = 0, .length=1, .msb_right =0 } + }, + { .name = "ARGB1555", // ARGB1555 + .bpp = 16, .pixenum = ARGB1555, + .red = { .offset = 10, .length=5, .msb_right =0 }, + .green = { .offset = 5, .length=5, .msb_right =0 }, + .blue = { .offset = 0, .length=5, .msb_right =0 }, + .transp= { .offset = 15, .length=1, .msb_right =0 } + }, + { .name = "RGB565", // RGB565 + .bpp = 16, .pixenum = RGB565, + .red = { .offset = 11, .length=5, .msb_right =0 }, + .green = { .offset = 5, .length=6, .msb_right =0 }, + .blue = { .offset = 0, .length=5, .msb_right =0 }, + .transp= { .offset = 0, .length=0, .msb_right =0 } + }, + { .name = "ARGB", // 32 f*cking bits, the real McCoy :) + .bpp = 32, .pixenum = ARGB, + .red = { .offset = 16, .length=8, .msb_right =0 }, + .green = { .offset = 8, .length=8, .msb_right =0 }, + .blue = { .offset = 0, .length=8, .msb_right =0 }, + .transp= { .offset = 24, .length=8, .msb_right =0 } + } +}; +#define PIXELFORMATNUM (sizeof(pixelformattable)/sizeof(struct pixelformat)) + +struct colour { + __u16 r; + __u16 g; + __u16 b; + __u16 a; +}; +static +struct colour colourtable[] = { + {.r =0xffff, .g = 0xffff, .b=0xffff, .a=0xffff}, // fully transparent white + {.r =0xffff, .g = 0x0000, .b=0x0000, .a=0x0000}, // red + {.r =0x0000, .g = 0xffff, .b=0x0000, .a=0x0000}, // green + {.r =0x0000, .g = 0x0000, .b=0xffff, .a=0x0000}, // blue + {.r =0x0000, .g = 0x0000, .b=0x0000, .a=0x0000} // black +}; +#define COLOURNUM (sizeof(colourtable)/sizeof(struct colour)) + +struct rect{ + int x; + int y; + int width; + int height; + const struct colour *col; +}; +struct pixel{ // up to 32 bits of pixel information + char byte[4]; +}; + +void col2pixel (struct pixel *pix, const struct pixelformat *pixf, const struct colour *col){ + switch (pixf->pixenum){ + case RGB565: + pix->byte[0]=(col->r&0xf8)|(col->g&0xfc)>>5; + pix->byte[1]=(col->g&0xfc)<<3|(col->b&0xf8)>>3; + break; + case ARGB1555: + pix->byte[0]=(col->a&0x80)|(col->r&0xf8)>>1|(col->g&0xf8)>>6; + pix->byte[1]=(col->g&0xf8)<<2|(col->b&0xf8)>>3; + break; + case ARGB: + pix->byte[0]=col->a; + pix->byte[1]=col->r; + pix->byte[2]=col->g; + pix->byte[3]=col->b; + break; + default: + printf ("unknown pixelformat\n"); + exit(1); + } +} + +int setmode(int fbd, const struct pixelformat *pixf,const struct vidsize *vids){ + struct fb_var_screeninfo var; + int stat; + stat = ioctl (fbd, FBIOGET_VSCREENINFO,&var); + if (stat<0) return -2; + + var.xres= vids->width; + var.xres_virtual = vids->width; + var.yres= vids->height; + var.yres_virtual = vids->height; + + var.bits_per_pixel = pixf->bpp; + var.red = pixf->red; + var.green = pixf->green; + var.blue = pixf->blue; + var.transp = pixf->transp; + + stat = ioctl (fbd, FBIOPUT_VSCREENINFO,&var); + if (stat<0) return -1; + return 0; +} + +// unefficient implementation, do NOT use it for your next ego shooter, please :) +// for 4-Bit only rectangles with even width are supported +// CLUT-modes use value of red component as index +void drawrect(void *videoram, struct rect *r, const struct pixelformat *pixf, const struct vidsize *vids){ + int x,y,corwidth, bpp = 0, tocopy = 1; + struct pixel pix; + unsigned char *pmem = videoram; + corwidth = r->width; // actually only "corrected" for 4 Bit + + if (pixf->pixenum!=CLUT4&&pixf->pixenum!=CLUT8){ + switch (pixf->pixenum){ + case ARGB1555: + case RGB565: + bpp = 16; + tocopy = 2; + break; + case ARGB: + bpp = 32; + tocopy = 4; + break; + default: + printf ("drawrect: unknown pixelformat(%d) bpp:%d\n",pixf->pixenum,pixf->bpp); + exit(1); + } + col2pixel(&pix,pixf,r->col); + } else { + switch (pixf->pixenum){ // CLUT = Colour LookUp Table (palette) + case CLUT4: // take red value as index in this case + pix.byte[0]=(r->col->r)<<4|(r->col->r&0xf); // slightly cryptic... "rect->colour->red" + corwidth>>=1; // we copy bytes + bpp=4; + tocopy=1; + break; + case CLUT8: + pix.byte[0]=(r->col->r&0xff); + bpp=8; + tocopy=1; + break; + } + } + pmem=videoram+((((r->y*vids->width)+r->x)*bpp)>>3); + for (y=0;y<r->height;y++){ + int offset = 0; + for (x=0;x<corwidth;x++){ + memcpy (pmem+offset,pix.byte,tocopy); + offset+=tocopy; + } + pmem +=((vids->width*bpp)>>3); // skip one whole line, actually should be taken from "fix-info" + } +} + +// create quick little test image, 4 colours from table +void draw4field(void *videoram, const struct pixelformat *pixf, const struct vidsize *vids){ + struct rect r; + struct colour c; + int height, width; + c.r = 1; // only used for the indexed modes, r is taken as index + height = vids->height; + width = vids->width; + + r.height = height>>1; + r.width = width>>1; + r.x = 0; r.y = 0; + if (pixf->pixenum==CLUT4||pixf->pixenum==CLUT8) r.col = &c; + else r.col = &colourtable[1]; + drawrect (videoram, &r, pixf, vids); + + r.x = width/2; r.y = 0; + if (pixf->pixenum==CLUT4||pixf->pixenum==CLUT8) c.r = 2; + else r.col = &colourtable[2]; + drawrect (videoram, &r, pixf, vids); + + r.x = 0; r.y = height/2; + if (pixf->pixenum==CLUT4||pixf->pixenum==CLUT8) c.r = 3; + else r.col = &colourtable[3]; + drawrect (videoram, &r, pixf, vids); + + r.x = width/2; r.y = height/2; + if (pixf->pixenum==CLUT4||pixf->pixenum==CLUT8) c.r = 0; + else r.col = &colourtable[0]; + drawrect (videoram, &r, pixf, vids); +} + +void usage(char *name){ + printf ("Usage: %s [options]\n" + "Options: -f<pixelformat>\n" + " where format is one of:\n" + " CLUT4,CLUT8,ARGB1555,RGB565,ARGB\n" + " -s<width>x<heigth>\n" + " where width is either 720,640,360,320\n" + " and height is either 288,240,480,576\n" + " -n\n" + " disables clearing the framebuffer after drawing\n" + " the testimage. This can be useful to keep the last\n" + " drawn image onscreen.\n" + "\nExample: %s -fRGB322\n",name,name); + exit(0); +} + +int main (int argc,char **argv){ + struct fb_fix_screeninfo fix; + struct fb_var_screeninfo var; + struct fb_cmap cmap; + struct rect r; + int fbd; + unsigned char *pfb; + int stat; + int optchar,fmode=-1,smode=-1,clear=1; + int i_cmap,i_size,i_pix; + extern char *optarg; + + if (argc!=0&&argc>4) usage(argv[0]); + while ( (optchar = getopt (argc,argv,"f:s:n"))!= -1){ + int i,height,width; + switch (optchar){ + case 'f': + for (i=0;i<(sizeof(pixname)/sizeof(char*));i++){ + if (!strncmp (optarg,pixname[i],strlen(pixname[i]))){ + fmode=i; + printf ("displaying only %s-modes\n",pixname[i]); + break; + } + } + if (fmode==-1){ + printf ("unknown pixelformat\n"); + exit(0); + } + break; + case 's': + if (sscanf (optarg,"%dx%d",&width,&height)!=2){ + printf ("parsing size failed\n"); + exit(0); + } else { + printf ("requested size %dx%d\n",width,height); + for (i=0;i<VIDSIZENUM;i++){ + if (vidsizetable[i].width == width && + vidsizetable[i].height == height){ + smode = i; + break; + } + } + if (smode==-1){ + printf ("this size is not supported\n"); + exit(0); + } + } + break; + case 'n': + clear = 0; + printf ("clearing framebuffer after drawing is disabled\n"); + break; + case '?': + usage (argv[0]); + } + } + + fbd = open (FBDEV, O_RDWR); + if (fbd<0){ + perror ("Error opening framebuffer device"); + return 1; + } + stat = ioctl (fbd, FBIOGET_FSCREENINFO,&fix); + if (stat<0){ + perror ("Error getting fix screeninfo"); + return 1; + } + stat = ioctl (fbd, FBIOGET_VSCREENINFO,&var); + if (stat<0){ + perror ("Error getting var screeninfo"); + return 1; + } + stat = ioctl (fbd, FBIOPUT_VSCREENINFO,&var); + if (stat<0){ + perror ("Error setting mode"); + return 1; + } + pfb = mmap (0, fix.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, fbd, 0); + if (pfb == MAP_FAILED){ + perror ("Error mmap'ing framebuffer device"); + return 1; + } + + // iterate over all modes + for (i_pix=0;i_pix<PIXELFORMATNUM;i_pix++){ + if (fmode!=-1 && pixelformattable[i_pix].pixenum != fmode) continue; + printf ("testing: %s",pixelformattable[i_pix].name); + printf (" for sizes: \n"); + for (i_size=0;i_size<VIDSIZENUM;i_size++){ + if (smode!=-1 && i_size!=smode) continue; + printf ("%dx%d ",vidsizetable[i_size].width,vidsizetable[i_size].height); + fflush(stdout); + if ((i_size%4)==3) printf ("\n"); + + // try to set mode + stat = setmode(fbd,&pixelformattable[i_pix],&vidsizetable[i_size]); + if (stat==-2) perror ("fbtest: could not get fb_var-screeninfo from fb-device"); + else if (stat==-1){ + printf ("\nCould not set mode %s (%dx%d), possible reasons:\n" + "- you have a GTX (soz m8)\n" + "- your configuration does not have enough graphics RAM\n" + "- you found a bug\n" + "choose your poison accordingly...\n", + pixelformattable[i_pix].name,vidsizetable[i_size].width,vidsizetable[i_size].height); + continue; + } + // fill cmap; + cmap.len = 1; + if ((pixelformattable[i_pix].bpp==4)|| + ((pixelformattable[i_pix].bpp==8)&&(pixelformattable[i_pix].red.length!=3))){ + for (i_cmap=0;i_cmap<COLOURNUM;i_cmap++){ + cmap.start=i_cmap; + cmap.red=&colourtable[i_cmap].r; + cmap.green=&colourtable[i_cmap].g; + cmap.blue=&colourtable[i_cmap].b; + cmap.transp=&colourtable[i_cmap].a; + stat = ioctl (fbd, FBIOPUTCMAP, &cmap); + if (stat<0) printf ("setting colourmap failed\n"); + } + } + // create the test image + draw4field(pfb,&pixelformattable[i_pix],&vidsizetable[i_size]); + usleep (500000); + // clear screen + if (clear){ + r.x=r.y=0;r.width = vidsizetable[i_size].width; r.height = vidsizetable[i_size].height; + r.col = &colourtable[4]; + drawrect(pfb,&r,&pixelformattable[i_pix],&vidsizetable[i_size]); + } + } + printf ("\n"); + } + + stat = munmap (pfb,fix.smem_len); + if (stat<0){ + perror ("Error munmap'ing framebuffer device"); + return 1; + } + close (fbd); + return 0; +} diff --git a/package/system/utils/hostap-utils/Makefile b/package/system/utils/hostap-utils/Makefile new file mode 100644 index 0000000000..1d7b22122e --- /dev/null +++ b/package/system/utils/hostap-utils/Makefile @@ -0,0 +1,44 @@ +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=hostap-utils +PKG_VERSION:=0.4.7 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://hostap.epitest.fi/releases/ +PKG_MD5SUM:=afe041581b8f01666e353bec20917c85 + +include $(INCLUDE_DIR)/package.mk + +define Package/hostap-utils + SECTION:=net + CATEGORY:=Network + DEPENDS:=kmod-hostap + TITLE:=Host AP driver utility programs + URL:=http://hostap.epitest.fi/ +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(TARGET_CONFIGURE_OPTS) \ + CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS) -Wall" \ + all +endef + +define Package/hostap-utils/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostap_crypt_conf $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostap_diag $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostap_io_debug $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostap_rid $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/prism2_srec $(1)/usr/sbin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/split_combined_hex $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,hostap-utils)) diff --git a/package/system/utils/nvram/Makefile b/package/system/utils/nvram/Makefile new file mode 100644 index 0000000000..81cff034c4 --- /dev/null +++ b/package/system/utils/nvram/Makefile @@ -0,0 +1,60 @@ +# +# Copyright (C) 2009-2010 Jo-Philipp Wich <xm@subsignal.org> +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=nvram +PKG_RELEASE:=9 + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/nvram + SECTION:=utils + CATEGORY:=Base system + TITLE:=Userspace port of the Broadcom NVRAM manipulation tool + MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org> + DEPENDS:=@TARGET_brcm47xx||@TARGET_ar71xx +endef + +define Package/nvram/description + This package contains an utility to manipulate NVRAM on Broadcom based devices. + It works on bcm47xx (Linux 2.6) without using the kernel api. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Configure +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS) -Wall" \ + LDFLAGS="$(TARGET_LDFLAGS)" +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_BIN) $(PKG_BUILD_DIR)/libnvram.so.0.1 $(1)/usr/lib/ + ln -s libnvram.so.0.1 $(1)/usr/lib/libnvram.so +endef + +define Package/nvram/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/nvram.init $(1)/etc/init.d/nvram + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/nvram $(1)/usr/sbin/ + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_BIN) $(PKG_BUILD_DIR)/libnvram.so.0.1 $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,nvram)) diff --git a/package/system/utils/nvram/files/nvram.init b/package/system/utils/nvram/files/nvram.init new file mode 100755 index 0000000000..467ab28195 --- /dev/null +++ b/package/system/utils/nvram/files/nvram.init @@ -0,0 +1,98 @@ +#!/bin/sh /etc/rc.common +# NVRAM setup +# +# This file handles the NVRAM quirks of various hardware. + +START=02 +alias debug=${DEBUG:-:} + +nvram_default() { + [ -z "$(nvram get $1)" ] && nvram set "$1=$2" +} + +nvram_set() { # for the linksys fixup part + [ "$(nvram get "$1")" = "$2" -a "$2" != "" ] || { + COMMIT=1 + /usr/sbin/nvram set "$1=$2" + } +} + +fixup_linksys() { + # work around braindead CFE defaults in linksys routers + boardtype=$(nvram get boardtype) + boardnum=$(nvram get boardnum) + boardflags=$(($(nvram get boardflags))) + adm_switch="$(( ($boardflags & 0x80) >> 7 ))" + + [ -n "$(nvram get vxkilled)" ] && boardtype=0 # don't mess with the ram settings on the hacked cfe + case "$(( $boardtype ))" in + "1800") #0x708 + if [ "$adm_switch" = 0 ]; then + nvram_set sdram_init "$(printf 0x%04x $(( $(/usr/sbin/nvram get sdram_init) | 0x0100 )))" + [ "$COMMIT" = 1 ] && { + nvram_set clkfreq 216 + nvram_set sdram_ncdl 0x0 + nvram_set pa0itssit 62 + nvram_set pa0b0 0x15eb + nvram_set pa0b1 0xfa82 + nvram_set pa0b2 0xfe66 + nvram_set pa0maxpwr 0x4e + } + fi + ;; + "1127") #0x467 + nvram_set sdram_init "$(printf 0x%04x $(( $(/usr/sbin/nvram get sdram_init) | 0x0100 )))" + [ "$COMMIT" = 1 ] && { + nvram_set sdram_ncdl 0x0 + nvram_set pa0itssit 62 + nvram_set pa0b0 0x168b + nvram_set pa0b1 0xfabf + nvram_set pa0b2 0xfeaf + nvram_set pa0maxpwr 0x4e + } + ;; + "1071") #0x042f + # do sanity check first! max 0x0011 = 128mb + SDRAM_INIT=$(printf %d $(/usr/sbin/nvram get sdram_init)) + [ "$SDRAM_INIT" -lt "9" -o "$SDRAM_INIT" -gt "17" ] && { + # set this to default: 0x09 only if value is invaild like 16MB on Asus WL-500GP + echo "sdram_init is invaild: $(printf 0x%04x $SDRAM_INIT), force to default!" + nvram_set sdram_init 0x0009 + } + # on WRT54G3GV2 set flag, so checksum errors of firmware image 2 don't stop the boot process + noset_try_flag=$(nvram get noset_try_flag) + [ "$noset_try_flag" = 0 ] && { + echo "setting noset_try_flag to 1." + nvram_set noset_try_flag 1 + } + [ "$COMMIT" = 1 ] && { + nvram_set sdram_ncdl 0x0 + } + esac +} + +start() { + # Don't do any fixups on the WGT634U + [ "$(cat /proc/diag/model)" = "Netgear WGT634U" ] && return + + fixup_linksys + + # OFDM Power Offset is set incorrectly on many boards. + # Setting it to 0 will increase the tx power to normal levels. + nvram_set opo 0x0 + + [ "$(nvram get il0macaddr)" = "00:90:4c:5f:00:2a" ] && { + # if default wifi mac, set two higher than the lan mac + nvram set il0macaddr=$(nvram get et0macaddr| + awk '{OFS=FS=":";for(x=7,y=2;--x;){$x=sprintf("%02x",(y+="0x"$x)%256);y/=256}print}') + } + + [ "$(nvram get et0macaddr)" = "00:90:4c:c0:00:08" ] && { + # OvisLink WL-1600GL mac workaround + nvram set et0macaddr=$(hexdump -n 6 -s 130976 -e '5/1 "%02x:" "%02x" ' /dev/mtd/0) + nvram set il0macaddr=$(nvram get et0macaddr| + awk '{OFS=FS=":";for(x=7,y=2;--x;){$x=sprintf("%02x",(y+="0x"$x)%256);y/=256}print}') + } + + [ "$COMMIT" = "1" ] && nvram commit +} diff --git a/package/system/utils/nvram/src/Makefile b/package/system/utils/nvram/src/Makefile new file mode 100644 index 0000000000..4872728baf --- /dev/null +++ b/package/system/utils/nvram/src/Makefile @@ -0,0 +1,33 @@ +CLI_FILENAME = nvram + +LIB_VERMAJOR = 0 +LIB_VERMINOR = 1 +LIB_FILENAME = libnvram.so + +LIB_CFLAGS = $(CFLAGS) -shared -fPIC +LIB_LDFLAGS = $(LDFLAGS) -Wl,-soname,$(LIB_FILENAME).$(LIB_VERMAJOR).$(LIB_VERMINOR) + +CLI_CFLAGS = $(CFLAGS) +CLI_LDFLAGS = $(LDFLAGS) + +CLI_OBJ = cli.o +LIB_OBJ = crc.o nvram.o + +all: cli libnvram + +cli: libnvram + $(CC) $(CLI_CFLAGS) -c -o cli.o cli.c + $(CC) -o $(CLI_FILENAME) $(CLI_LDFLAGS) $(CLI_OBJ) \ + $(LIB_FILENAME).$(LIB_VERMAJOR).$(LIB_VERMINOR) + +cli.o: cli.c + $(CC) $(CLI_CFLAGS) -c -o $@ $< + +libnvram: + $(CC) $(LIB_CFLAGS) -c -o crc.o crc.c + $(CC) $(LIB_CFLAGS) -c -o nvram.o nvram.c + $(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) \ + -o $(LIB_FILENAME).$(LIB_VERMAJOR).$(LIB_VERMINOR) $(LIB_OBJ) + +clean: + rm -f $(CLI_FILENAME) $(LIB_FILENAME)* *.o diff --git a/package/system/utils/nvram/src/cli.c b/package/system/utils/nvram/src/cli.c new file mode 100644 index 0000000000..66ef904885 --- /dev/null +++ b/package/system/utils/nvram/src/cli.c @@ -0,0 +1,246 @@ +/* + * Command line interface for libnvram + * + * Copyright 2009, Jo-Philipp Wich <xm@subsignal.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * + * The libnvram code is based on Broadcom code for Linux 2.4.x . + * + */ + +#include "nvram.h" + + +static nvram_handle_t * nvram_open_rdonly(void) +{ + const char *file = nvram_find_staging(); + + if( file == NULL ) + file = nvram_find_mtd(); + + if( file != NULL ) + return nvram_open(file, NVRAM_RO); + + return NULL; +} + +static nvram_handle_t * nvram_open_staging(void) +{ + if( nvram_find_staging() != NULL || nvram_to_staging() == 0 ) + return nvram_open(NVRAM_STAGING, NVRAM_RW); + + return NULL; +} + +static int do_show(nvram_handle_t *nvram) +{ + nvram_tuple_t *t; + int stat = 1; + + if( (t = nvram_getall(nvram)) != NULL ) + { + while( t ) + { + printf("%s=%s\n", t->name, t->value); + t = t->next; + } + + stat = 0; + } + + return stat; +} + +static int do_get(nvram_handle_t *nvram, const char *var) +{ + const char *val; + int stat = 1; + + if( (val = nvram_get(nvram, var)) != NULL ) + { + printf("%s\n", val); + stat = 0; + } + + return stat; +} + +static int do_unset(nvram_handle_t *nvram, const char *var) +{ + return nvram_unset(nvram, var); +} + +static int do_set(nvram_handle_t *nvram, const char *pair) +{ + char *val = strstr(pair, "="); + char var[strlen(pair)]; + int stat = 1; + + if( val != NULL ) + { + memset(var, 0, sizeof(var)); + strncpy(var, pair, (int)(val-pair)); + stat = nvram_set(nvram, var, (char *)(val + 1)); + } + + return stat; +} + +static int do_info(nvram_handle_t *nvram) +{ + nvram_header_t *hdr = nvram_header(nvram); + + /* CRC8 over the last 11 bytes of the header and data bytes */ + uint8_t crc = hndcrc8((unsigned char *) &hdr[0] + NVRAM_CRC_START_POSITION, + hdr->len - NVRAM_CRC_START_POSITION, 0xff); + + /* Show info */ + printf("Magic: 0x%08X\n", hdr->magic); + printf("Length: 0x%08X\n", hdr->len); + printf("Offset: 0x%08X\n", nvram->offset); + + printf("CRC8: 0x%02X (calculated: 0x%02X)\n", + hdr->crc_ver_init & 0xFF, crc); + + printf("Version: 0x%02X\n", (hdr->crc_ver_init >> 8) & 0xFF); + printf("SDRAM init: 0x%04X\n", (hdr->crc_ver_init >> 16) & 0xFFFF); + printf("SDRAM config: 0x%04X\n", hdr->config_refresh & 0xFFFF); + printf("SDRAM refresh: 0x%04X\n", (hdr->config_refresh >> 16) & 0xFFFF); + printf("NCDL values: 0x%08X\n\n", hdr->config_ncdl); + + printf("%i bytes used / %i bytes available (%.2f%%)\n", + hdr->len, NVRAM_SPACE - hdr->len, + (100.00 / (double)NVRAM_SPACE) * (double)hdr->len); + + return 0; +} + + +int main( int argc, const char *argv[] ) +{ + nvram_handle_t *nvram; + int commit = 0; + int write = 0; + int stat = 1; + int done = 0; + int i; + + /* Ugly... iterate over arguments to see whether we can expect a write */ + for( i = 1; i < argc; i++ ) + if( ( !strcmp(argv[i], "set") && ++i < argc ) || + ( !strcmp(argv[i], "unset") && ++i < argc ) || + !strcmp(argv[i], "commit") ) + { + write = 1; + break; + } + + + nvram = write ? nvram_open_staging() : nvram_open_rdonly(); + + if( nvram != NULL && argc > 1 ) + { + for( i = 1; i < argc; i++ ) + { + if( !strcmp(argv[i], "show") ) + { + stat = do_show(nvram); + done++; + } + else if( !strcmp(argv[i], "info") ) + { + stat = do_info(nvram); + done++; + } + else if( !strcmp(argv[i], "get") || !strcmp(argv[i], "unset") || !strcmp(argv[i], "set") ) + { + if( (i+1) < argc ) + { + switch(argv[i++][0]) + { + case 'g': + stat = do_get(nvram, argv[i]); + break; + + case 'u': + stat = do_unset(nvram, argv[i]); + break; + + case 's': + stat = do_set(nvram, argv[i]); + break; + } + done++; + } + else + { + fprintf(stderr, "Command '%s' requires an argument!\n", argv[i]); + done = 0; + break; + } + } + else if( !strcmp(argv[i], "commit") ) + { + commit = 1; + done++; + } + else + { + fprintf(stderr, "Unknown option '%s' !\n", argv[i]); + done = 0; + break; + } + } + + if( write ) + stat = nvram_commit(nvram); + + nvram_close(nvram); + + if( commit ) + stat = staging_to_nvram(); + } + + if( !nvram ) + { + fprintf(stderr, + "Could not open nvram! Possible reasons are:\n" + " - No device found (/proc not mounted or no nvram present)\n" + " - Insufficient permissions to open mtd device\n" + " - Insufficient memory to complete operation\n" + " - Memory mapping failed or not supported\n" + ); + + stat = 1; + } + else if( !done ) + { + fprintf(stderr, + "Usage:\n" + " nvram show\n" + " nvram info\n" + " nvram get variable\n" + " nvram set variable=value [set ...]\n" + " nvram unset variable [unset ...]\n" + " nvram commit\n" + ); + + stat = 1; + } + + return stat; +} diff --git a/package/system/utils/nvram/src/crc.c b/package/system/utils/nvram/src/crc.c new file mode 100644 index 0000000000..22a36652aa --- /dev/null +++ b/package/system/utils/nvram/src/crc.c @@ -0,0 +1,69 @@ +#include "nvram.h" + +/******************************************************************************* + * crc8 + * + * Computes a crc8 over the input data using the polynomial: + * + * x^8 + x^7 +x^6 + x^4 + x^2 + 1 + * + * The caller provides the initial value (either CRC8_INIT_VALUE + * or the previous returned value) to allow for processing of + * discontiguous blocks of data. When generating the CRC the + * caller is responsible for complementing the final return value + * and inserting it into the byte stream. When checking, a final + * return value of CRC8_GOOD_VALUE indicates a valid CRC. + * + * Reference: Dallas Semiconductor Application Note 27 + * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", + * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., + * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt + * + * **************************************************************************** + */ + +static const uint8_t crc8_table[256] = { + 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, + 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, + 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, + 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, + 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, + 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, + 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, + 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, + 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, + 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, + 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, + 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, + 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, + 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, + 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, + 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, + 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, + 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, + 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, + 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, + 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, + 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, + 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, + 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, + 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, + 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, + 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, + 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, + 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, + 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, + 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, + 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F +}; + +uint8_t hndcrc8 ( + uint8_t * pdata, /* pointer to array of data to process */ + uint32_t nbytes, /* number of input data bytes to process */ + uint8_t crc /* either CRC8_INIT_VALUE or previous return value */ +) { + while (nbytes-- > 0) + crc = crc8_table[(crc ^ *pdata++) & 0xff]; + + return crc; +} diff --git a/package/system/utils/nvram/src/nvram.c b/package/system/utils/nvram/src/nvram.c new file mode 100644 index 0000000000..a0bc006d15 --- /dev/null +++ b/package/system/utils/nvram/src/nvram.c @@ -0,0 +1,556 @@ +/* + * NVRAM variable manipulation (common) + * + * Copyright 2004, Broadcom Corporation + * Copyright 2009-2010, OpenWrt.org + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + */ + +#include "nvram.h" + +#define TRACE(msg) \ + printf("%s(%i) in %s(): %s\n", \ + __FILE__, __LINE__, __FUNCTION__, msg ? msg : "?") + +size_t nvram_erase_size = 0; + + +/* + * -- Helper functions -- + */ + +/* String hash */ +static uint32_t hash(const char *s) +{ + uint32_t hash = 0; + + while (*s) + hash = 31 * hash + *s++; + + return hash; +} + +/* Free all tuples. */ +static void _nvram_free(nvram_handle_t *h) +{ + uint32_t i; + nvram_tuple_t *t, *next; + + /* Free hash table */ + for (i = 0; i < NVRAM_ARRAYSIZE(h->nvram_hash); i++) { + for (t = h->nvram_hash[i]; t; t = next) { + next = t->next; + free(t); + } + h->nvram_hash[i] = NULL; + } + + /* Free dead table */ + for (t = h->nvram_dead; t; t = next) { + next = t->next; + free(t); + } + + h->nvram_dead = NULL; +} + +/* (Re)allocate NVRAM tuples. */ +static nvram_tuple_t * _nvram_realloc( nvram_handle_t *h, nvram_tuple_t *t, + const char *name, const char *value ) +{ + if ((strlen(value) + 1) > NVRAM_SPACE) + return NULL; + + if (!t) { + if (!(t = malloc(sizeof(nvram_tuple_t) + strlen(name) + 1))) + return NULL; + + /* Copy name */ + t->name = (char *) &t[1]; + strcpy(t->name, name); + + t->value = NULL; + } + + /* Copy value */ + if (!t->value || strcmp(t->value, value)) + { + if(!(t->value = (char *) realloc(t->value, strlen(value)+1))) + return NULL; + + strcpy(t->value, value); + t->value[strlen(value)] = '\0'; + } + + return t; +} + +/* (Re)initialize the hash table. */ +static int _nvram_rehash(nvram_handle_t *h) +{ + nvram_header_t *header = nvram_header(h); + char buf[] = "0xXXXXXXXX", *name, *value, *eq; + + /* (Re)initialize hash table */ + _nvram_free(h); + + /* Parse and set "name=value\0 ... \0\0" */ + name = (char *) &header[1]; + + for (; *name; name = value + strlen(value) + 1) { + if (!(eq = strchr(name, '='))) + break; + *eq = '\0'; + value = eq + 1; + nvram_set(h, name, value); + *eq = '='; + } + + /* Set special SDRAM parameters */ + if (!nvram_get(h, "sdram_init")) { + sprintf(buf, "0x%04X", (uint16_t)(header->crc_ver_init >> 16)); + nvram_set(h, "sdram_init", buf); + } + if (!nvram_get(h, "sdram_config")) { + sprintf(buf, "0x%04X", (uint16_t)(header->config_refresh & 0xffff)); + nvram_set(h, "sdram_config", buf); + } + if (!nvram_get(h, "sdram_refresh")) { + sprintf(buf, "0x%04X", + (uint16_t)((header->config_refresh >> 16) & 0xffff)); + nvram_set(h, "sdram_refresh", buf); + } + if (!nvram_get(h, "sdram_ncdl")) { + sprintf(buf, "0x%08X", header->config_ncdl); + nvram_set(h, "sdram_ncdl", buf); + } + + return 0; +} + + +/* + * -- Public functions -- + */ + +/* Get nvram header. */ +nvram_header_t * nvram_header(nvram_handle_t *h) +{ + return (nvram_header_t *) &h->mmap[h->offset]; +} + +/* Get the value of an NVRAM variable. */ +char * nvram_get(nvram_handle_t *h, const char *name) +{ + uint32_t i; + nvram_tuple_t *t; + char *value; + + if (!name) + return NULL; + + /* Hash the name */ + i = hash(name) % NVRAM_ARRAYSIZE(h->nvram_hash); + + /* Find the associated tuple in the hash table */ + for (t = h->nvram_hash[i]; t && strcmp(t->name, name); t = t->next); + + value = t ? t->value : NULL; + + return value; +} + +/* Set the value of an NVRAM variable. */ +int nvram_set(nvram_handle_t *h, const char *name, const char *value) +{ + uint32_t i; + nvram_tuple_t *t, *u, **prev; + + /* Hash the name */ + i = hash(name) % NVRAM_ARRAYSIZE(h->nvram_hash); + + /* Find the associated tuple in the hash table */ + for (prev = &h->nvram_hash[i], t = *prev; + t && strcmp(t->name, name); prev = &t->next, t = *prev); + + /* (Re)allocate tuple */ + if (!(u = _nvram_realloc(h, t, name, value))) + return -12; /* -ENOMEM */ + + /* Value reallocated */ + if (t && t == u) + return 0; + + /* Move old tuple to the dead table */ + if (t) { + *prev = t->next; + t->next = h->nvram_dead; + h->nvram_dead = t; + } + + /* Add new tuple to the hash table */ + u->next = h->nvram_hash[i]; + h->nvram_hash[i] = u; + + return 0; +} + +/* Unset the value of an NVRAM variable. */ +int nvram_unset(nvram_handle_t *h, const char *name) +{ + uint32_t i; + nvram_tuple_t *t, **prev; + + if (!name) + return 0; + + /* Hash the name */ + i = hash(name) % NVRAM_ARRAYSIZE(h->nvram_hash); + + /* Find the associated tuple in the hash table */ + for (prev = &h->nvram_hash[i], t = *prev; + t && strcmp(t->name, name); prev = &t->next, t = *prev); + + /* Move it to the dead table */ + if (t) { + *prev = t->next; + t->next = h->nvram_dead; + h->nvram_dead = t; + } + + return 0; +} + +/* Get all NVRAM variables. */ +nvram_tuple_t * nvram_getall(nvram_handle_t *h) +{ + int i; + nvram_tuple_t *t, *l, *x; + + l = NULL; + + for (i = 0; i < NVRAM_ARRAYSIZE(h->nvram_hash); i++) { + for (t = h->nvram_hash[i]; t; t = t->next) { + if( (x = (nvram_tuple_t *) malloc(sizeof(nvram_tuple_t))) != NULL ) + { + x->name = t->name; + x->value = t->value; + x->next = l; + l = x; + } + else + { + break; + } + } + } + + return l; +} + +/* Regenerate NVRAM. */ +int nvram_commit(nvram_handle_t *h) +{ + nvram_header_t *header = nvram_header(h); + char *init, *config, *refresh, *ncdl; + char *ptr, *end; + int i; + nvram_tuple_t *t; + nvram_header_t tmp; + uint8_t crc; + + /* Regenerate header */ + header->magic = NVRAM_MAGIC; + header->crc_ver_init = (NVRAM_VERSION << 8); + if (!(init = nvram_get(h, "sdram_init")) || + !(config = nvram_get(h, "sdram_config")) || + !(refresh = nvram_get(h, "sdram_refresh")) || + !(ncdl = nvram_get(h, "sdram_ncdl"))) { + header->crc_ver_init |= SDRAM_INIT << 16; + header->config_refresh = SDRAM_CONFIG; + header->config_refresh |= SDRAM_REFRESH << 16; + header->config_ncdl = 0; + } else { + header->crc_ver_init |= (strtoul(init, NULL, 0) & 0xffff) << 16; + header->config_refresh = strtoul(config, NULL, 0) & 0xffff; + header->config_refresh |= (strtoul(refresh, NULL, 0) & 0xffff) << 16; + header->config_ncdl = strtoul(ncdl, NULL, 0); + } + + /* Clear data area */ + ptr = (char *) header + sizeof(nvram_header_t); + memset(ptr, 0xFF, NVRAM_SPACE - sizeof(nvram_header_t)); + memset(&tmp, 0, sizeof(nvram_header_t)); + + /* Leave space for a double NUL at the end */ + end = (char *) header + NVRAM_SPACE - 2; + + /* Write out all tuples */ + for (i = 0; i < NVRAM_ARRAYSIZE(h->nvram_hash); i++) { + for (t = h->nvram_hash[i]; t; t = t->next) { + if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end) + break; + ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1; + } + } + + /* End with a double NULL and pad to 4 bytes */ + *ptr = '\0'; + ptr++; + + if( (int)ptr % 4 ) + memset(ptr, 0, 4 - ((int)ptr % 4)); + + ptr++; + + /* Set new length */ + header->len = NVRAM_ROUNDUP(ptr - (char *) header, 4); + + /* Little-endian CRC8 over the last 11 bytes of the header */ + tmp.crc_ver_init = header->crc_ver_init; + tmp.config_refresh = header->config_refresh; + tmp.config_ncdl = header->config_ncdl; + crc = hndcrc8((unsigned char *) &tmp + NVRAM_CRC_START_POSITION, + sizeof(nvram_header_t) - NVRAM_CRC_START_POSITION, 0xff); + + /* Continue CRC8 over data bytes */ + crc = hndcrc8((unsigned char *) &header[0] + sizeof(nvram_header_t), + header->len - sizeof(nvram_header_t), crc); + + /* Set new CRC8 */ + header->crc_ver_init |= crc; + + /* Write out */ + msync(h->mmap, h->length, MS_SYNC); + fsync(h->fd); + + /* Reinitialize hash table */ + return _nvram_rehash(h); +} + +/* Open NVRAM and obtain a handle. */ +nvram_handle_t * nvram_open(const char *file, int rdonly) +{ + int i; + int fd; + char *mtd = NULL; + nvram_handle_t *h; + nvram_header_t *header; + int offset = -1; + + /* If erase size or file are undefined then try to define them */ + if( (nvram_erase_size == 0) || (file == NULL) ) + { + /* Finding the mtd will set the appropriate erase size */ + if( (mtd = nvram_find_mtd()) == NULL || nvram_erase_size == 0 ) + { + free(mtd); + return NULL; + } + } + + if( (fd = open(file ? file : mtd, O_RDWR)) > -1 ) + { + char *mmap_area = (char *) mmap( + NULL, nvram_erase_size, PROT_READ | PROT_WRITE, + (( rdonly == NVRAM_RO ) ? MAP_PRIVATE : MAP_SHARED) | MAP_LOCKED, fd, 0); + + if( mmap_area != MAP_FAILED ) + { + for( i = 0; i <= ((nvram_erase_size - NVRAM_SPACE) / sizeof(uint32_t)); i++ ) + { + if( ((uint32_t *)mmap_area)[i] == NVRAM_MAGIC ) + { + offset = i * sizeof(uint32_t); + break; + } + } + + if( offset < 0 ) + { + free(mtd); + return NULL; + } + else if( (h = malloc(sizeof(nvram_handle_t))) != NULL ) + { + memset(h, 0, sizeof(nvram_handle_t)); + + h->fd = fd; + h->mmap = mmap_area; + h->length = nvram_erase_size; + h->offset = offset; + + header = nvram_header(h); + + if( header->magic == NVRAM_MAGIC ) + { + _nvram_rehash(h); + free(mtd); + return h; + } + else + { + munmap(h->mmap, h->length); + free(h); + } + } + } + } + + free(mtd); + return NULL; +} + +/* Close NVRAM and free memory. */ +int nvram_close(nvram_handle_t *h) +{ + _nvram_free(h); + munmap(h->mmap, h->length); + close(h->fd); + free(h); + + return 0; +} + +/* Determine NVRAM device node. */ +char * nvram_find_mtd(void) +{ + FILE *fp; + int i, esz; + char dev[PATH_MAX]; + char *path = NULL; + struct stat s; + int supported = 1; + + /* Refuse any operation on the WGT634U */ + if( (fp = fopen("/proc/diag/model", "r")) ) + { + if( fgets(dev, sizeof(dev), fp) && !strncmp(dev, "Netgear WGT634U", 15) ) + supported = 0; + + fclose(fp); + } + + if( supported && (fp = fopen("/proc/mtd", "r")) ) + { + while( fgets(dev, sizeof(dev), fp) ) + { + if( strstr(dev, "nvram") && sscanf(dev, "mtd%d: %08x", &i, &esz) ) + { + nvram_erase_size = esz; + + sprintf(dev, "/dev/mtdblock/%d", i); + if( stat(dev, &s) > -1 && (s.st_mode & S_IFBLK) ) + { + if( (path = (char *) malloc(strlen(dev)+1)) != NULL ) + { + strncpy(path, dev, strlen(dev)+1); + break; + } + } + else + { + sprintf(dev, "/dev/mtdblock%d", i); + if( stat(dev, &s) > -1 && (s.st_mode & S_IFBLK) ) + { + if( (path = (char *) malloc(strlen(dev)+1)) != NULL ) + { + strncpy(path, dev, strlen(dev)+1); + break; + } + } + } + } + } + fclose(fp); + } + + return path; +} + +/* Check NVRAM staging file. */ +char * nvram_find_staging(void) +{ + struct stat s; + + if( (stat(NVRAM_STAGING, &s) > -1) && (s.st_mode & S_IFREG) ) + { + return NVRAM_STAGING; + } + + return NULL; +} + +/* Copy NVRAM contents to staging file. */ +int nvram_to_staging(void) +{ + int fdmtd, fdstg, stat; + char *mtd = nvram_find_mtd(); + char buf[nvram_erase_size]; + + stat = -1; + + if( (mtd != NULL) && (nvram_erase_size > 0) ) + { + if( (fdmtd = open(mtd, O_RDONLY)) > -1 ) + { + if( read(fdmtd, buf, sizeof(buf)) == sizeof(buf) ) + { + if((fdstg = open(NVRAM_STAGING, O_WRONLY | O_CREAT, 0600)) > -1) + { + write(fdstg, buf, sizeof(buf)); + fsync(fdstg); + close(fdstg); + + stat = 0; + } + } + + close(fdmtd); + } + } + + free(mtd); + return stat; +} + +/* Copy staging file to NVRAM device. */ +int staging_to_nvram(void) +{ + int fdmtd, fdstg, stat; + char *mtd = nvram_find_mtd(); + char buf[nvram_erase_size]; + + stat = -1; + + if( (mtd != NULL) && (nvram_erase_size > 0) ) + { + if( (fdstg = open(NVRAM_STAGING, O_RDONLY)) > -1 ) + { + if( read(fdstg, buf, sizeof(buf)) == sizeof(buf) ) + { + if( (fdmtd = open(mtd, O_WRONLY | O_SYNC)) > -1 ) + { + write(fdmtd, buf, sizeof(buf)); + fsync(fdmtd); + close(fdmtd); + stat = 0; + } + } + + close(fdstg); + + if( !stat ) + stat = unlink(NVRAM_STAGING) ? 1 : 0; + } + } + + free(mtd); + return stat; +} diff --git a/package/system/utils/nvram/src/nvram.h b/package/system/utils/nvram/src/nvram.h new file mode 100644 index 0000000000..c72f67e9a8 --- /dev/null +++ b/package/system/utils/nvram/src/nvram.h @@ -0,0 +1,123 @@ +/* + * NVRAM variable manipulation + * + * Copyright 2007, Broadcom Corporation + * Copyright 2009, OpenWrt.org + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + */ + +#ifndef _nvram_h_ +#define _nvram_h_ + +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <linux/limits.h> + +#include "sdinitvals.h" + + +struct nvram_header { + uint32_t magic; + uint32_t len; + uint32_t crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ + uint32_t config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ + uint32_t config_ncdl; /* ncdl values for memc */ +} __attribute__((__packed__)); + +struct nvram_tuple { + char *name; + char *value; + struct nvram_tuple *next; +}; + +struct nvram_handle { + int fd; + char *mmap; + unsigned int length; + unsigned int offset; + struct nvram_tuple *nvram_hash[257]; + struct nvram_tuple *nvram_dead; +}; + +typedef struct nvram_handle nvram_handle_t; +typedef struct nvram_header nvram_header_t; +typedef struct nvram_tuple nvram_tuple_t; + + +/* Get nvram header. */ +nvram_header_t * nvram_header(nvram_handle_t *h); + +/* Set the value of an NVRAM variable */ +int nvram_set(nvram_handle_t *h, const char *name, const char *value); + +/* Get the value of an NVRAM variable. */ +char * nvram_get(nvram_handle_t *h, const char *name); + +/* Unset the value of an NVRAM variable. */ +int nvram_unset(nvram_handle_t *h, const char *name); + +/* Get all NVRAM variables. */ +nvram_tuple_t * nvram_getall(nvram_handle_t *h); + +/* Regenerate NVRAM. */ +int nvram_commit(nvram_handle_t *h); + +/* Open NVRAM and obtain a handle. */ +nvram_handle_t * nvram_open(const char *file, int rdonly); + +/* Close NVRAM and free memory. */ +int nvram_close(nvram_handle_t *h); + +/* Get the value of an NVRAM variable in a safe way, use "" instead of NULL. */ +#define nvram_safe_get(h, name) (nvram_get(h, name) ? : "") + +/* Computes a crc8 over the input data. */ +uint8_t hndcrc8 (uint8_t * pdata, uint32_t nbytes, uint8_t crc); + +/* Returns the crc value of the nvram. */ +uint8_t nvram_calc_crc(nvram_header_t * nvh); + +/* Determine NVRAM device node. */ +char * nvram_find_mtd(void); + +/* Copy NVRAM contents to staging file. */ +int nvram_to_staging(void); + +/* Copy staging file to NVRAM device. */ +int staging_to_nvram(void); + +/* Check NVRAM staging file. */ +char * nvram_find_staging(void); + + +/* Staging file for NVRAM */ +#define NVRAM_STAGING "/tmp/.nvram" +#define NVRAM_RO 1 +#define NVRAM_RW 0 + +/* Helper macros */ +#define NVRAM_ARRAYSIZE(a) sizeof(a)/sizeof(a[0]) +#define NVRAM_ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) + +/* NVRAM constants */ +#define NVRAM_SPACE 0x8000 +#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ +#define NVRAM_VERSION 1 + +#define NVRAM_CRC_START_POSITION 9 /* magic, len, crc8 to be skipped */ + + +#endif /* _nvram_h_ */ diff --git a/package/system/utils/nvram/src/sdinitvals.h b/package/system/utils/nvram/src/sdinitvals.h new file mode 100644 index 0000000000..5a289adece --- /dev/null +++ b/package/system/utils/nvram/src/sdinitvals.h @@ -0,0 +1,30 @@ +/* + * SDRAM init values + * + * Copyright 2007, Broadcom Corporation + * Copyright 2009, OpenWrt.org + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + */ + +#ifndef _sdinitvals_h_ +#define _sdinitvals_h_ + +/* SDRAM refresh control (refresh) register bits */ +#define SDRAM_REF(p) (((p)&0xff) | SDRAM_REF_EN) /* Refresh period */ +#define SDRAM_REF_EN 0x8000 /* Writing 1 enables periodic refresh */ + +/* SDRAM Core default Init values (OCP ID 0x803) */ +#define MEM4MX16X2 0x419 /* 16 MB */ + +#define SDRAM_INIT MEM4MX16X2 +#define SDRAM_BURSTFULL 0x0000 /* Use full page bursts */ +#define SDRAM_CONFIG SDRAM_BURSTFULL +#define SDRAM_REFRESH SDRAM_REF(0x40) + +#endif /* _sdinitvals_h_ */ diff --git a/package/system/utils/robocfg/Makefile b/package/system/utils/robocfg/Makefile new file mode 100644 index 0000000000..4bc72f51db --- /dev/null +++ b/package/system/utils/robocfg/Makefile @@ -0,0 +1,39 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=robocfg +PKG_VERSION:=0.01 +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/robocfg + +include $(INCLUDE_DIR)/package.mk + +define Package/robocfg + SECTION:=utils + CATEGORY:=Utilities + TITLE:=BCM5325E/536x switch configuration utility +endef + +define Package/robocfg/description + This package contains an utility for configuring the Broadcom BCM5325E/536x + based switches. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Package/robocfg/install + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/robocfg $(1)/sbin/ +endef + +$(eval $(call BuildPackage,robocfg)) diff --git a/package/system/utils/robocfg/src/Makefile b/package/system/utils/robocfg/src/Makefile new file mode 100644 index 0000000000..e11acb020a --- /dev/null +++ b/package/system/utils/robocfg/src/Makefile @@ -0,0 +1,11 @@ + +all: robocfg + +%.o: %.c + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $^ + +robocfg: robocfg.o + $(CC) -o $@ $^ + +clean: + rm -f *.o robocfg diff --git a/package/system/utils/robocfg/src/etc53xx.h b/package/system/utils/robocfg/src/etc53xx.h new file mode 100644 index 0000000000..d5b1310cb6 --- /dev/null +++ b/package/system/utils/robocfg/src/etc53xx.h @@ -0,0 +1,619 @@ +/* + * Broadcom Home Gateway Reference Design + * BCM53xx Register definitions + * + * Copyright 2004, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + */ + +#ifndef __BCM535M_H_ +#define __BCM535M_H_ + +/* ROBO embedded device type */ +#define ROBO_DEV_5380 1 +#define ROBO_DEV_5365 2 +#define ROBO_DEV_5350 3 + +/* BCM5325m GLOBAL PAGE REGISTER MAP */ +#ifndef _CFE_ +#pragma pack(1) +#endif + +/* BCM5325m Serial Management Port (SMP) Page offsets */ +#define ROBO_CTRL_PAGE 0x00 /* Control registers */ +#define ROBO_STAT_PAGE 0x01 /* Status register */ +#define ROBO_MGMT_PAGE 0x02 /* Management Mode registers */ +#define ROBO_MIB_AC_PAGE 0x03 /* MIB Autocast registers */ +#define ROBO_ARLCTRL_PAGE 0x04 /* ARL Control Registers */ +#define ROBO_ARLIO_PAGE 0x05 /* ARL Access Registers */ +#define ROBO_FRAMEBUF_PAGE 0x06 /* Management frame access registers */ +#define ROBO_MEM_ACCESS_PAGE 0x08 /* Memory access registers */ + +/* PHY Registers */ +#define ROBO_PORT0_MII_PAGE 0x10 /* Port 0 MII Registers */ +#define ROBO_PORT1_MII_PAGE 0x11 /* Port 1 MII Registers */ +#define ROBO_PORT2_MII_PAGE 0x12 /* Port 2 MII Registers */ +#define ROBO_PORT3_MII_PAGE 0x13 /* Port 3 MII Registers */ +#define ROBO_PORT4_MII_PAGE 0x14 /* Port 4 MII Registers */ +/* (start) registers only for BCM5380 */ +#define ROBO_PORT5_MII_PAGE 0x15 /* Port 5 MII Registers */ +#define ROBO_PORT6_MII_PAGE 0x16 /* Port 6 MII Registers */ +#define ROBO_PORT7_MII_PAGE 0x17 /* Port 7 MII Registers */ +/* (end) registers only for BCM5380 */ +#define ROBO_IM_PORT_PAGE 0x18 /* Inverse MII Port (to EMAC) */ +#define ROBO_ALL_PORT_PAGE 0x19 /* All ports MII Registers (broadcast)*/ + +/* MAC Statistics registers */ +#define ROBO_PORT0_MIB_PAGE 0x20 /* Port 0 10/100 MIB Statistics */ +#define ROBO_PORT1_MIB_PAGE 0x21 /* Port 1 10/100 MIB Statistics */ +#define ROBO_PORT2_MIB_PAGE 0x22 /* Port 2 10/100 MIB Statistics */ +#define ROBO_PORT3_MIB_PAGE 0x23 /* Port 3 10/100 MIB Statistics */ +#define ROBO_PORT4_MIB_PAGE 0x24 /* Port 4 10/100 MIB Statistics */ +/* (start) registers only for BCM5380 */ +#define ROBO_PORT5_MIB_PAGE 0x25 /* Port 5 10/100 MIB Statistics */ +#define ROBO_PORT6_MIB_PAGE 0x26 /* Port 6 10/100 MIB Statistics */ +#define ROBO_PORT7_MIB_PAGE 0x27 /* Port 7 10/100 MIB Statistics */ +/* (end) registers only for BCM5380 */ +#define ROBO_IM_PORT_MIB_PAGE 0x28 /* Inverse MII Port MIB Statistics */ + +/* Quality of Service (QoS) Registers */ +#define ROBO_QOS_PAGE 0x30 /* QoS Registers */ + +/* VLAN Registers */ +#define ROBO_VLAN_PAGE 0x34 /* VLAN Registers */ + +/* Note SPI Data/IO Registers not used */ +#define ROBO_SPI_DATA_IO_0_PAGE 0xf0 /* SPI Data I/O 0 */ +#define ROBO_SPI_DATA_IO_1_PAGE 0xf1 /* SPI Data I/O 1 */ +#define ROBO_SPI_DATA_IO_2_PAGE 0xf2 /* SPI Data I/O 2 */ +#define ROBO_SPI_DATA_IO_3_PAGE 0xf3 /* SPI Data I/O 3 */ +#define ROBO_SPI_DATA_IO_4_PAGE 0xf4 /* SPI Data I/O 4 */ +#define ROBO_SPI_DATA_IO_5_PAGE 0xf5 /* SPI Data I/O 5 */ +#define ROBO_SPI_DATA_IO_6_PAGE 0xf6 /* SPI Data I/O 6 */ +#define ROBO_SPI_DATA_IO_7_PAGE 0xf7 /* SPI Data I/O 7 */ + +#define ROBO_SPI_STATUS_PAGE 0xfe /* SPI Status Registers */ +#define ROBO_PAGE_PAGE 0xff /* Page Registers */ + + +/* BCM5325m CONTROL PAGE (0x00) REGISTER MAP : 8bit (byte) registers */ +typedef struct _ROBO_PORT_CTRL_STRUC +{ + unsigned char rx_disable:1; /* rx disable */ + unsigned char tx_disable:1; /* tx disable */ + unsigned char rsvd:3; /* reserved */ + unsigned char stp_state:3; /* spanning tree state */ +} ROBO_PORT_CTRL_STRUC; + +#define ROBO_PORT0_CTRL 0x00 /* 10/100 Port 0 Control */ +#define ROBO_PORT1_CTRL 0x01 /* 10/100 Port 1 Control */ +#define ROBO_PORT2_CTRL 0x02 /* 10/100 Port 2 Control */ +#define ROBO_PORT3_CTRL 0x03 /* 10/100 Port 3 Control */ +#define ROBO_PORT4_CTRL 0x04 /* 10/100 Port 4 Control */ +/* (start) registers only for BCM5380 */ +#define ROBO_PORT5_CTRL 0x05 /* 10/100 Port 5 Control */ +#define ROBO_PORT6_CTRL 0x06 /* 10/100 Port 6 Control */ +#define ROBO_PORT7_CTRL 0x07 /* 10/100 Port 7 Control */ +/* (end) registers only for BCM5380 */ +#define ROBO_IM_PORT_CTRL 0x08 /* 10/100 Port 8 Control */ +#define ROBO_SMP_CTRL 0x0a /* SMP Control register */ +#define ROBO_SWITCH_MODE 0x0b /* Switch Mode Control */ +#define ROBO_PORT_OVERRIDE_CTRL 0x0e /* Port state override */ +#define ROBO_PORT_OVERRIDE_RVMII (1<<4) /* Bit 4 enables RvMII */ +#define ROBO_PD_MODE_CTRL 0x0f /* Power-down mode control */ +#define ROBO_IP_MULTICAST_CTRL 0x21 /* IP Multicast control */ + +/* BCM5325m STATUS PAGE (0x01) REGISTER MAP : 16bit/48bit registers */ +#define ROBO_HALF_DUPLEX 0 +#define ROBO_FULL_DUPLEX 1 + +#define ROBO_LINK_STAT_SUMMARY 0x00 /* Link Status Summary: 16bit */ +#define ROBO_LINK_STAT_CHANGE 0x02 /* Link Status Change: 16bit */ +#define ROBO_SPEED_STAT_SUMMARY 0x04 /* Port Speed Summary: 16bit*/ +#define ROBO_DUPLEX_STAT_SUMMARY 0x06 /* Duplex Status Summary: 16bit */ +#define ROBO_PAUSE_STAT_SUMMARY 0x08 /* PAUSE Status Summary: 16bit */ +#define ROBO_SOURCE_ADDR_CHANGE 0x0C /* Source Address Change: 16bit */ +#define ROBO_LSA_PORT0 0x10 /* Last Source Addr, Port 0: 48bits*/ +#define ROBO_LSA_PORT1 0x16 /* Last Source Addr, Port 1: 48bits*/ +#define ROBO_LSA_PORT2 0x1c /* Last Source Addr, Port 2: 48bits*/ +#define ROBO_LSA_PORT3 0x22 /* Last Source Addr, Port 3: 48bits*/ +#define ROBO_LSA_PORT4 0x28 /* Last Source Addr, Port 4: 48bits*/ +#define ROBO_LSA_IM_PORT 0x40 /* Last Source Addr, IM Port: 48bits*/ + +/* BCM5325m MANAGEMENT MODE REGISTERS (0x02) REGISTER MAP: 8/48 bit regs*/ +typedef struct _ROBO_GLOBAL_CONFIG_STRUC +{ + unsigned char resetMIB:1; /* reset MIB counters */ + unsigned char rxBPDU:1; /* receive BDPU enable */ + unsigned char rsvd1:2; /* reserved */ + unsigned char MIBacHdrCtrl:1; /* MIB autocast header control */ + unsigned char MIBac:1; /* MIB autocast enable */ + unsigned char frameMgmtPort:2; /* frame management port */ +} ROBO_GLOBAL_CONFIG_STRUC; +#define ROBO_GLOBAL_CONFIG 0x00 /* Global Management Config: 8bit*/ +#define ROBO_MGMT_PORT_ID 0x02 /* Management Port ID: 8bit*/ +#define ROBO_RMON_MIB_STEER 0x04 /* RMON Mib Steering: 16bit */ +#define ROBO_MIB_MODE_SELECT 0x04 /* MIB Mode select: 16bit (BCM5350) */ +#define ROBO_AGE_TIMER_CTRL 0x06 /* Age time control: 32bit */ +#define ROBO_MIRROR_CAP_CTRL 0x10 /* Mirror Capture : 16bit */ +#define ROBO_MIRROR_ING_CTRL 0x12 /* Mirror Ingress Control: 16bit */ +#define ROBO_MIRROR_ING_DIV_CTRL 0x14 /* Mirror Ingress Divider: 16bit */ +#define ROBO_MIRROR_ING_MAC_ADDR 0x16 /* Ingress Mirror MAC Addr: 48bit*/ +#define ROBO_MIRROR_EGR_CTRL 0x1c /* Mirror Egress Control: 16bit */ +#define ROBO_MIRROR_EGR_DIV_CTRL 0x1e /* Mirror Egress Divider: 16bit */ +#define ROBO_MIRROR_EGR_MAC_ADDR 0x20 /* Egress Mirror MAC Addr: 48bit*/ + +/* BCM5325m MIB AUTOCAST REGISTERS (0x03) REGISTER MAP: 8/16/48 bit regs */ +#define ROBO_MIB_AC_PORT 0x00 /* MIB Autocast Port: 16bit */ +#define ROBO_MIB_AC_HDR_PTR 0x02 /* MIB Autocast Header pointer:16bit*/ +#define ROBO_MIB_AC_HDR_LEN 0x04 /* MIB Autocast Header Len: 16bit */ +#define ROBO_MIB_AC_DA 0x06 /* MIB Autocast DA: 48bit */ +#define ROBO_MIB_AC_SA 0x0c /* MIB Autocast SA: 48bit */ +#define ROBO_MIB_AC_TYPE 0x12 /* MIB Autocast Type: 16bit */ +#define ROBO_MIB_AC_RATE 0x14 /* MIB Autocast Rate: 8bit */ +#define ROBO_GET_AC_RATE(secs) ((secs)*10) +#define ROBO_AC_RATE_MAX 0xff +#define ROBO_AC_RATE_DEFAULT 0x64 /* 10 secs */ +typedef struct _ROBO_MIB_AC_STRUCT +{ + unsigned char opcode:4; /* Tx MIB Autocast opcode */ + unsigned char portno:4; /* zero-based port no. */ + unsigned char portstate:8; /* port state */ + unsigned long long TxOctets; + unsigned int TxDropPkts; + unsigned int rsvd; + unsigned int TxBroadcastPkts; + unsigned int TxMulticastPkts; + unsigned int TxUnicastPkts; + unsigned int TxCollisions; + unsigned int TxSingleCollision; + unsigned int TxMultiCollision; + unsigned int TxDeferredTransmit; + unsigned int TxLateCollision; + unsigned int TxExcessiveCollision; + unsigned int TxFrameInDiscards; + unsigned int TxPausePkts; + unsigned int rsvd1[2]; + unsigned long long RxOctets; + unsigned int RxUndersizePkts; + unsigned int RxPausePkts; + unsigned int RxPkts64Octets; + unsigned int RxPkts64to127Octets; + unsigned int RxPkts128to255Octets; + unsigned int RxPkts256to511Octets; + unsigned int RxPkts512to1023Octets; + unsigned int RxPkts1024to1522Octets; + unsigned int RxOversizePkts; + unsigned int RxJabbers; + unsigned int RxAlignmentErrors; + unsigned int RxFCSErrors; + unsigned long long RxGoodOctets; + unsigned int RxDropPkts; + unsigned int RxUnicastPkts; + unsigned int RxMulticastPkts; + unsigned int RxBroadcastPkts; + unsigned int RxSAChanges; + unsigned int RxFragments; + unsigned int RxExcessSizeDisc; + unsigned int RxSymbolError; +} ROBO_MIB_AC_STRUCT; + +/* BCM5325m ARL CONTROL REGISTERS (0x04) REGISTER MAP: 8/16/48/64 bit regs */ +#define ROBO_ARL_CONFIG 0x00 /* ARL Global Configuration: 8bit*/ +#define ROBO_BPDU_MC_ADDR_REG 0x04 /* BPDU Multicast Address Reg:64bit*/ +#define ROBO_MULTIPORT_ADDR_1 0x10 /* Multiport Address 1: 48 bits*/ +#define ROBO_MULTIPORT_VECTOR_1 0x16 /* Multiport Vector 1: 16 bits */ +#define ROBO_MULTIPORT_ADDR_2 0x20 /* Multiport Address 2: 48 bits*/ +#define ROBO_MULTIPORT_VECTOR_2 0x26 /* Multiport Vector 2: 16 bits */ +#define ROBO_SECURE_SRC_PORT_MASK 0x30 /* Secure Source Port Mask: 16 bits*/ +#define ROBO_SECURE_DST_PORT_MASK 0x32 /* Secure Dest Port Mask: 16 bits */ + + +/* BCM5325m ARL IO REGISTERS (0x05) REGISTER MAP: 8/16/48/64 bit regs */ +#define ARL_TABLE_WRITE 0 /* for read/write state in control reg */ +#define ARL_TABLE_READ 1 /* for read/write state in control reg */ +#ifdef BCM5380 +#define ARL_VID_BYTES 2 /* number of bytes for VID */ +#else +#define ARL_VID_BYTES 1 /* number of bytes for VID */ +#endif +typedef struct _ROBO_ARL_RW_CTRL_STRUC +{ + unsigned char ARLrw:1; /* ARL read/write (1=read) */ + unsigned char rsvd:6; /* reserved */ + unsigned char ARLStart:1; /* ARL start/done (1=start) */ +} ROBO_ARL_RW_CTRL_STRUC; +typedef struct _ROBO_ARL_SEARCH_CTRL_STRUC +{ + unsigned char valid:1; /* ARL search result valid */ + unsigned char rsvd:6; /* reserved */ + unsigned char ARLStart:1; /* ARL start/done (1=start) */ +} ROBO_ARL_SEARCH_CTRL_STRUC; +typedef struct _ROBO_ARL_ENTRY_CTRL_STRUC +{ + unsigned char portID:4; /* port id */ + unsigned char chipID:2; /* chip id */ + unsigned char rsvd:5; /* reserved */ + unsigned char prio:2; /* priority */ + unsigned char age:1; /* age */ + unsigned char staticEn:1; /* static */ + unsigned char valid:1; /* valid */ +} ROBO_ARL_ENTRY_CTRL_STRUC; +typedef struct _ROBO_ARL_SEARCH_RESULT_CTRL_STRUC +{ + unsigned char portID:4; /* port id */ + unsigned char rsvd:1; /* reserved */ + unsigned char vid:8; /* vlan id */ + unsigned char age:1; /* age */ + unsigned char staticEn:1; /* static */ + unsigned char valid:1; /* valid */ +} ROBO_ARL_SEARCH_RESULT_CTRL_STRUC; +typedef struct _ROBO_ARL_ENTRY_MAC_STRUC +{ + unsigned char macBytes[6]; /* MAC address */ +} ROBO_ARL_ENTRY_MAC_STRUC; + +typedef struct _ROBO_ARL_ENTRY_STRUC +{ + ROBO_ARL_ENTRY_MAC_STRUC mac; /* MAC address */ + ROBO_ARL_ENTRY_CTRL_STRUC ctrl; /* control bits */ +} ROBO_ARL_ENTRY_STRUC; + +typedef struct _ROBO_ARL_SEARCH_RESULT_STRUC +{ + ROBO_ARL_ENTRY_MAC_STRUC mac; /* MAC address */ + ROBO_ARL_SEARCH_RESULT_CTRL_STRUC ctrl; /* control bits */ +} ROBO_ARL_SEARCH_RESULT_STRUC; + +/* multicast versions of ARL entry structs */ +typedef struct _ROBO_ARL_ENTRY_MCAST_CTRL_STRUC +{ + unsigned int portMask:12;/* multicast port mask */ + unsigned char prio:1; /* priority */ + unsigned char gigPort:1; /* gigabit port 1 mask */ + unsigned char staticEn:1; /* static */ + unsigned char valid:1; /* valid */ +} ROBO_ARL_ENTRY_MCAST_CTRL_STRUC; +typedef struct _ROBO_ARL_SEARCH_RESULT_MCAST_CTRL_STRUC +{ + unsigned int portMask:13; /* multicast port mask */ + unsigned char age:1; /* age */ + unsigned char staticEn:1; /* static */ + unsigned char valid:1; /* valid */ +} ROBO_ARL_SEARCH_RESULT_MCAST_CTRL_STRUC; +/* BCM5350 extension register */ +typedef struct _ROBO_ARL_SEARCH_RESULT_EXTENSION +{ + unsigned int prio:2; /* priority */ + unsigned int portMask:1; /* MSB (MII) of port mask for multicast */ + unsigned int reserved:5; +} ROBO_ARL_SEARCH_RESULT_EXTENSION; + +typedef struct _ROBO_ARL_ENTRY_MCAST_STRUC +{ + ROBO_ARL_ENTRY_MAC_STRUC mac; /* MAC address */ + ROBO_ARL_ENTRY_MCAST_CTRL_STRUC ctrl; /* control bits */ +} ROBO_ARL_ENTRY_MCAST_STRUC; +typedef struct _ROBO_ARL_SEARCH_RESULT_MCAST_STRUC +{ + ROBO_ARL_ENTRY_MAC_STRUC mac; /* MAC address */ + ROBO_ARL_SEARCH_RESULT_MCAST_CTRL_STRUC ctrl; /* control bits */ +} ROBO_ARL_SEARCH_RESULT_MCAST_STRUC; + +#define ROBO_ARL_RW_CTRL 0x00 /* ARL Read/Write Control : 8bit */ +#define ROBO_ARL_MAC_ADDR_IDX 0x02 /* MAC Address Index: 48bit */ +#define ROBO_ARL_VID_TABLE_IDX 0x08 /* VID Table Address Index: 8bit */ +#define ROBO_ARL_ENTRY0 0x10 /* ARL Entry 0 : 64 bit */ +#define ROBO_ARL_ENTRY1 0x18 /* ARL Entry 1 : 64 bit */ +#define ROBO_ARL_SEARCH_CTRL 0x20 /* ARL Search Control: 8bit */ +#define ROBO_ARL_SEARCH_ADDR 0x22 /* ARL Search Address: 16bit */ +#define ROBO_ARL_SEARCH_RESULT 0x24 /* ARL Search Result: 64bit */ +#define ROBO_ARL_SEARCH_RESULT_EXT 0x2c /* ARL Search Result Extension (5350): 8bit */ +#define ROBO_ARL_VID_ENTRY0 0x30 /* ARL VID Entry 0: 64bit */ +#define ROBO_ARL_VID_ENTRY1 0x32 /* ARL VID Entry 1: 64bit */ + +/* BCM5325m MANAGEMENT FRAME REGISTERS (0x6) REGISTER MAP: 8/16 bit regs */ +#define ROBO_MGMT_FRAME_RD_DATA 0x00 /* Management Frame Read Data :8bit*/ +#define ROBO_MGMT_FRAME_WR_DATA 0x01 /* Management Frame Write Data:8bit*/ +#define ROBO_MGMT_FRAME_WR_CTRL 0x02 /* Write Control: 16bit */ +#define ROBO_MGMT_FRAME_RD_STAT 0x04 /* Read Status: 16bit */ + +/* BCM5325m MEMORY ACCESS REGISTERS (Page 0x08) REGISTER MAP: 32 bit regs */ +#define MEM_TABLE_READ 1 /* for read/write state in mem access reg */ +#define MEM_TABLE_WRITE 0 /* for read/write state in mem access reg */ +#define MEM_TABLE_ACCESS_START 1 /* for mem access read/write start */ +#define MEM_TABLE_ACCESS_DONE 0 /* for mem access read/write done */ +#define VLAN_TABLE_ADDR 0x3800 /* BCM5380 only */ +#ifdef BCM5380 +#define NUM_ARL_TABLE_ENTRIES 4096 /* number of entries in ARL table */ +#define NUM_VLAN_TABLE_ENTRIES 2048 /* number of entries in VLAN table */ +#define ARL_TABLE_ADDR 0 /* offset of ARL table start */ +#else +#define NUM_ARL_TABLE_ENTRIES 2048 /* number of entries in ARL table */ +#define NUM_VLAN_TABLE_ENTRIES 256 /* number of entries in VLAN table */ +#define ARL_TABLE_ADDR 0x3800 /* offset of ARL table start */ +/* corresponding values for 5350 */ +#define NUM_ARL_TABLE_ENTRIES_5350 1024 /* number of entries in ARL table (5350) */ +#define NUM_VLAN_TABLE_ENTRIES_5350 16 /* number of entries in VLAN table */ +#define ARL_TABLE_ADDR_5350 0x1c00 /* offset of ARL table start (5350) */ +#endif +typedef struct _ROBO_MEM_ACCESS_CTRL_STRUC +{ + unsigned int memAddr:14; /* 64-bit memory address */ + unsigned char rsvd:4; /* reserved */ + unsigned char readEn:1; /* read enable (0 == write) */ + unsigned char startDone:1;/* memory access start/done */ + unsigned int rsvd1:12; /* reserved */ +} ROBO_MEM_ACCESS_CTRL_STRUC; +typedef struct _ROBO_MEM_ACCESS_DATA_STRUC +{ + unsigned int memData[2]; /* 64-bit data */ + unsigned short rsvd; /* reserved */ +} ROBO_MEM_ACCESS_DATA_STRUC; + +#ifdef BCM5380 +typedef struct _ROBO_ARL_TABLE_DATA_STRUC +{ + unsigned char MACaddr[6]; /* MAC addr */ + unsigned int portID:4; /* port ID */ + unsigned int chipID:2; /* chip ID */ + unsigned int rsvd:6; /* reserved */ + unsigned int highPrio:1; /* high priority address */ + unsigned int age:1; /* entry accessed/learned since ageing process */ + unsigned int staticAddr:1;/* entry is static */ + unsigned int valid:1; /* entry is valid */ + unsigned int vid:12; /* vlan id */ + unsigned int rsvd2:4; /* reserved */ +} ROBO_ARL_TABLE_DATA_STRUC; +#else +typedef struct _ROBO_ARL_TABLE_DATA_STRUC +{ + unsigned char MACaddr[6]; /* MAC addr */ + unsigned int portID:4; /* port ID */ + unsigned int chipID:2; /* chip ID */ + unsigned int rsvd:7; /* reserved */ + unsigned int age:1; /* entry accessed/learned since ageing process */ + unsigned int staticAddr:1;/* entry is static */ + unsigned int valid:1; /* entry is valid */ +} ROBO_ARL_TABLE_DATA_STRUC; +#endif + +/* multicast format*/ +typedef struct _ROBO_ARL_TABLE_MCAST_DATA_STRUC +{ + unsigned char MACaddr[6]; /* MAC addr */ + unsigned int portMask:12;/* multicast port mask */ + unsigned char prio:1; /* priority */ + unsigned char gigPort:1; /* gigabit port 1 mask */ + unsigned char staticEn:1; /* static */ + unsigned char valid:1; /* valid */ + unsigned int vid:12; /* vlan id */ + unsigned int rsvd2:4; /* reserved */ +} ROBO_ARL_TABLE_MCAST_DATA_STRUC; +#define ROBO_MEM_ACCESS_CTRL 0x00 /* Memory Read/Write Control :32bit*/ +#define ROBO_MEM_ACCESS_DATA 0x04 /* Memory Read/Write Data:64bit*/ + +/* BCM5325m SWITCH PORT (0x10-18) REGISTER MAP: 8/16 bit regs */ +typedef struct _ROBO_MII_CTRL_STRUC +{ + unsigned char rsvd:8; /* reserved */ + unsigned char duplex:1; /* duplex mode */ + unsigned char restartAN:1;/* restart auto-negotiation */ + unsigned char rsvd1:1; /* reserved */ + unsigned char powerDown:1;/* power down */ + unsigned char ANenable:1; /* auto-negotiation enable */ + unsigned char speed:1; /* forced speed selection */ + unsigned char loopback:1; /* loopback */ + unsigned char reset:1; /* reset */ +} ROBO_MII_CTRL_STRUC; +typedef struct _ROBO_MII_AN_ADVERT_STRUC +{ + unsigned char selector:5; /* advertise selector field */ + unsigned char T10BaseT:1; /* advertise 10BaseT */ + unsigned char T10BaseTFull:1; /* advertise 10BaseT, full duplex */ + unsigned char T100BaseX:1; /* advertise 100BaseX */ + unsigned char T100BaseXFull:1;/* advertise 100BaseX full duplex */ + unsigned char noT4:1; /* do not advertise T4 */ + unsigned char pause:1; /* advertise pause for full duplex */ + unsigned char rsvd:2; /* reserved */ + unsigned char remoteFault:1; /* transmit remote fault */ + unsigned char rsvd1:1; /* reserved */ + unsigned char nextPage:1; /* nex page operation supported */ +} ROBO_MII_AN_ADVERT_STRUC; +#define ROBO_MII_CTRL 0x00 /* Port MII Control */ +#define ROBO_MII_STAT 0x02 /* Port MII Status */ +/* Fields of link status register */ +#define ROBO_MII_STAT_JABBER (1<<1) /* Jabber detected */ +#define ROBO_MII_STAT_LINK (1<<2) /* Link status */ + +#define ROBO_MII_PHYID_HI 0x04 /* Port PHY ID High */ +#define ROBO_MII_PHYID_LO 0x06 /* Port PHY ID Low */ +#define ROBO_MII_ANA_REG 0x08 /* MII Auto-Neg Advertisement */ +#define ROBO_MII_ANP_REG 0x0a /* MII Auto-Neg Partner Ability */ +#define ROBO_MII_AN_EXP_REG 0x0c /* MII Auto-Neg Expansion */ +#define ROBO_MII_AN_NP_REG 0x0e /* MII next page */ +#define ROBO_MII_ANP_NP_REG 0x10 /* MII Partner next page */ +#define ROBO_MII_100BX_AUX_CTRL 0x20 /* 100BASE-X Auxiliary Control */ +#define ROBO_MII_100BX_AUX_STAT 0x22 /* 100BASE-X Auxiliary Status */ +#define ROBO_MII_100BX_RCV_ERR_CTR 0x24 /* 100BASE-X Receive Error Ctr */ +#define ROBO_MII_100BX_RCV_FS_ERR 0x26 /* 100BASE-X Rcv False Sense Ctr */ +#define ROBO_MII_AUX_CTRL 0x30 /* Auxiliary Control/Status */ +/* Fields of Auxiliary control register */ +#define ROBO_MII_AUX_CTRL_FD (1<<0) /* Full duplex link detected*/ +#define ROBO_MII_AUX_CTRL_SP100 (1<<1) /* Speed 100 indication */ +#define ROBO_MII_AUX_STATUS 0x32 /* Aux Status Summary */ +#define ROBO_MII_CONN_STATUS 0x34 /* Aux Connection Status */ +#define ROBO_MII_AUX_MODE2 0x36 /* Aux Mode 2 */ +#define ROBO_MII_AUX_ERR_STATUS 0x38 /* Aux Error and General Status */ +#define ROBO_MII_AUX_MULTI_PHY 0x3c /* Aux Multiple PHY Register*/ +#define ROBO_MII_BROADCOM_TEST 0x3e /* Broadcom Test Register */ + + +/* BCM5325m PORT MIB REGISTERS (Pages 0x20-0x24,0x28) REGISTER MAP: 64/32 */ +/* Tranmit Statistics */ +#define ROBO_MIB_TX_OCTETS 0x00 /* 64b: TxOctets */ +#define ROBO_MIB_TX_DROP_PKTS 0x08 /* 32b: TxDropPkts */ +#define ROBO_MIB_TX_BC_PKTS 0x10 /* 32b: TxBroadcastPkts */ +#define ROBO_MIB_TX_MC_PKTS 0x14 /* 32b: TxMulticastPkts */ +#define ROBO_MIB_TX_UC_PKTS 0x18 /* 32b: TxUnicastPkts */ +#define ROBO_MIB_TX_COLLISIONS 0x1c /* 32b: TxCollisions */ +#define ROBO_MIB_TX_SINGLE_COLLISIONS 0x20 /* 32b: TxSingleCollision */ +#define ROBO_MIB_TX_MULTI_COLLISIONS 0x24 /* 32b: TxMultiCollision */ +#define ROBO_MIB_TX_DEFER_TX 0x28 /* 32b: TxDeferred Transmit */ +#define ROBO_MIB_TX_LATE_COLLISIONS 0x2c /* 32b: TxLateCollision */ +#define ROBO_MIB_EXCESS_COLLISIONS 0x30 /* 32b: TxExcessiveCollision*/ +#define ROBO_MIB_FRAME_IN_DISCARDS 0x34 /* 32b: TxFrameInDiscards */ +#define ROBO_MIB_TX_PAUSE_PKTS 0x38 /* 32b: TxPausePkts */ + +/* Receive Statistics */ +#define ROBO_MIB_RX_OCTETS 0x44 /* 64b: RxOctets */ +#define ROBO_MIB_RX_UNDER_SIZE_PKTS 0x4c /* 32b: RxUndersizePkts(runts)*/ +#define ROBO_MIB_RX_PAUSE_PKTS 0x50 /* 32b: RxPausePkts */ +#define ROBO_MIB_RX_PKTS_64 0x54 /* 32b: RxPkts64Octets */ +#define ROBO_MIB_RX_PKTS_65_TO_127 0x58 /* 32b: RxPkts64to127Octets*/ +#define ROBO_MIB_RX_PKTS_128_TO_255 0x5c /* 32b: RxPkts128to255Octets*/ +#define ROBO_MIB_RX_PKTS_256_TO_511 0x60 /* 32b: RxPkts256to511Octets*/ +#define ROBO_MIB_RX_PKTS_512_TO_1023 0x64 /* 32b: RxPkts512to1023Octets*/ +#define ROBO_MIB_RX_PKTS_1024_TO_1522 0x68 /* 32b: RxPkts1024to1522Octets*/ +#define ROBO_MIB_RX_OVER_SIZE_PKTS 0x6c /* 32b: RxOversizePkts*/ +#define ROBO_MIB_RX_JABBERS 0x70 /* 32b: RxJabbers*/ +#define ROBO_MIB_RX_ALIGNMENT_ERRORS 0x74 /* 32b: RxAlignmentErrors*/ +#define ROBO_MIB_RX_FCS_ERRORS 0x78 /* 32b: RxFCSErrors */ +#define ROBO_MIB_RX_GOOD_OCTETS 0x7c /* 32b: RxGoodOctets */ +#define ROBO_MIB_RX_DROP_PKTS 0x84 /* 32b: RxDropPkts */ +#define ROBO_MIB_RX_UC_PKTS 0x88 /* 32b: RxUnicastPkts */ +#define ROBO_MIB_RX_MC_PKTS 0x8c /* 32b: RxMulticastPkts */ +#define ROBO_MIB_RX_BC_PKTS 0x90 /* 32b: RxBroadcastPkts */ +#define ROBO_MIB_RX_SA_CHANGES 0x94 /* 32b: RxSAChanges */ +#define ROBO_MIB_RX_FRAGMENTS 0x98 /* 32b: RxFragments */ +#define ROBO_MIB_RX_EXCESS_SZ_DISC 0x9c /* 32b: RxExcessSizeDisc*/ +#define ROBO_MIB_RX_SYMBOL_ERROR 0xa0 /* 32b: RxSymbolError */ + +/* BCM5350 MIB Statistics */ +/* Group 0 */ +#define ROBO_MIB_TX_GOOD_PKTS 0x00 /* 16b: TxGoodPkts */ +#define ROBO_MIB_TX_UNICAST_PKTS 0x02 /* 16b: TxUnicastPkts */ +#define ROBO_MIB_RX_GOOD_PKTS 0x04 /* 16b: RxGoodPkts */ +#define ROBO_MIB_RX_GOOD_UNICAST_PKTS 0x06 /* 16b: RxGoodUnicastPkts */ +/* Group 1 */ +#define ROBO_MIB_TX_COLLISION 0x00 /* 16b: TxCollision */ +#define ROBO_MIB_TX_OCTETS_5350 0x02 /* 16b: TxOctets */ +#define ROBO_MIB_RX_FCS_ERRORS_5350 0x04 /* 16b: RxFCSErrors */ +#define ROBO_MIB_RX_GOOD_OCTETS_5350 0x06 /* 16b: RxGoodOctets */ + +/* BCM5325m QoS REGISTERS (Page 0x30) REGISTER MAP: 8/16 */ +#define ROBO_QOS_CTRL 0x00 /* 16b: QoS Control Register */ +#define ROBO_QOS_LOCAL_WEIGHT_CTRL 0x10 /* 8b: Local HQ/LQ Weight Register*/ +#define ROBO_QOS_CPU_WEIGHT_CTRL 0x12 /* 8b: CPU HQ/LQ Weight Register*/ +#define ROBO_QOS_PAUSE_ENA 0x13 /* 16b: Qos Pause Enable Register*/ +#define ROBO_QOS_PRIO_THRESHOLD 0x15 /* 8b: Priority Threshold Register*/ +#define ROBO_QOS_RESERVED 0x16 /* 8b: Qos Reserved Register */ + +/* BCM5325m VLAN REGISTERS (Page 0x34) REGISTER MAP: 8/16bit */ +typedef struct _ROBO_VLAN_CTRL0_STRUC +{ + unsigned char frameControlP:2; /* 802.1P frame control */ + unsigned char frameControlQ:2; /* 802.1Q frame control */ + unsigned char dropMissedVID:1; /* enable drop missed VID packet */ + unsigned char vidMacHash:1; /* VID_MAC hash enable */ + unsigned char vidMacCheck:1; /* VID_MAC check enable */ + unsigned char VLANen:1; /* 802.1Q VLAN enable */ +} ROBO_VLAN_CTRL0_STRUC; +#define VLAN_TABLE_WRITE 1 /* for read/write state in table access reg */ +#define VLAN_TABLE_READ 0 /* for read/write state in table access reg */ +#define VLAN_ID_HIGH_BITS 0 /* static high bits in table access reg */ +#define VLAN_ID_MAX 255 /* max VLAN id */ +#define VLAN_ID_MAX5350 15 /* max VLAN id (5350) */ +#define VLAN_ID_MASK VLAN_ID_MAX /* VLAN id mask */ +#ifdef BCM5380 +#define VLAN_UNTAG_SHIFT 13 /* for postioning untag bits in write reg */ +#define VLAN_VALID 0x4000000 /* valid bit in write reg */ +#else +#define VLAN_UNTAG_SHIFT 7 /* for postioning untag bits in write reg */ +#define VLAN_VALID 0x4000 /* valid bit in write reg */ +/* corresponding values for 5350 */ +#define VLAN_UNTAG_SHIFT_5350 6 /* for postioning untag bits in write reg */ +#define VLAN_VALID_5350 0x00100000 /* valid bit in write reg */ +#endif +typedef struct _ROBO_VLAN_TABLE_ACCESS_STRUC +{ + unsigned char VLANid:8; /* VLAN ID (low 8 bits) */ + unsigned char VLANidHi:4; /* VLAN ID (fixed upper portion) */ + unsigned char readWriteState:1; /* read/write state (write = 1) */ + volatile unsigned char readWriteEnable:1; /* table read/write enable */ + unsigned char rsvd:2; /* reserved */ +} ROBO_VLAN_TABLE_ACCESS_STRUC; +#ifdef BCM5380 +typedef struct _ROBO_VLAN_READ_WRITE_STRUC +{ + unsigned int VLANgroup:13;/* VLAN group mask */ + unsigned int VLANuntag:13;/* VLAN untag enable mask */ + unsigned char valid:1; /* valid */ + unsigned char rsvd:5; /* reserved */ +} ROBO_VLAN_READ_WRITE_STRUC; +#else +typedef struct _ROBO_VLAN_READ_WRITE_STRUC +{ + unsigned char VLANgroup:7; /* VLAN group mask */ + unsigned char VLANuntag:7; /* VLAN untag enable mask */ + unsigned char valid:1; /* valid */ + unsigned char rsvd:1; /* reserved */ +} ROBO_VLAN_READ_WRITE_STRUC; +typedef struct _ROBO_VLAN_READ_WRITE_STRUC_5350 +{ + unsigned char VLANgroup:6; /* VLAN group mask */ + unsigned char VLANuntag:6; /* VLAN untag enable mask */ + unsigned char highVID:8; /* upper bits of vid */ + unsigned char valid:1; /* valid */ + unsigned int rsvd:11; /* reserved */ +} ROBO_VLAN_READ_WRITE_STRUC_5350; +#endif +#define ROBO_VLAN_CTRL0 0x00 /* 8b: VLAN Control 0 Register */ +#define ROBO_VLAN_CTRL1 0x01 /* 8b: VLAN Control 1 Register */ +#define ROBO_VLAN_CTRL2 0x02 /* 8b: VLAN Control 2 Register */ +#define ROBO_VLAN_CTRL3 0x03 /* 8b: VLAN Control 3 Register */ +#define ROBO_VLAN_CTRL4 0x04 /* 8b: VLAN Control 4 Register */ +#define ROBO_VLAN_CTRL5 0x05 /* 8b: VLAN Control 5 Register */ +#define ROBO_VLAN_TABLE_ACCESS 0x08 /* 14b: VLAN Table Access Register */ +#define ROBO_VLAN_TABLE_ACCESS_5350 0x06 /* 14b: VLAN Table Access Register (5350) */ +#define ROBO_VLAN_WRITE 0x0a /* 15b: VLAN Write Register */ +#define ROBO_VLAN_WRITE_5350 0x08 /* 15b: VLAN Write Register (5350) */ +#define ROBO_VLAN_READ 0x0c /* 15b: VLAN Read Register */ +#define ROBO_VLAN_PORT0_DEF_TAG 0x10 /* 16b: VLAN Port 0 Default Tag Register */ +#define ROBO_VLAN_PORT1_DEF_TAG 0x12 /* 16b: VLAN Port 1 Default Tag Register */ +#define ROBO_VLAN_PORT2_DEF_TAG 0x14 /* 16b: VLAN Port 2 Default Tag Register */ +#define ROBO_VLAN_PORT3_DEF_TAG 0x16 /* 16b: VLAN Port 3 Default Tag Register */ +#define ROBO_VLAN_PORT4_DEF_TAG 0x18 /* 16b: VLAN Port 4 Default Tag Register */ +#define ROBO_VLAN_PORTMII_DEF_TAG 0x1a /* 16b: VLAN Port MII Default Tag Register */ +/* 5380 only */ +#define ROBO_VLAN_PORT5_DEF_TAG 0x1a /* 16b: VLAN Port 5 Default Tag Register */ +#define ROBO_VLAN_PORT6_DEF_TAG 0x1c /* 16b: VLAN Port 6 Default Tag Register */ +#define ROBO_VLAN_PORT7_DEF_TAG 0x1e /* 16b: VLAN Port 7 Default Tag Register */ + +/* obsolete */ +#define ROBO_VLAN_PORT0_CTRL 0x00 /* 16b: Port 0 VLAN Register */ +#define ROBO_VLAN_PORT1_CTRL 0x02 /* 16b: Port 1 VLAN Register */ +#define ROBO_VLAN_PORT2_CTRL 0x04 /* 16b: Port 2 VLAN Register */ +#define ROBO_VLAN_PORT3_CTRL 0x06 /* 16b: Port 3 VLAN Register */ +#define ROBO_VLAN_PORT4_CTRL 0x08 /* 16b: Port 4 VLAN Register */ +#define ROBO_VLAN_IM_PORT_CTRL 0x10 /* 16b: Inverse MII Port VLAN Reg */ +#define ROBO_VLAN_SMP_PORT_CTRL 0x12 /* 16b: Serial Port VLAN Register */ +#define ROBO_VLAN_PORTSPI_DEF_TAG 0x1c /* 16b: VLAN Port SPI Default Tag Register */ +#define ROBO_VLAN_PRIORITY_REMAP 0x20 /* 24b: VLAN Priority Re-Map Register */ + +#ifndef _CFE_ +#pragma pack() +#endif + + +#endif /* !__BCM535M_H_ */ + + + + + diff --git a/package/system/utils/robocfg/src/robocfg.c b/package/system/utils/robocfg/src/robocfg.c new file mode 100644 index 0000000000..7a4094dd41 --- /dev/null +++ b/package/system/utils/robocfg/src/robocfg.c @@ -0,0 +1,581 @@ +/* + * Broadcom BCM5325E/536x switch configuration utility + * + * Copyright (C) 2005 Oleg I. Vdovikin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/param.h> +#include <sys/ioctl.h> +#include <sys/socket.h> + +/* linux stuff */ +typedef u_int64_t u64; +typedef u_int32_t u32; +typedef u_int16_t u16; +typedef u_int8_t u8; + +#include <linux/if.h> +#include <linux/sockios.h> +#include <linux/ethtool.h> +#include <linux/mii.h> + +#include "etc53xx.h" +#define ROBO_PHY_ADDR 0x1E /* robo switch phy address */ + +/* MII registers */ +#define REG_MII_PAGE 0x10 /* MII Page register */ +#define REG_MII_ADDR 0x11 /* MII Address register */ +#define REG_MII_DATA0 0x18 /* MII Data register 0 */ + +#define REG_MII_PAGE_ENABLE 1 +#define REG_MII_ADDR_WRITE 1 +#define REG_MII_ADDR_READ 2 + +/* Private et.o ioctls */ +#define SIOCGETCPHYRD (SIOCDEVPRIVATE + 9) +#define SIOCSETCPHYWR (SIOCDEVPRIVATE + 10) + +typedef struct { + struct ifreq ifr; + int fd; + int et; /* use private ioctls */ +} robo_t; + +static u16 mdio_read(robo_t *robo, u16 phy_id, u8 reg) +{ + if (robo->et) { + int args[2] = { reg }; + + if (phy_id != ROBO_PHY_ADDR) { + fprintf(stderr, + "Access to real 'phy' registers unavaliable.\n" + "Upgrade kernel driver.\n"); + + return 0xffff; + } + + robo->ifr.ifr_data = (caddr_t) args; + if (ioctl(robo->fd, SIOCGETCPHYRD, (caddr_t)&robo->ifr) < 0) { + perror("SIOCGETCPHYRD"); + exit(1); + } + + return args[1]; + } else { + struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&robo->ifr.ifr_data; + mii->phy_id = phy_id; + mii->reg_num = reg; + if (ioctl(robo->fd, SIOCGMIIREG, &robo->ifr) < 0) { + perror("SIOCGMIIREG"); + exit(1); + } + return mii->val_out; + } +} + +static void mdio_write(robo_t *robo, u16 phy_id, u8 reg, u16 val) +{ + if (robo->et) { + int args[2] = { reg, val }; + + if (phy_id != ROBO_PHY_ADDR) { + fprintf(stderr, + "Access to real 'phy' registers unavaliable.\n" + "Upgrade kernel driver.\n"); + return; + } + + robo->ifr.ifr_data = (caddr_t) args; + if (ioctl(robo->fd, SIOCSETCPHYWR, (caddr_t)&robo->ifr) < 0) { + perror("SIOCGETCPHYWR"); + exit(1); + } + } else { + struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&robo->ifr.ifr_data; + mii->phy_id = phy_id; + mii->reg_num = reg; + mii->val_in = val; + if (ioctl(robo->fd, SIOCSMIIREG, &robo->ifr) < 0) { + perror("SIOCSMIIREG"); + exit(1); + } + } +} + +static int robo_reg(robo_t *robo, u8 page, u8 reg, u8 op) +{ + int i = 3; + + /* set page number */ + mdio_write(robo, ROBO_PHY_ADDR, REG_MII_PAGE, + (page << 8) | REG_MII_PAGE_ENABLE); + + /* set register address */ + mdio_write(robo, ROBO_PHY_ADDR, REG_MII_ADDR, + (reg << 8) | op); + + /* check if operation completed */ + while (i--) { + if ((mdio_read(robo, ROBO_PHY_ADDR, REG_MII_ADDR) & 3) == 0) + return 0; + } + + fprintf(stderr, "robo_reg: timeout\n"); + exit(1); + + return 0; +} + +static void robo_read(robo_t *robo, u8 page, u8 reg, u16 *val, int count) +{ + int i; + + robo_reg(robo, page, reg, REG_MII_ADDR_READ); + + for (i = 0; i < count; i++) + val[i] = mdio_read(robo, ROBO_PHY_ADDR, REG_MII_DATA0 + i); +} + +static u16 robo_read16(robo_t *robo, u8 page, u8 reg) +{ + robo_reg(robo, page, reg, REG_MII_ADDR_READ); + + return mdio_read(robo, ROBO_PHY_ADDR, REG_MII_DATA0); +} + +static u32 robo_read32(robo_t *robo, u8 page, u8 reg) +{ + robo_reg(robo, page, reg, REG_MII_ADDR_READ); + + return mdio_read(robo, ROBO_PHY_ADDR, REG_MII_DATA0) + + (mdio_read(robo, ROBO_PHY_ADDR, REG_MII_DATA0 + 1) << 16); +} + +static void robo_write16(robo_t *robo, u8 page, u8 reg, u16 val16) +{ + /* write data */ + mdio_write(robo, ROBO_PHY_ADDR, REG_MII_DATA0, val16); + + robo_reg(robo, page, reg, REG_MII_ADDR_WRITE); +} + +static void robo_write32(robo_t *robo, u8 page, u8 reg, u32 val32) +{ + /* write data */ + mdio_write(robo, ROBO_PHY_ADDR, REG_MII_DATA0, val32 & 65535); + mdio_write(robo, ROBO_PHY_ADDR, REG_MII_DATA0 + 1, val32 >> 16); + + robo_reg(robo, page, reg, REG_MII_ADDR_WRITE); +} + +/* checks that attached switch is 5325E/5350 */ +static int robo_vlan5350(robo_t *robo) +{ + /* set vlan access id to 15 and read it back */ + u16 val16 = 15; + robo_write16(robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); + + /* 5365 will refuse this as it does not have this reg */ + return (robo_read16(robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350) == val16); +} + +u8 port[6] = { 0, 1, 2, 3, 4, 8 }; +char ports[6] = { 'W', '4', '3', '2', '1', 'C' }; +char *rxtx[4] = { "enabled", "rx_disabled", "tx_disabled", "disabled" }; +char *stp[8] = { "none", "disable", "block", "listen", "learn", "forward", "6", "7" }; + +struct { + char *name; + u16 bmcr; +} media[5] = { { "auto", BMCR_ANENABLE | BMCR_ANRESTART }, + { "10HD", 0 }, { "10FD", BMCR_FULLDPLX }, + { "100HD", BMCR_SPEED100 }, { "100FD", BMCR_SPEED100 | BMCR_FULLDPLX } }; + +struct { + char *name; + u16 value; +} mdix[3] = { { "auto", 0x0000 }, { "on", 0x1800 }, { "off", 0x0800 } }; + +void usage() +{ + fprintf(stderr, "Broadcom BCM5325E/536x switch configuration utility\n" + "Copyright (C) 2005 Oleg I. Vdovikin\n\n" + "This program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n\n"); + + fprintf(stderr, "Usage: robocfg <op> ... <op>\n" + "Operations are as below:\n" + "\tshow\n" + "\tswitch <enable|disable>\n" + "\tport <port_number> [state <%s|%s|%s|%s>]\n\t\t[stp %s|%s|%s|%s|%s|%s] [tag <vlan_tag>]\n" + "\t\t[media %s|%s|%s|%s|%s] [mdi-x %s|%s|%s]\n" + "\tvlan <vlan_number> [ports <ports_list>]\n" + "\tvlans <enable|disable|reset>\n\n" + "\tports_list should be one argument, space separated, quoted if needed,\n" + "\tport number could be followed by 't' to leave packet vlan tagged (CPU \n" + "\tport default) or by 'u' to untag packet (other ports default) before \n" + "\tbringing it to the port, '*' is ignored\n" + "\nSamples:\n" + "1) ASUS WL-500g Deluxe stock config (eth0 is WAN, eth0.1 is LAN):\n" + "robocfg switch disable vlans enable reset vlan 0 ports \"0 5u\" vlan 1 ports \"1 2 3 4 5t\"" + " port 0 state enabled stp none switch enable\n" + "2) WRT54g, WL-500g Deluxe OpenWRT config (vlan0 is LAN, vlan1 is WAN):\n" + "robocfg switch disable vlans enable reset vlan 0 ports \"1 2 3 4 5t\" vlan 1 ports \"0 5t\"" + " port 0 state enabled stp none switch enable\n", + rxtx[0], rxtx[1], rxtx[2], rxtx[3], stp[0], stp[1], stp[2], stp[3], stp[4], stp[5], + media[0].name, media[1].name, media[2].name, media[3].name, media[4].name, + mdix[0].name, mdix[1].name, mdix[2].name); +} + +static robo_t robo; +int bcm53xx_probe(const char *dev) +{ + struct ethtool_drvinfo info; + unsigned int phyid; + int ret; + + fprintf(stderr, "probing %s\n", dev); + + strcpy(robo.ifr.ifr_name, dev); + memset(&info, 0, sizeof(info)); + info.cmd = ETHTOOL_GDRVINFO; + robo.ifr.ifr_data = (caddr_t)&info; + ret = ioctl(robo.fd, SIOCETHTOOL, (caddr_t)&robo.ifr); + if (ret < 0) { + perror("SIOCETHTOOL"); + return ret; + } + + if ( strcmp(info.driver, "et0") && + strcmp(info.driver, "b44") && + strcmp(info.driver, "bcm63xx_enet") ) { + fprintf(stderr, "driver not supported %s\n", info.driver); + return -ENOSYS; + } + + /* try access using MII ioctls - get phy address */ + robo.et = 0; + if (ioctl(robo.fd, SIOCGMIIPHY, &robo.ifr) < 0) + robo.et = 1; + + if (robo.et) { + unsigned int args[2] = { 2 }; + + robo.ifr.ifr_data = (caddr_t) args; + ret = ioctl(robo.fd, SIOCGETCPHYRD, (caddr_t)&robo.ifr); + if (ret < 0) { + perror("SIOCGETCPHYRD"); + return ret; + } + phyid = args[1] & 0xffff; + + args[0] = 3; + robo.ifr.ifr_data = (caddr_t) args; + ret = ioctl(robo.fd, SIOCGETCPHYRD, (caddr_t)&robo.ifr); + if (ret < 0) { + perror("SIOCGETCPHYRD"); + return ret; + } + phyid |= args[1] << 16; + } else { + struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&robo.ifr.ifr_data; + mii->phy_id = ROBO_PHY_ADDR; + mii->reg_num = 2; + ret = ioctl(robo.fd, SIOCGMIIREG, &robo.ifr); + if (ret < 0) { + perror("SIOCGMIIREG"); + return ret; + } + phyid = mii->val_out & 0xffff; + + mii->phy_id = ROBO_PHY_ADDR; + mii->reg_num = 3; + ret = ioctl(robo.fd, SIOCGMIIREG, &robo.ifr); + if (ret < 0) { + perror("SIOCGMIIREG"); + return ret; + } + phyid |= mii->val_out << 16; + } + + if (phyid == 0xffffffff || phyid == 0x55210022) { + perror("phyid"); + return -EIO; + } + + return 0; +} + +int +main(int argc, char *argv[]) +{ + u16 val16; + u16 mac[3]; + int i = 0, j; + int robo5350 = 0; + u32 phyid; + + if ((robo.fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("socket"); + exit(1); + } + + if (bcm53xx_probe("eth1")) { + if (bcm53xx_probe("eth0")) { + perror("bcm53xx_probe"); + exit(1); + } + } + + robo5350 = robo_vlan5350(&robo); + + for (i = 1; i < argc;) { + if (strcasecmp(argv[i], "port") == 0 && (i + 1) < argc) + { + int index = atoi(argv[++i]); + /* read port specs */ + while (++i < argc) { + if (strcasecmp(argv[i], "state") == 0 && ++i < argc) { + for (j = 0; j < 4 && strcasecmp(argv[i], rxtx[j]); j++); + if (j < 4) { + /* change state */ + robo_write16(&robo,ROBO_CTRL_PAGE, port[index], + (robo_read16(&robo, ROBO_CTRL_PAGE, port[index]) & ~(3 << 0)) | (j << 0)); + } else { + fprintf(stderr, "Invalid state '%s'.\n", argv[i]); + exit(1); + } + } else + if (strcasecmp(argv[i], "stp") == 0 && ++i < argc) { + for (j = 0; j < 8 && strcasecmp(argv[i], stp[j]); j++); + if (j < 8) { + /* change stp */ + robo_write16(&robo,ROBO_CTRL_PAGE, port[index], + (robo_read16(&robo, ROBO_CTRL_PAGE, port[index]) & ~(7 << 5)) | (j << 5)); + } else { + fprintf(stderr, "Invalid stp '%s'.\n", argv[i]); + exit(1); + } + } else + if (strcasecmp(argv[i], "media") == 0 && ++i < argc) { + for (j = 0; j < 5 && strcasecmp(argv[i], media[j].name); j++); + if (j < 5) { + mdio_write(&robo, port[index], MII_BMCR, media[j].bmcr); + } else { + fprintf(stderr, "Invalid media '%s'.\n", argv[i]); + exit(1); + } + } else + if (strcasecmp(argv[i], "mdi-x") == 0 && ++i < argc) { + for (j = 0; j < 3 && strcasecmp(argv[i], mdix[j].name); j++); + if (j < 3) { + mdio_write(&robo, port[index], 0x1c, mdix[j].value | + (mdio_read(&robo, port[index], 0x1c) & ~0x1800)); + } else { + fprintf(stderr, "Invalid mdi-x '%s'.\n", argv[i]); + exit(1); + } + } else + if (strcasecmp(argv[i], "tag") == 0 && ++i < argc) { + j = atoi(argv[i]); + /* change vlan tag */ + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (index << 1), j); + } else break; + } + } else + if (strcasecmp(argv[i], "vlan") == 0 && (i + 1) < argc) + { + int index = atoi(argv[++i]); + while (++i < argc) { + if (strcasecmp(argv[i], "ports") == 0 && ++i < argc) { + char *ports = argv[i]; + int untag = 0; + int member = 0; + + while (*ports >= '0' && *ports <= '9') { + j = *ports++ - '0'; + member |= 1 << j; + + /* untag if needed, CPU port requires special handling */ + if (*ports == 'u' || (j != 5 && (*ports == ' ' || *ports == 0))) + { + untag |= 1 << j; + if (*ports) ports++; + /* change default vlan tag */ + robo_write16(&robo, ROBO_VLAN_PAGE, + ROBO_VLAN_PORT0_DEF_TAG + (j << 1), index); + } else + if (*ports == '*' || *ports == 't' || *ports == ' ') ports++; + else break; + + while (*ports == ' ') ports++; + } + + if (*ports) { + fprintf(stderr, "Invalid ports '%s'.\n", argv[i]); + exit(1); + } else { + /* write config now */ + val16 = (index) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */; + if (robo5350) { + robo_write32(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5350, + (1 << 20) /* valid */ | (untag << 6) | member); + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); + } else { + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, + (1 << 14) /* valid */ | (untag << 7) | member); + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); + } + } + } else break; + } + } else + if (strcasecmp(argv[i], "switch") == 0 && (i + 1) < argc) + { + /* enable/disable switching */ + robo_write16(&robo, ROBO_CTRL_PAGE, ROBO_SWITCH_MODE, + (robo_read16(&robo, ROBO_CTRL_PAGE, ROBO_SWITCH_MODE) & ~2) | + (*argv[++i] == 'e' ? 2 : 0)); + i++; + } else + if (strcasecmp(argv[i], "vlans") == 0 && (i + 1) < argc) + { + while (++i < argc) { + if (strcasecmp(argv[i], "reset") == 0) { + /* reset vlan validity bit */ + for (j = 0; j <= (robo5350 ? VLAN_ID_MAX5350 : VLAN_ID_MAX); j++) + { + /* write config now */ + val16 = (j) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */; + if (robo5350) { + robo_write32(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5350, 0); + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); + } else { + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, 0); + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); + } + } + } else + if (strcasecmp(argv[i], "enable") == 0 || strcasecmp(argv[i], "disable") == 0) + { + int disable = (*argv[i] == 'd') || (*argv[i] == 'D'); + /* enable/disable vlans */ + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_CTRL0, disable ? 0 : + (1 << 7) /* 802.1Q VLAN */ | (3 << 5) /* mac check and hash */); + + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_CTRL1, disable ? 0 : + (1 << 1) | (1 << 2) | (1 << 3) /* RSV multicast */); + + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_CTRL4, disable ? 0 : + (1 << 6) /* drop invalid VID frames */); + + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_CTRL5, disable ? 0 : + (1 << 3) /* drop miss V table frames */); + + } else break; + } + } else + if (strcasecmp(argv[i], "show") == 0) + { + break; + } else { + fprintf(stderr, "Invalid option %s\n", argv[i]); + usage(); + exit(1); + } + } + + if (i == argc) { + if (argc == 1) usage(); + return 0; + } + + /* show config */ + + printf("Switch: %sabled\n", robo_read16(&robo, ROBO_CTRL_PAGE, ROBO_SWITCH_MODE) & 2 ? "en" : "dis"); + + for (i = 0; i < 6; i++) { + printf(robo_read16(&robo, ROBO_STAT_PAGE, ROBO_LINK_STAT_SUMMARY) & (1 << port[i]) ? + "Port %d(%c): %s%s " : "Port %d(%c): DOWN ", i, ports[i], + robo_read16(&robo, ROBO_STAT_PAGE, ROBO_SPEED_STAT_SUMMARY) & (1 << port[i]) ? "100" : " 10", + robo_read16(&robo, ROBO_STAT_PAGE, ROBO_DUPLEX_STAT_SUMMARY) & (1 << port[i]) ? "FD" : "HD"); + + val16 = robo_read16(&robo, ROBO_CTRL_PAGE, port[i]); + + printf("%s stp: %s vlan: %d ", rxtx[val16 & 3], stp[(val16 >> 5) & 7], + robo_read16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (i << 1))); + + robo_read(&robo, ROBO_STAT_PAGE, ROBO_LSA_PORT0 + port[i] * 6, mac, 3); + + printf("mac: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[2] >> 8, mac[2] & 255, mac[1] >> 8, mac[1] & 255, mac[0] >> 8, mac[0] & 255); + } + + val16 = robo_read16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_CTRL0); + + printf("VLANs: %s %sabled%s%s\n", + robo5350 ? "BCM5325/535x" : "BCM536x", + (val16 & (1 << 7)) ? "en" : "dis", + (val16 & (1 << 6)) ? " mac_check" : "", + (val16 & (1 << 5)) ? " mac_hash" : ""); + + /* scan VLANs */ + for (i = 0; i <= (robo5350 ? VLAN_ID_MAX5350 : VLAN_ID_MAX); i++) { + /* issue read */ + val16 = (i) /* vlan */ | (0 << 12) /* read */ | (1 << 13) /* enable */; + + if (robo5350) { + u32 val32; + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); + /* actual read */ + val32 = robo_read32(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_READ); + if ((val32 & (1 << 20)) /* valid */) { + printf("vlan%d:", i); + for (j = 0; j < 6; j++) { + if (val32 & (1 << j)) { + printf(" %d%s", j, (val32 & (1 << (j + 6))) ? + (j == 5 ? "u" : "") : "t"); + } + } + printf("\n"); + } + } else { + robo_write16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); + /* actual read */ + val16 = robo_read16(&robo, ROBO_VLAN_PAGE, ROBO_VLAN_READ); + if ((val16 & (1 << 14)) /* valid */) { + printf("vlan%d:", i); + for (j = 0; j < 6; j++) { + if (val16 & (1 << j)) { + printf(" %d%s", j, (val16 & (1 << (j + 7))) ? + (j == 5 ? "u" : "") : "t"); + } + } + printf("\n"); + } + } + } + + return (0); +} diff --git a/package/system/utils/usbreset/Makefile b/package/system/utils/usbreset/Makefile new file mode 100644 index 0000000000..75bfd85138 --- /dev/null +++ b/package/system/utils/usbreset/Makefile @@ -0,0 +1,44 @@ +# +# Copyright (C) 2011-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=usbreset +PKG_RELEASE:=2 + +include $(INCLUDE_DIR)/package.mk + +define Package/usbreset + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Utility to send a USB port reset to a USB device + MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org> +endef + +define Package/usbreset/description + This package contains the small usbreset utility which + can be used to send a USB port reset to a USB device - + useful for debugging or to force re-detection of particular + devices. +endef + +define Build/Prepare + $(INSTALL_DIR) $(PKG_BUILD_DIR) + $(INSTALL_DATA) ./src/usbreset.c $(PKG_BUILD_DIR)/ +endef + +define Build/Compile + $(TARGET_CC) $(TARGET_CFLAGS) -Wall \ + -o $(PKG_BUILD_DIR)/usbreset $(PKG_BUILD_DIR)/usbreset.c +endef + +define Package/usbreset/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/usbreset $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,usbreset)) diff --git a/package/system/utils/usbreset/src/usbreset.c b/package/system/utils/usbreset/src/usbreset.c new file mode 100644 index 0000000000..087a14cfa4 --- /dev/null +++ b/package/system/utils/usbreset/src/usbreset.c @@ -0,0 +1,253 @@ +/* usbreset -- send a USB port reset to a USB device */ + +/* + +http://marc.info/?l=linux-usb-users&m=116827193506484&w=2 + +and needs mounted usbfs filesystem + + sudo mount -t usbfs none /proc/bus/usb + +There is a way to suspend a USB device. In order to use it, +you must have a kernel with CONFIG_PM_SYSFS_DEPRECATED turned on. To +suspend a device, do (as root): + + echo -n 2 >/sys/bus/usb/devices/.../power/state + +where the "..." is the ID for your device. To unsuspend, do the same +thing but with a "0" instead of the "2" above. + +Note that this mechanism is slated to be removed from the kernel within +the next year. Hopefully some other mechanism will take its place. + +> To reset a +> device? + +Here's a program to do it. You invoke it as either + + usbreset /proc/bus/usb/BBB/DDD +or + usbreset /dev/usbB.D + +depending on how your system is set up, where BBB and DDD are the bus and +device address numbers. + +Alan Stern + +*/ + +#include <stdio.h> +#include <stdbool.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/ioctl.h> + +#include <linux/usbdevice_fs.h> + + +static char *usbfs = NULL; + +struct usbentry { + int bus_num; + int dev_num; + int vendor_id; + int product_id; + char vendor_name[128]; + char product_name[128]; +}; + + +static bool find_usbfs(void) +{ + FILE *mtab; + + char buf[1024], type[32]; + static char path[1024]; + + if ((mtab = fopen("/proc/mounts", "r")) != NULL) + { + while (fgets(buf, sizeof(buf), mtab)) + { + if (sscanf(buf, "%*s %1023s %31s ", path, type) == 2 && + !strncmp(type, "usbfs", 5)) + { + usbfs = path; + break; + } + } + + fclose(mtab); + } + + return !!usbfs; +} + +static FILE * open_devlist(void) +{ + char buf[1024]; + snprintf(buf, sizeof(buf), "%s/devices", usbfs); + return fopen(buf, "r"); +} + +static void close_devlist(FILE *devs) +{ + fclose(devs); +} + +static struct usbentry * parse_devlist(FILE *devs) +{ + char buf[1024]; + static struct usbentry dev; + + memset(&dev, 0, sizeof(dev)); + + while (fgets(buf, sizeof(buf), devs)) + { + buf[strlen(buf)-1] = 0; + + switch (buf[0]) + { + case 'T': + sscanf(buf, "T: Bus=%d Lev=%*d Prnt=%*d Port=%*d Cnt=%*d Dev#=%d", + &dev.bus_num, &dev.dev_num); + break; + + case 'P': + sscanf(buf, "P: Vendor=%x ProdID=%x", + &dev.vendor_id, &dev.product_id); + break; + + case 'S': + if (!strncmp(buf, "S: Manufacturer=", 17)) + snprintf(dev.vendor_name, sizeof(dev.vendor_name), + "%s", buf+17); + else if (!strncmp(buf, "S: Product=", 12)) + snprintf(dev.product_name, sizeof(dev.product_name), + "%s", buf+12); + break; + } + + if (dev.product_name[0]) + return &dev; + } + + return NULL; +} + +static void list_devices(void) +{ + FILE *devs = open_devlist(); + struct usbentry *dev; + + if (!devs) + return; + + while ((dev = parse_devlist(devs)) != NULL) + { + printf(" Number %03d/%03d ID %04x:%04x %s\n", + dev->bus_num, dev->dev_num, + dev->vendor_id, dev->product_id, + dev->product_name); + } + + close_devlist(devs); +} + +struct usbentry * find_device(int *bus, int *dev, + int *vid, int *pid, + const char *product) +{ + FILE *devs = open_devlist(); + + struct usbentry *e, *match = NULL; + + if (!devs) + return NULL; + + while ((e = parse_devlist(devs)) != NULL) + { + if ((bus && (e->bus_num == *bus) && (e->dev_num == *dev)) || + (vid && (e->vendor_id == *vid) && (e->product_id == *pid)) || + (product && !strcasecmp(e->product_name, product))) + { + match = e; + break; + } + } + + close_devlist(devs); + + return match; +} + +static void reset_device(struct usbentry *dev) +{ + int fd; + char path[1024]; + + snprintf(path, sizeof(path), "%s/%03d/%03d", + usbfs, dev->bus_num, dev->dev_num); + + printf("Resetting %s ... ", dev->product_name); + + if ((fd = open(path, O_WRONLY)) > -1) + { + if (ioctl(fd, USBDEVFS_RESET, 0) < 0) + printf("failed [%s]\n", strerror(errno)); + else + printf("ok\n"); + + close(fd); + } + else + { + printf("can't open [%s]\n", strerror(errno)); + } +} + + +int main(int argc, char **argv) +{ + int id1, id2; + struct usbentry *dev; + + if (!find_usbfs()) + { + fprintf(stderr, "Unable to find usbfs, is it mounted?\n"); + return 1; + } + + if ((argc == 2) && (sscanf(argv[1], "%3d/%3d", &id1, &id2) == 2)) + { + dev = find_device(&id1, &id2, NULL, NULL, NULL); + } + else if ((argc == 2) && (sscanf(argv[1], "%4x:%4x", &id1, &id2) == 2)) + { + dev = find_device(NULL, NULL, &id1, &id2, NULL); + } + else if ((argc == 2) && strlen(argv[1]) < 128) + { + dev = find_device(NULL, NULL, NULL, NULL, argv[1]); + } + else + { + printf("Usage:\n" + " usbreset PPPP:VVVV - reset by product and vendor id\n" + " usbreset BBB/DDD - reset by bus and device number\n" + " usbreset \"Product\" - reset by product name\n\n" + "Devices:\n"); + list_devices(); + return 1; + } + + if (!dev) + { + fprintf(stderr, "No such device found\n"); + return 1; + } + + reset_device(dev); + return 0; +} diff --git a/package/system/utils/xfsprogs/Makefile b/package/system/utils/xfsprogs/Makefile new file mode 100644 index 0000000000..a7a865a0eb --- /dev/null +++ b/package/system/utils/xfsprogs/Makefile @@ -0,0 +1,87 @@ +# +# Copyright (C) 2006-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=xfsprogs +PKG_RELEASE:=1 +PKG_VERSION:=3.1.7 +PKG_SOURCE_URL:=ftp://oss.sgi.com/projects/xfs/previous/ +PKG_MD5SUM:=049cf9873794ea49d0bb3f12d45748a4 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_INSTALL:=1 +PKG_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk + +define Package/xfsprogs/default + SECTION:=utils + CATEGORY:=Utilities + DEPENDS:=+libuuid +libpthread +librt + URL:=http://oss.sgi.com/projects/xfs +endef + +define Package/xfs-mkfs +$(call Package/xfsprogs/default) + TITLE:=Utility for creating XFS filesystems +endef + +define Package/xfs-fsck +$(call Package/xfsprogs/default) + TITLE:=Utilities for checking and repairing XFS filesystems +endef + +define Package/xfs-growfs +$(call Package/xfsprogs/default) + TITLE:=Utility for increasing the size of XFS filesystems +endef + +CONFIGURE_ARGS += \ + --enable-gettext=no \ + --enable-lib64=no + +TARGET_CFLAGS += \ + -I$(STAGING_DIR)/usr/include \ + -D_LARGEFILE64_SOURCE \ + -D_FILE_OFFSET_BITS=64 \ + -D_GNU_SOURCE + +MAKE_FLAGS += \ + DEBUG= Q= \ + PCFLAGS="-Wall" \ + PKG_PLATFORM=linux \ + ENABLE_GETTEXT=no \ + prefix=$(PKG_INSTALL_DIR)/usr \ + exec_prefix=$(PKG_INSTALL_DIR)/usr \ + PKG_SBIN_DIR=$(PKG_INSTALL_DIR)/usr/sbin \ + PKG_ROOT_SBIN_DIR=$(PKG_INSTALL_DIR)/sbin \ + PKG_MAN_DIR=$(PKG_INSTALL_DIR)/usr/man \ + PKG_LOCALE_DIR=$(PKG_INSTALL_DIR)/usr/share/locale \ + PKG_ROOT_LIB_DIR=$(PKG_INSTALL_DIR)/lib \ + PKG_DOC_DIR=$(PKG_INSTALL_DIR)/usr/share/doc/xfsprogs + +define Package/xfs-mkfs/install + mkdir -p $(1)/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/mkfs.xfs $(1)/sbin +endef + +define Package/xfs-fsck/install + mkdir -p $(1)/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/xfs_repair $(1)/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/xfs_db $(1)/sbin +endef + +define Package/xfs-growfs/install + mkdir -p $(1)/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/xfs_growfs $(1)/sbin +endef + +$(eval $(call BuildPackage,xfs-mkfs)) +$(eval $(call BuildPackage,xfs-fsck)) +$(eval $(call BuildPackage,xfs-growfs)) diff --git a/package/system/utils/xfsprogs/patches/001-automake-compat.patch b/package/system/utils/xfsprogs/patches/001-automake-compat.patch new file mode 100644 index 0000000000..3003d6d210 --- /dev/null +++ b/package/system/utils/xfsprogs/patches/001-automake-compat.patch @@ -0,0 +1,84 @@ +commit 2222aa77e11b959e0e5a0ded3482e56799593bc2 +Author: Jens Muecke <jens@nons.de> +Date: Thu Jan 26 00:34:15 2012 +0100 + + 001-automake-compat + +diff --git a/configure.in b/configure.in +index 664c0e9..d91b6ec 100644 +--- a/configure.in ++++ b/configure.in +@@ -2,7 +2,8 @@ AC_INIT(include/libxfs.h) + AC_PREREQ(2.50) + AC_CONFIG_AUX_DIR([.]) + AC_CONFIG_MACRO_DIR([m4]) +-AC_CONFIG_HEADER(include/platform_defs.h) ++# Put a dummy here (http://www.mail-archive.com/automake@gnu.org/msg09241.html) ++AC_CONFIG_HEADERS([doesnotexist.h include/platform_defs.h]) + AC_PREFIX_DEFAULT(/usr) + + AC_PROG_LIBTOOL +diff --git a/include/builddefs.in b/include/builddefs.in +index 81ebfcd..5a4a0e8 100644 +--- a/include/builddefs.in ++++ b/include/builddefs.in +@@ -20,6 +20,8 @@ + ifndef _BUILDDEFS_INCLUDED_ + _BUILDDEFS_INCLUDED_ = 1 + ++SHELL = @SHELL@ ++ + DEBUG = @debug_build@ + OPTIMIZER = @opt_build@ + MALLOCLIB = @malloc_lib@ +diff --git a/m4/package_types.m4 b/m4/package_types.m4 +index 0a0e087..66a136a 100644 +--- a/m4/package_types.m4 ++++ b/m4/package_types.m4 +@@ -9,7 +9,7 @@ AC_DEFUN([AC_TYPE_PSINT], + #include <stddef.h> + ], [ + __psint_t psint; +- ], AC_DEFINE(HAVE___PSINT_T) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) ++ ], AC_DEFINE([HAVE___PSINT_T], [1], [Define if __psint_t exists]) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) + ]) + + # +@@ -23,7 +23,7 @@ AC_DEFUN([AC_TYPE_PSUNSIGNED], + #include <stddef.h> + ], [ + __psunsigned_t psuint; +- ], AC_DEFINE(HAVE___PSUNSIGNED_T) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) ++ ], AC_DEFINE([HAVE___PSUNSIGNED_T], [1], [Define if __psunsigned_t exists]) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) + ]) + + # +@@ -37,7 +37,7 @@ AC_DEFUN([AC_TYPE_U32], + #include <stddef.h> + ], [ + __u32 u32; +- ], AC_DEFINE(HAVE___U32) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) ++ ], AC_DEFINE([HAVE___U32], [1], [Define if __u32 exists]) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no)) + ]) + + # +@@ -50,15 +50,15 @@ AC_DEFUN([AC_SIZEOF_POINTERS_AND_LONG], + AC_CHECK_SIZEOF(long, 4) + AC_CHECK_SIZEOF(char *, 4) + if test $ac_cv_sizeof_long -eq 4 -o $ac_cv_sizeof_long -eq 0; then +- AC_DEFINE(HAVE_32BIT_LONG) ++ AC_DEFINE([HAVE_32BIT_LONG], [1], [Define if long is 32bit]) + fi + if test $ac_cv_sizeof_long -eq 8; then +- AC_DEFINE(HAVE_64BIT_LONG) ++ AC_DEFINE([HAVE_64BIT_LONG], [1], [Define if long is 64bit]) + fi + if test $ac_cv_sizeof_char_p -eq 4 -o $ac_cv_sizeof_char_p -eq 0; then +- AC_DEFINE(HAVE_32BIT_PTR) ++ AC_DEFINE([HAVE_32BIT_PTR], [1], [Define if char* is 32bit]) + fi + if test $ac_cv_sizeof_char_p -eq 8; then +- AC_DEFINE(HAVE_64BIT_PTR) ++ AC_DEFINE([HAVE_64BIT_PTR], [1], [Define if char* is 64bit]) + fi + ]) diff --git a/package/system/utils/xfsprogs/patches/100-no_aio.patch b/package/system/utils/xfsprogs/patches/100-no_aio.patch new file mode 100644 index 0000000000..30d36b4da8 --- /dev/null +++ b/package/system/utils/xfsprogs/patches/100-no_aio.patch @@ -0,0 +1,21 @@ +commit e72b7bd12fdef06c3494b919376bfe886aa8bb4d +Author: Jens Muecke <jens@nons.de> +Date: Thu Jan 26 00:35:43 2012 +0100 + + 100-no_aio + +diff --git a/configure.in b/configure.in +index d91b6ec..8dc8b4a 100644 +--- a/configure.in ++++ b/configure.in +@@ -92,8 +92,8 @@ AC_PACKAGE_GLOBALS(xfsprogs) + AC_PACKAGE_UTILITIES(xfsprogs) + AC_MULTILIB($enable_lib64) + +-AC_PACKAGE_NEED_AIO_H +-AC_PACKAGE_NEED_LIO_LISTIO ++librt="-lrt" ++AC_SUBST(librt) + + AC_PACKAGE_NEED_UUID_H + AC_PACKAGE_NEED_UUIDCOMPARE diff --git a/package/system/utils/xfsprogs/patches/110-uclibc_no_ustat.patch b/package/system/utils/xfsprogs/patches/110-uclibc_no_ustat.patch new file mode 100644 index 0000000000..c46e8025cd --- /dev/null +++ b/package/system/utils/xfsprogs/patches/110-uclibc_no_ustat.patch @@ -0,0 +1,36 @@ +commit 7b1d0a98e779170232c0a81b4749ab934ec67a7e +Author: Jens Muecke <jens@nons.de> +Date: Thu Jan 26 00:36:42 2012 +0100 + + 110-uclibc_no_ustat + +diff --git a/libxfs/linux.c b/libxfs/linux.c +index 2e07d54..6a6c905 100644 +--- a/libxfs/linux.c ++++ b/libxfs/linux.c +@@ -21,7 +21,9 @@ + #include <mntent.h> + #include <sys/stat.h> + #undef ustat ++#ifndef __UCLIBC__ + #include <sys/ustat.h> ++#endif + #include <sys/mount.h> + #include <sys/ioctl.h> + #include <sys/sysinfo.h> +@@ -49,6 +51,7 @@ static int max_block_alignment; + int + platform_check_ismounted(char *name, char *block, struct stat64 *s, int verbose) + { ++#ifndef __UCLIBC__ + /* Pad ust; pre-2.6.28 linux copies out too much in 32bit compat mode */ + struct ustat ust[2]; + struct stat64 st; +@@ -68,6 +71,7 @@ platform_check_ismounted(char *name, char *block, struct stat64 *s, int verbose) + progname, name); + return 1; + } ++#endif + return 0; + } + diff --git a/package/system/utils/xfsprogs/patches/120-portability.patch b/package/system/utils/xfsprogs/patches/120-portability.patch new file mode 100644 index 0000000000..1e9b533654 --- /dev/null +++ b/package/system/utils/xfsprogs/patches/120-portability.patch @@ -0,0 +1,47 @@ +commit d2aef8b3967e53fe58178f5af50fef488ee0faed +Author: Jens Muecke <jens@nons.de> +Date: Thu Jan 26 00:37:52 2012 +0100 + + 120-portability + +diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c +index c01e0b9..2e2f320 100644 +--- a/copy/xfs_copy.c ++++ b/copy/xfs_copy.c +@@ -463,6 +463,15 @@ read_ag_header(int fd, xfs_agnumber_t agno, wbuf *buf, ag_header_t *ag, + } + + ++static void sig_mask(int type) ++{ ++ sigset_t mask; ++ sigemptyset(&mask); ++ sigaddset(&mask, SIGCHLD); ++ sigprocmask(type, &mask, NULL); ++} ++ ++ + void + write_wbuf(void) + { +@@ -478,9 +487,9 @@ write_wbuf(void) + if (target[i].state != INACTIVE) + pthread_mutex_unlock(&targ[i].wait); /* wake up */ + +- sigrelse(SIGCHLD); ++ sig_mask(SIG_UNBLOCK); + pthread_mutex_lock(&mainwait); +- sighold(SIGCHLD); ++ sig_mask(SIG_BLOCK); + } + + +@@ -847,7 +856,7 @@ main(int argc, char **argv) + /* set up sigchild signal handler */ + + signal(SIGCHLD, handler); +- sighold(SIGCHLD); ++ sig_mask(SIG_BLOCK); + + /* make children */ + diff --git a/package/system/utils/xfsprogs/patches/130-uclibc_no_xattr.patch b/package/system/utils/xfsprogs/patches/130-uclibc_no_xattr.patch new file mode 100644 index 0000000000..b1ecda71e5 --- /dev/null +++ b/package/system/utils/xfsprogs/patches/130-uclibc_no_xattr.patch @@ -0,0 +1,36 @@ +commit 10d6058b24f18cb31889154f830b191849f45106 +Author: Jens Muecke <jens@nons.de> +Date: Thu Jan 26 00:38:27 2012 +0100 + + 130-uclibc_no_xattr + +diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c +index 40c2e6f..4f54059 100644 +--- a/fsr/xfs_fsr.c ++++ b/fsr/xfs_fsr.c +@@ -35,7 +35,9 @@ + #include <sys/wait.h> + #include <sys/vfs.h> + #include <sys/statvfs.h> ++#ifndef __UCLIBC__ + #include <sys/xattr.h> ++#endif + + + #ifndef XFS_XFLAG_NODEFRAG +@@ -990,6 +992,7 @@ fsr_setup_attr_fork( + int tfd, + xfs_bstat_t *bstatp) + { ++#ifndef __UCLIBC__ + struct stat64 tstatbuf; + int i; + int last_forkoff = 0; +@@ -1108,6 +1111,7 @@ fsr_setup_attr_fork( + out: + if (dflag) + fsrprintf(_("set temp attr\n")); ++#endif + return 0; + } + diff --git a/package/system/utils/xfsprogs/patches/140-no_po.patch b/package/system/utils/xfsprogs/patches/140-no_po.patch new file mode 100644 index 0000000000..f915a9cf27 --- /dev/null +++ b/package/system/utils/xfsprogs/patches/140-no_po.patch @@ -0,0 +1,20 @@ +diff -urN xfsprogs-3.1.7/Makefile xfsprogs-3.1.7.new/Makefile +--- xfsprogs-3.1.7/Makefile 2011-11-18 00:30:24.000000000 +0100 ++++ xfsprogs-3.1.7.new/Makefile 2012-04-20 14:15:48.641722955 +0200 +@@ -41,7 +41,7 @@ + + LIB_SUBDIRS = libxfs libxlog libxcmd libhandle libdisk + TOOL_SUBDIRS = copy db estimate fsck fsr growfs io logprint mkfs quota \ +- mdrestore repair rtcp m4 man doc po debian ++ mdrestore repair rtcp m4 man doc debian + + SUBDIRS = include $(LIB_SUBDIRS) $(TOOL_SUBDIRS) + +@@ -135,7 +135,6 @@ + $(Q)$(MAKE) $(MAKEOPTS) -C . $@ + else + $(Q)$(MAKE) $(MAKEOPTS) $(SRCDIR) +- $(Q)$(MAKE) $(MAKEOPTS) -C po + $(Q)$(MAKE) $(MAKEOPTS) source-link + $(Q)cd $(SRCDIR) && dpkg-buildpackage + endif |