move package/linux into target/linux, use wbx' new kernel code. support building images with more than one kernel, split kernel module parts off of packages that use their own kernel modules (fuse, shfs, openswan). some cleanup in the image building process in target/. image builder is disabled for now, needs some fixing.

SVN-Revision: 1085
lede-17.01
Felix Fietkau 2005-05-28 09:17:29 +00:00
parent ca55f8d3da
commit 269c715804
234 changed files with 1012 additions and 121969 deletions

View File

@ -125,11 +125,5 @@ source "package/sdk/Config.in"
endmenu
menu "Kernel Configuration"
source "package/linux/Config.in"
endmenu
source "package/Sysconf.in"

View File

@ -114,7 +114,7 @@ SDK_DEFAULT_PACKAGES:=busybox dnsmasq iptables wireless-tools dropbear bridge ip
SDK_DEFAULT_COMPILE:=$(patsubst %,%-compile,$(SDK_DEFAULT_PACKAGES))
all: compile install
clean: $(patsubst %,%-clean,$(package-) $(package-y) $(package-m)) linux-clean
clean: $(patsubst %,%-clean,$(package-) $(package-y) $(package-m))
compile: $(patsubst %,%-compile,$(package-y) $(package-m))
install: $(patsubst %,%-install,$(package-y))
@ -200,7 +200,6 @@ ulogd-compile: postgresql-compile
endif
sdk-compile: $(DEV_LIBS_COMPILE) $(SDK_DEFAULT_COMPILE) openwrt-install
$(patsubst %,%-prepare,$(package-y) $(package-m) $(package-)): linux-install
%-prepare:
@[ -f $(STAMP_DIR)/.$@ ] || $(MAKE) -C $(patsubst %-prepare,%,$@) prepare

View File

@ -1,39 +1,14 @@
config BR2_PACKAGE_FUSE
bool
default n
depends BR2_PACKAGE_KMOD_FUSE
config BR2_PACKAGE_KMOD_FUSE
select BR2_PACKAGE_FUSE
prompt "kmod-fuse - FUSE kernel module"
tristate
default m if CONFIG_DEVEL
select BR2_PACKAGE_FUSE
help
With FUSE it is possible to implement a fully functional
filesystem in a userspace program.
Features include:
* Simple library API
* Simple installation (no need to patch or recompile the kernel)
* Secure implementation
* Userspace - kernel interface is very efficient
* Usable by non privileged users
* Runs on Linux kernels 2.4.X and 2.6.X
* Has proven very stable over time
http://fuse.sourceforge.net/
This package contains the fuse.o kernel module.
depends BR2_PACKAGE_LIBFUSE
config BR2_PACKAGE_LIBFUSE
prompt "libfuse - FUSE library"
tristate
default m if CONFIG_DEVEL
depends BR2_PACKAGE_KMOD_FUSE
select BR2_PACKAGE_KMOD_FUSE
select BR2_PACKAGE_LIBPTHREAD
help
With FUSE it is possible to implement a fully functional

View File

@ -16,7 +16,6 @@ PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install
include $(TOPDIR)/package/rules.mk
$(eval $(call PKG_template,KMOD_FUSE,kmod-fuse,$(LINUX_VERSION)+$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
$(eval $(call PKG_template,LIBFUSE,libfuse,$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
$(eval $(call PKG_template,FUSE_UTILS,fuse-utils,$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH)))
@ -69,12 +68,6 @@ $(PKG_BUILD_DIR)/.built:
all install
touch $@
$(IPKG_KMOD_FUSE):
mkdir -p $(IDIR_KMOD_FUSE)/lib/modules/$(LINUX_VERSION)
cp -fpR $(PKG_INSTALL_DIR)/lib/modules/$(LINUX_VERSION)/kernel/fs/fuse/fuse.o \
$(IDIR_KMOD_FUSE)/lib/modules/$(LINUX_VERSION)/
$(IPKG_BUILD) $(IDIR_KMOD_FUSE) $(PACKAGE_DIR)
$(IPKG_LIBFUSE):
mkdir -p $(IDIR_LIBFUSE)/usr/lib
cp -fpR $(PKG_INSTALL_DIR)/usr/lib/libfuse.so.* $(IDIR_LIBFUSE)/usr/lib/

View File

@ -1,175 +0,0 @@
# $Id$
include $(TOPDIR)/rules.mk
include ./linux-2.4/linux.mk
include ./linux-2.4/linux.config
PKG_BUILD_DIR := $(BUILD_DIR)/linux-modules
PKG_RELEASE := 1
TARGETS :=
INSTALL_TARGETS :=
.NOTPARALLEL:
define KMOD_template
ifeq ($$(strip $(4)),)
KDEPEND_$(1):=m
else
KDEPEND_$(1):=$($(4))
endif
PKG_$(1) := $(PACKAGE_DIR)/kmod-$(2)_$(LINUX_VERSION)-$(PKG_RELEASE)_$(ARCH).ipk
I_$(1) := $(PKG_BUILD_DIR)/ipkg/$(2)
ifeq ($$(KDEPEND_$(1)),m)
ifneq ($(BR2_PACKAGE_KMOD_$(1)),)
TARGETS += $$(PKG_$(1))
endif
ifeq ($(BR2_PACKAGE_KMOD_$(1)),y)
INSTALL_TARGETS += $$(PKG_$(1))
endif
endif
$$(PKG_$(1)): $(LINUX_DIR)/.modules_done
mkdir -p $$(I_$(1))/lib/modules/$(LINUX_VERSION)
$(SCRIPT_DIR)/make-ipkg-dir.sh $$(I_$(1)) control/kmod-$(2).control $(LINUX_VERSION)-$(PKG_RELEASE) $(ARCH)
cp $(3) $$(I_$(1))/lib/modules/$(LINUX_VERSION)
$(IPKG_BUILD) $$(I_$(1)) $(PACKAGE_DIR)
endef
$(eval $(call KMOD_template,DIAG,diag,\
$(MODULES_DIR)/kernel/drivers/net/diag/diag.o \
))
$(eval $(call KMOD_template,BRCM_WL,brcm-wl,\
$(MODULES_DIR)/kernel/drivers/net/wl/wl.o \
,CONFIG_WL))
$(eval $(call KMOD_template,B44,b44,\
$(MODULES_DIR)/kernel/drivers/net/b44.o \
,CONFIG_B44))
$(eval $(call KMOD_template,BRCM_ET,brcm-et,\
$(MODULES_DIR)/kernel/drivers/net/et/et.o \
,CONFIG_ET))
$(eval $(call KMOD_template,ARPT,arptables,\
$(MODULES_DIR)/kernel/net/ipv4/netfilter/arp*.o \
,CONFIG_IP_NF_ARPTABLES))
$(eval $(call KMOD_template,EBT,ebtables,\
$(MODULES_DIR)/kernel/net/bridge/netfilter/*.o \
,CONFIG_BRIDGE_NF_EBTABLES))
$(eval $(call KMOD_template,IPTABLES_V4,iptables,\
$(MODULES_DIR)/kernel/net/ipv4/netfilter/ipt_state.o \
$(MODULES_DIR)/kernel/net/ipv4/netfilter/iptable_nat.o \
$(MODULES_DIR)/kernel/net/ipv4/netfilter/ip_nat_ftp.o \
$(MODULES_DIR)/kernel/net/ipv4/netfilter/ipt_conntrack.o \
$(MODULES_DIR)/kernel/net/ipv4/netfilter/ip_conntrack.o \
$(MODULES_DIR)/kernel/net/ipv4/netfilter/ip_conntrack_ftp.o \
$(MODULES_DIR)/kernel/net/ipv4/netfilter/ipt_MASQUERADE.o \
))
$(eval $(call KMOD_template,IPTABLES_V4_EXTRA,iptables-extra,\
$(MODULES_DIR)/kernel/net/ipv4/netfilter/ip*.o \
))
$(eval $(call KMOD_template,IPTABLES_V6,ip6tables,\
$(MODULES_DIR)/kernel/net/ipv6/netfilter/ip*.o \
,CONFIG_IP6_NF_IPTABLES))
$(eval $(call KMOD_template,IPV6,ipv6,\
$(MODULES_DIR)/kernel/net/ipv6/ipv6.o \
,CONFIG_IPV6))
$(eval $(call KMOD_template,CIFS,cifs,\
$(MODULES_DIR)/kernel/fs/cifs/cifs.o \
,CONFIG_CIFS))
$(eval $(call KMOD_template,NFS,nfs,\
$(MODULES_DIR)/kernel/fs/lockd/*.o \
$(MODULES_DIR)/kernel/fs/nfs/*.o \
$(MODULES_DIR)/kernel/net/sunrpc/*.o \
,CONFIG_NFS_FS))
$(eval $(call KMOD_template,USB,usb-core,\
$(MODULES_DIR)/kernel/drivers/usb/usbcore.o \
,CONFIG_USB))
$(eval $(call KMOD_template,USB_UHCI,usb-uhci,\
$(MODULES_DIR)/kernel/drivers/usb/host/uhci.o \
,CONFIG_USB_UHCI_ALT))
$(eval $(call KMOD_template,USB_OHCI,usb-ohci,\
$(MODULES_DIR)/kernel/drivers/usb/host/usb-ohci.o \
,CONFIG_USB_OHCI))
$(eval $(call KMOD_template,USB2,usb2,\
$(MODULES_DIR)/kernel/drivers/usb/host/ehci-hcd.o \
,CONFIG_USB_EHCI_HCD))
$(eval $(call KMOD_template,USB_STORAGE,usb-storage,\
$(MODULES_DIR)/kernel/drivers/scsi/*.o \
$(MODULES_DIR)/kernel/drivers/usb/storage/*.o \
,CONFIG_USB_STORAGE))
$(eval $(call KMOD_template,USB_PRINTER,usb-printer,\
$(MODULES_DIR)/kernel/drivers/usb/printer.o \
,CONFIG_USB_PRINTER))
$(eval $(call KMOD_template,LOOP,loop,\
$(MODULES_DIR)/kernel/drivers/block/loop.o \
,CONFIG_BLK_DEV_LOOP))
$(eval $(call KMOD_template,NBD,nbd,\
$(MODULES_DIR)/kernel/drivers/block/nbd.o \
,CONFIG_BLK_DEV_NBD))
$(eval $(call KMOD_template,LP,lp,\
$(MODULES_DIR)/kernel/drivers/parport/parport.o \
$(MODULES_DIR)/kernel/drivers/parport/parport_splink.o \
$(MODULES_DIR)/kernel/drivers/char/lp.o \
,CONFIG_PARPORT))
$(eval $(call KMOD_template,IDE,ide,\
$(MODULES_DIR)/kernel/drivers/ide/*.o \
$(MODULES_DIR)/kernel/drivers/ide/*/*.o \
,CONFIG_IDE))
$(eval $(call KMOD_template,EXT2,ext2,\
$(MODULES_DIR)/kernel/fs/ext2/*.o \
,CONFIG_EXT2_FS))
$(eval $(call KMOD_template,EXT3,ext3,\
$(MODULES_DIR)/kernel/fs/ext3/*.o \
$(MODULES_DIR)/kernel/fs/jbd/*.o \
,CONFIG_EXT3_FS))
$(eval $(call KMOD_template,XFS,xfs,\
$(MODULES_DIR)/kernel/fs/xfs/*.o \
,CONFIG_XFS_FS))
$(eval $(call KMOD_template,HFSPLUS,hfsplus,\
$(MODULES_DIR)/kernel/fs/hfsplus/*.o \
,CONFIG_HFSPLUS_FS))
$(eval $(call KMOD_template,VFAT,vfat,\
$(MODULES_DIR)/kernel/fs/vfat/vfat.o \
$(MODULES_DIR)/kernel/fs/fat/fat.o \
,CONFIG_VFAT_FS))
$(eval $(call KMOD_template,CRYPTO,crypto,\
$(MODULES_DIR)/kernel/crypto/*.o \
))
$(eval $(call KMOD_template,PPP,ppp,\
$(MODULES_DIR)/kernel/drivers/net/ppp_async.o \
$(MODULES_DIR)/kernel/drivers/net/ppp_generic.o \
$(MODULES_DIR)/kernel/drivers/net/slhc.o \
,CONFIG_PPP))
$(eval $(call KMOD_template,MPPE,mppe,\
$(MODULES_DIR)/kernel/drivers/net/ppp_mppe_mppc.o \
,CONFIG_PPP_MPPE_MPPC))
$(eval $(call KMOD_template,PPPOE,pppoe,\
$(MODULES_DIR)/kernel/drivers/net/pppoe.o \
$(MODULES_DIR)/kernel/drivers/net/pppox.o \
,CONFIG_PPPOE))
$(eval $(call KMOD_template,TUN,tun,\
$(MODULES_DIR)/kernel/drivers/net/tun.o \
,CONFIG_TUN))
$(eval $(call KMOD_template,GRE,gre,\
$(MODULES_DIR)/kernel/net/ipv4/ip_gre.o \
,CONFIG_NET_IPGRE))
$(eval $(call KMOD_template,SCHED,sched,\
$(MODULES_DIR)/kernel/net/sched/*.o \
))
$(TARGETS): $(PACKAGE_DIR)
$(PACKAGE_DIR):
mkdir -p $(PACKAGE_DIR)
source: linux-source
prepare: $(LINUX_DIR)/.configured
compile: $(LINUX_DIR)/.modules_done $(TARGETS)
install: compile $(TARGET_MODULES_DIR)
@[ "$(INSTALL_TARGETS)" != "" ] && $(IPKG) install $(INSTALL_TARGETS) || true
clean: linux-dirclean
rm -f $(TARGETS)

View File

@ -1,43 +0,0 @@
--- ../../../kernel/linux-mips-cvs/Makefile 2005-01-20 03:19:21.000000000 +0100
+++ linux-2.4.29.new/Makefile 2005-03-15 01:15:27.441095231 +0100
@@ -17,9 +17,9 @@
FINDHPATH = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net $(HPATH)/math-emu
HOSTCC = gcc
-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+HOSTCFLAGS = -Wall -Wstrict-prototypes -Os -fomit-frame-pointer
-CROSS_COMPILE =
+CROSS_COMPILE=
#
# Include the make variables (CC, etc...)
@@ -91,8 +91,18 @@
CPPFLAGS := -D__KERNEL__ -I$(HPATH)
-CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
+CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -Os \
-fno-strict-aliasing -fno-common
+
+
+# Turn on -pg to instrument the kernel with calls to mcount().
+# Unfortunately, gcc won't allow -pg without frame pointers.
+ifdef CONFIG_MCOUNT
+ CFLAGS += -pg
+ CFLAGS_KERNEL += -pg
+ CONFIG_FRAME_POINTER = 1
+endif
+
ifndef CONFIG_FRAME_POINTER
CFLAGS += -fomit-frame-pointer
endif
@@ -501,7 +511,7 @@
ifdef CONFIG_MODVERSIONS
$(MAKE) update-modverfile
endif
- scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
+ (find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print | xargs -r scripts/mkdep -- ) > .hdepend
scripts/mkdep -- init/*.c > .depend
ifdef CONFIG_MODVERSIONS

View File

@ -1,18 +0,0 @@
--- linux-mips-cvs/Rules.make 2003-08-13 17:39:03.000000000 +0200
+++ linux-broadcom/Rules.make 2005-01-31 13:13:14.000000000 +0100
@@ -176,7 +176,14 @@
_modinst__: dummy
ifneq "$(strip $(ALL_MOBJS))" ""
mkdir -p $(MODLIB)/kernel/$(MOD_DESTDIR)
- cp $(sort $(ALL_MOBJS)) $(MODLIB)/kernel/$(MOD_DESTDIR)
+ @#cp $(sort $(ALL_MOBJS)) $(MODLIB)/kernel/$(MOD_DESTDIR)
+ for f in $(ALL_MOBJS) ; do \
+ $(OBJCOPY) -R __ksymtab -R .comment -R .note -x \
+ `$(NM) $$f | cut -f3- -d' ' | sed -n \
+ -e 's/__module_parm_\(.*\)/-K \1/p' \
+ -e 's/__ks..tab_\(.*\)/-K \1/p'` \
+ $$f $(MODLIB)/kernel/$(MOD_DESTDIR)$(MOD_TARGET)$$f ; \
+ done
endif
.PHONY: modules_install

View File

@ -1,42 +0,0 @@
--- linux-mips-cvs/arch/mips/Makefile 2005-01-31 12:59:28.000000000 +0100
+++ linux-broadcom/arch/mips/Makefile 2005-01-31 13:13:14.000000000 +0100
@@ -47,9 +47,9 @@
GCCFLAGS += -G 0 -mno-abicalls -fno-pic -pipe
GCCFLAGS += $(call check_gcc, -finline-limit=100000,)
LINKFLAGS += -G 0 -static -n
-MODFLAGS += -mlong-calls
+MODFLAGS += -mlong-calls -fno-common
-ifdef CONFIG_DEBUG_INFO
+ifdef CONFIG_REMOTE_DEBUG
GCCFLAGS += -g
ifdef CONFIG_SB1XXX_CORELIS
GCCFLAGS += -mno-sched-prolog -fno-omit-frame-pointer
@@ -174,6 +174,7 @@
endif
AFLAGS += $(GCCFLAGS)
+ASFLAGS += $(GCCFLAGS)
CFLAGS += $(GCCFLAGS)
LD += -m $(ld-emul)
@@ -727,6 +728,19 @@
endif
#
+# Broadcom BCM947XX variants
+#
+ifdef CONFIG_BCM947XX
+LIBS += arch/mips/brcm-boards/generic/brcm.o arch/mips/brcm-boards/bcm947xx/bcm947xx.o
+SUBDIRS += arch/mips/brcm-boards/generic arch/mips/brcm-boards/bcm947xx
+LOADADDR := 0x80001000
+
+zImage: vmlinux
+ $(MAKE) -C arch/$(ARCH)/brcm-boards/bcm947xx/compressed
+export LOADADDR
+endif
+
+#
# Choosing incompatible machines durings configuration will result in
# error messages during linking. Select a default linkscript if
# none has been choosen above.

View File

@ -1,56 +0,0 @@
--- ../../../kernel/linux-mips-cvs/arch/mips/config-shared.in 2005-01-31 12:59:28.000000000 +0100
+++ linux-2.4.29/arch/mips/config-shared.in 2005-03-12 19:51:22.474214917 +0100
@@ -208,6 +208,14 @@
fi
define_bool CONFIG_MIPS_RTC y
fi
+dep_bool 'Support for Broadcom MIPS-based boards' CONFIG_MIPS_BRCM $CONFIG_EXPERIMENTAL
+dep_bool 'Support for Broadcom BCM947XX' CONFIG_BCM947XX $CONFIG_MIPS_BRCM
+if [ "$CONFIG_BCM947XX" = "y" ] ; then
+ bool ' Support for Broadcom BCM4710' CONFIG_BCM4710
+ bool ' Support for Broadcom BCM4310' CONFIG_BCM4310
+ bool ' Support for Broadcom BCM4704' CONFIG_BCM4704
+ bool ' Support for Broadcom BCM5365' CONFIG_BCM5365
+fi
bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226
bool 'Support for TANBAC TB0229 (VR4131DIMM)' CONFIG_TANBAC_TB0229
@@ -229,6 +237,11 @@
define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
#
+# Provide an option for a default kernel command line
+#
+string 'Default kernel command string' CONFIG_CMDLINE ""
+
+#
# Select some configuration options automatically based on user selections.
#
if [ "$CONFIG_ACER_PICA_61" = "y" ]; then
@@ -554,6 +567,13 @@
define_bool CONFIG_SWAP_IO_SPACE_L y
define_bool CONFIG_BOOT_ELF32 y
fi
+if [ "$CONFIG_BCM947XX" = "y" ] ; then
+ define_bool CONFIG_PCI y
+ define_bool CONFIG_NONCOHERENT_IO y
+ define_bool CONFIG_NEW_TIME_C y
+ define_bool CONFIG_NEW_IRQ y
+ define_bool CONFIG_HND y
+fi
if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
define_bool CONFIG_ARC32 y
define_bool CONFIG_ARC_MEMORY y
@@ -1039,7 +1059,11 @@
bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG
-bool 'Remote GDB kernel debugging' CONFIG_KGDB
+if [ "$CONFIG_BCM947XX" = "y" ] ; then
+ bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG
+else
+ bool 'Remote GDB kernel debugging' CONFIG_KGDB
+fi
dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB
if [ "$CONFIG_KGDB" = "y" ]; then
define_bool CONFIG_DEBUG_INFO y

View File

@ -1,121 +0,0 @@
--- linux-mips-cvs/arch/mips/kernel/cpu-probe.c 2005-01-31 12:59:30.000000000 +0100
+++ linux-broadcom/arch/mips/kernel/cpu-probe.c 2005-01-31 13:13:14.000000000 +0100
@@ -175,7 +175,7 @@
static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
{
- switch (c->processor_id & 0xff00) {
+ switch (c->processor_id & PRID_IMP_MASK) {
case PRID_IMP_R2000:
c->cputype = CPU_R2000;
c->isa_level = MIPS_CPU_ISA_I;
@@ -185,7 +185,7 @@
c->tlbsize = 64;
break;
case PRID_IMP_R3000:
- if ((c->processor_id & 0xff) == PRID_REV_R3000A)
+ if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A)
if (cpu_has_confreg())
c->cputype = CPU_R3081E;
else
@@ -200,12 +200,12 @@
break;
case PRID_IMP_R4000:
if (read_c0_config() & CONF_SC) {
- if ((c->processor_id & 0xff) >= PRID_REV_R4400)
+ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400)
c->cputype = CPU_R4400PC;
else
c->cputype = CPU_R4000PC;
} else {
- if ((c->processor_id & 0xff) >= PRID_REV_R4400)
+ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400)
c->cputype = CPU_R4400SC;
else
c->cputype = CPU_R4000SC;
@@ -451,7 +451,7 @@
static inline void cpu_probe_mips(struct cpuinfo_mips *c)
{
decode_config1(c);
- switch (c->processor_id & 0xff00) {
+ switch (c->processor_id & PRID_IMP_MASK) {
case PRID_IMP_4KC:
c->cputype = CPU_4KC;
c->isa_level = MIPS_CPU_ISA_M32;
@@ -492,10 +492,10 @@
{
decode_config1(c);
c->options |= MIPS_CPU_PREFETCH;
- switch (c->processor_id & 0xff00) {
+ switch (c->processor_id & PRID_IMP_MASK) {
case PRID_IMP_AU1_REV1:
case PRID_IMP_AU1_REV2:
- switch ((c->processor_id >> 24) & 0xff) {
+ switch ((c->processor_id >> 24) & PRID_REV_MASK) {
case 0:
c->cputype = CPU_AU1000;
break;
@@ -523,10 +523,34 @@
}
}
+static inline void cpu_probe_broadcom(struct cpuinfo_mips *c)
+{
+ decode_config1(c);
+ c->options |= MIPS_CPU_PREFETCH;
+ switch (c->processor_id & PRID_IMP_MASK) {
+ case PRID_IMP_BCM4710:
+ c->cputype = CPU_BCM4710;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
+ c->scache.flags = MIPS_CACHE_NOT_PRESENT;
+ break;
+ case PRID_IMP_4KC:
+ case PRID_IMP_BCM3302:
+ c->cputype = CPU_BCM3302;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
+ c->scache.flags = MIPS_CACHE_NOT_PRESENT;
+ break;
+ default:
+ c->cputype = CPU_UNKNOWN;
+ break;
+ }
+}
+
static inline void cpu_probe_sibyte(struct cpuinfo_mips *c)
{
decode_config1(c);
- switch (c->processor_id & 0xff00) {
+ switch (c->processor_id & PRID_IMP_MASK) {
case PRID_IMP_SB1:
c->cputype = CPU_SB1;
c->isa_level = MIPS_CPU_ISA_M64;
@@ -548,7 +572,7 @@
static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
{
decode_config1(c);
- switch (c->processor_id & 0xff00) {
+ switch (c->processor_id & PRID_IMP_MASK) {
case PRID_IMP_SR71000:
c->cputype = CPU_SR71000;
c->isa_level = MIPS_CPU_ISA_M64;
@@ -573,7 +597,7 @@
c->cputype = CPU_UNKNOWN;
c->processor_id = read_c0_prid();
- switch (c->processor_id & 0xff0000) {
+ switch (c->processor_id & PRID_COMP_MASK) {
case PRID_COMP_LEGACY:
cpu_probe_legacy(c);
@@ -584,6 +608,9 @@
case PRID_COMP_ALCHEMY:
cpu_probe_alchemy(c);
break;
+ case PRID_COMP_BROADCOM:
+ cpu_probe_broadcom(c);
+ break;
case PRID_COMP_SIBYTE:
cpu_probe_sibyte(c);
break;

View File

@ -1,24 +0,0 @@
--- linux-mips-cvs/arch/mips/kernel/head.S 2004-11-22 14:38:23.000000000 +0100
+++ linux-broadcom/arch/mips/kernel/head.S 2005-01-31 13:13:14.000000000 +0100
@@ -28,12 +28,20 @@
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
+#ifdef CONFIG_BCM4710
+#undef eret
+#define eret nop; nop; eret
+#endif
+
.text
+ j kernel_entry
+ nop
+
/*
* Reserved space for exception handlers.
* Necessary for machines which link their kernels at KSEG0.
*/
- .fill 0x400
+ .fill 0x3f4
/* The following two symbols are used for kernel profiling. */
EXPORT(stext)

View File

@ -1,14 +0,0 @@
--- linux-mips-cvs/arch/mips/kernel/proc.c 2004-07-07 20:19:37.000000000 +0200
+++ linux-broadcom/arch/mips/kernel/proc.c 2005-01-31 13:58:35.000000000 +0100
@@ -78,9 +78,10 @@
[CPU_AU1550] "Au1550",
[CPU_24K] "MIPS 24K",
[CPU_AU1200] "Au1200",
+ [CPU_BCM4710] "BCM4710",
+ [CPU_BCM3302] "BCM3302",
};
-
static int show_cpuinfo(struct seq_file *m, void *v)
{
unsigned int version = current_cpu_data.processor_id;

View File

@ -1,22 +0,0 @@
--- linux-mips-cvs/arch/mips/kernel/setup.c 2005-01-13 22:15:57.000000000 +0100
+++ linux-broadcom/arch/mips/kernel/setup.c 2005-01-31 13:13:14.000000000 +0100
@@ -493,6 +493,7 @@
void swarm_setup(void);
void hp_setup(void);
void au1x00_setup(void);
+ void brcm_setup(void);
void frame_info_init(void);
frame_info_init();
@@ -691,6 +692,11 @@
pmc_yosemite_setup();
break;
#endif
+#if defined(CONFIG_BCM4710) || defined(CONFIG_BCM4310)
+ case MACH_GROUP_BRCM:
+ brcm_setup();
+ break;
+#endif
default:
panic("Unsupported architecture");
}

View File

@ -1,31 +0,0 @@
--- linux-mips-cvs/arch/mips/kernel/traps.c 2004-11-22 14:38:23.000000000 +0100
+++ linux-broadcom/arch/mips/kernel/traps.c 2005-01-31 13:13:14.000000000 +0100
@@ -919,6 +919,7 @@
void __init trap_init(void)
{
extern char except_vec1_generic;
+ extern char except_vec2_generic;
extern char except_vec3_generic, except_vec3_r4000;
extern char except_vec_ejtag_debug;
extern char except_vec4;
@@ -926,6 +927,7 @@
/* Copy the generic exception handler code to it's final destination. */
memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80);
+ memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
/*
* Setup default vectors
@@ -984,6 +986,12 @@
set_except_vector(13, handle_tr);
set_except_vector(22, handle_mdmx);
+ if (current_cpu_data.cputype == CPU_SB1) {
+ /* Enable timer interrupt and scd mapped interrupt */
+ clear_c0_status(0xf000);
+ set_c0_status(0xc00);
+ }
+
if (cpu_has_fpu && !cpu_has_nofpuex)
set_except_vector(15, handle_fpe);

View File

@ -1,12 +0,0 @@
--- linux-mips-cvs/arch/mips/pci/Makefile 2004-07-31 02:12:38.000000000 +0200
+++ linux-broadcom/arch/mips/pci/Makefile 2005-01-31 13:13:14.000000000 +0100
@@ -13,7 +13,9 @@
obj-$(CONFIG_MIPS_MSC) += ops-msc.o
obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o
obj-$(CONFIG_SNI_RM200_PCI) += ops-sni.o
+ifndef CONFIG_BCM947XX
obj-y += pci.o
+endif
obj-$(CONFIG_PCI_AUTO) += pci_auto.o
include $(TOPDIR)/Rules.make

View File

@ -1,12 +0,0 @@
--- linux-mips-cvs/drivers/char/mem.c 2004-08-14 20:38:49.000000000 +0200
+++ linux-broadcom/drivers/char/mem.c 2005-01-31 13:13:14.000000000 +0100
@@ -713,7 +713,8 @@
{1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
{2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
{3, "null", S_IRUGO | S_IWUGO, &null_fops},
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if defined(CONFIG_ISA) || !defined(__mc68000__) || \
+ defined(CONFIG_BCM94702_CPCI)
{4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
#endif
{5, "zero", S_IRUGO | S_IWUGO, &zero_fops},

View File

@ -1,37 +0,0 @@
--- linux-mips-cvs/drivers/char/serial.c 2004-12-27 05:13:43.000000000 +0100
+++ linux-broadcom/drivers/char/serial.c 2005-01-31 13:13:14.000000000 +0100
@@ -444,6 +444,10 @@
return inb(info->port+1);
#endif
case SERIAL_IO_MEM:
+#ifdef CONFIG_BCM4310
+ readb((unsigned long) info->iomem_base +
+ (UART_SCR<<info->iomem_reg_shift));
+#endif
return readb((unsigned long) info->iomem_base +
(offset<<info->iomem_reg_shift));
default:
@@ -464,6 +468,9 @@
case SERIAL_IO_MEM:
writeb(value, (unsigned long) info->iomem_base +
(offset<<info->iomem_reg_shift));
+#ifdef CONFIG_BCM4704
+ *((volatile unsigned int *) KSEG1ADDR(0x18000000));
+#endif
break;
default:
outb(value, info->port+offset);
@@ -5996,6 +6003,13 @@
* Divisor, bytesize and parity
*/
state = rs_table + co->index;
+ /*
+ * Safe guard: state structure must have been initialized
+ */
+ if (state->iomem_base == NULL) {
+ printk("!unable to setup serial console!\n");
+ return -1;
+ }
if (doflow)
state->flags |= ASYNC_CONS_FLOW;
info = &async_sercons;

View File

@ -1,105 +0,0 @@
diff -Nur linux-mips-cvs/drivers/mtd/chips/Config.in linux-broadcom/drivers/mtd/chips/Config.in
--- linux-mips-cvs/drivers/mtd/chips/Config.in 2003-02-26 01:53:49.000000000 +0100
+++ linux-broadcom/drivers/mtd/chips/Config.in 2005-01-31 13:13:14.000000000 +0100
@@ -45,6 +45,7 @@
dep_tristate ' Support for Intel/Sharp flash chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_GEN_PROBE
dep_tristate ' Support for AMD/Fujitsu flash chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_GEN_PROBE
dep_tristate ' Support for ST (Advanced Architecture) flash chips' CONFIG_MTD_CFI_STAA $CONFIG_MTD_GEN_PROBE
+dep_tristate ' Support for SST flash chips' CONFIG_MTD_CFI_SSTSTD $CONFIG_MTD_GEN_PROBE
dep_tristate ' Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD
dep_tristate ' Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD
diff -Nur linux-mips-cvs/drivers/mtd/chips/Makefile linux-broadcom/drivers/mtd/chips/Makefile
--- linux-mips-cvs/drivers/mtd/chips/Makefile 2003-07-05 05:23:38.000000000 +0200
+++ linux-broadcom/drivers/mtd/chips/Makefile 2005-01-31 13:13:14.000000000 +0100
@@ -18,6 +18,7 @@
obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
obj-$(CONFIG_MTD_CFI) += cfi_probe.o
obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o
+obj-$(CONFIG_MTD_CFI_SSTSTD) += cfi_cmdset_0701.o
obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o
obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o
obj-$(CONFIG_MTD_GEN_PROBE) += gen_probe.o
diff -Nur linux-mips-cvs/drivers/mtd/chips/cfi_probe.c linux-broadcom/drivers/mtd/chips/cfi_probe.c
--- linux-mips-cvs/drivers/mtd/chips/cfi_probe.c 2003-02-26 01:53:49.000000000 +0100
+++ linux-broadcom/drivers/mtd/chips/cfi_probe.c 2005-01-31 13:13:14.000000000 +0100
@@ -67,8 +67,15 @@
cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
- if (!qry_present(map,base,cfi))
- return 0;
+ if (!qry_present(map,base,cfi)) {
+ /* rather broken SST cfi probe (requires SST unlock) */
+ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+ cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
+ cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
+ cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
+ if (!qry_present(map,base,cfi))
+ return 0;
+ }
if (!cfi->numchips) {
/* This is the first time we're called. Set up the CFI
diff -Nur linux-mips-cvs/drivers/mtd/chips/gen_probe.c linux-broadcom/drivers/mtd/chips/gen_probe.c
--- linux-mips-cvs/drivers/mtd/chips/gen_probe.c 2003-08-13 19:19:18.000000000 +0200
+++ linux-broadcom/drivers/mtd/chips/gen_probe.c 2005-01-31 13:13:14.000000000 +0100
@@ -332,9 +332,13 @@
return cfi_cmdset_0002(map, primary);
#endif
#ifdef CONFIG_MTD_CFI_STAA
- case 0x0020:
+ case 0x0020:
return cfi_cmdset_0020(map, primary);
#endif
+#ifdef CONFIG_MTD_CFI_SSTSTD
+ case 0x0701:
+ return cfi_cmdset_0701(map, primary);
+#endif
}
return cfi_cmdset_unknown(map, primary);
diff -Nur linux-mips-cvs/drivers/mtd/devices/Config.in linux-broadcom/drivers/mtd/devices/Config.in
--- linux-mips-cvs/drivers/mtd/devices/Config.in 2003-02-26 01:53:49.000000000 +0100
+++ linux-broadcom/drivers/mtd/devices/Config.in 2005-01-31 13:13:14.000000000 +0100
@@ -5,6 +5,7 @@
mainmenu_option next_comment
comment 'Self-contained MTD device drivers'
+bool ' Broadcom Chipcommon Serial Flash support' CONFIG_MTD_SFLASH
dep_tristate ' Ramix PMC551 PCI Mezzanine RAM card support' CONFIG_MTD_PMC551 $CONFIG_MTD $CONFIG_PCI
if [ "$CONFIG_MTD_PMC551" = "y" -o "$CONFIG_MTD_PMC551" = "m" ]; then
bool ' PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX
diff -Nur linux-mips-cvs/drivers/mtd/devices/Makefile linux-broadcom/drivers/mtd/devices/Makefile
--- linux-mips-cvs/drivers/mtd/devices/Makefile 2002-03-30 09:15:50.000000000 +0100
+++ linux-broadcom/drivers/mtd/devices/Makefile 2005-01-31 13:13:14.000000000 +0100
@@ -12,6 +12,7 @@
# here where previously there was none. We now have to ensure that
# doc200[01].o are linked before docprobe.o
+obj-$(CONFIG_MTD_SFLASH) += sflash.o
obj-$(CONFIG_MTD_DOC1000) += doc1000.o
obj-$(CONFIG_MTD_DOC2000) += doc2000.o
obj-$(CONFIG_MTD_DOC2001) += doc2001.o
diff -Nur linux-mips-cvs/drivers/mtd/maps/Config.in linux-broadcom/drivers/mtd/maps/Config.in
--- linux-mips-cvs/drivers/mtd/maps/Config.in 2004-02-26 01:46:35.000000000 +0100
+++ linux-broadcom/drivers/mtd/maps/Config.in 2005-01-31 13:13:14.000000000 +0100
@@ -48,6 +48,7 @@
fi
if [ "$CONFIG_MIPS" = "y" ]; then
+ dep_tristate ' CFI Flash device mapped on Broadcom BCM947XX boards' CONFIG_MTD_BCM947XX $CONFIG_MTD_CFI
dep_tristate ' Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000
dep_tristate ' Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500
dep_tristate ' Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100
diff -Nur linux-mips-cvs/drivers/mtd/maps/Makefile linux-broadcom/drivers/mtd/maps/Makefile
--- linux-mips-cvs/drivers/mtd/maps/Makefile 2004-02-26 01:46:35.000000000 +0100
+++ linux-broadcom/drivers/mtd/maps/Makefile 2005-01-31 13:13:14.000000000 +0100
@@ -10,6 +10,7 @@
endif
# Chip mappings
+obj-$(CONFIG_MTD_BCM947XX) += bcm947xx-flash.o
obj-$(CONFIG_MTD_CDB89712) += cdb89712.o
obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o

View File

@ -1,10 +0,0 @@
--- linux-mips-cvs/drivers/net/Config.in 2004-11-07 18:13:42.000000000 +0100
+++ linux-broadcom/drivers/net/Config.in 2005-01-31 13:13:14.000000000 +0100
@@ -2,6 +2,7 @@
# Network device configuration
#
+source drivers/net/hnd/Config.in
source drivers/net/arcnet/Config.in
tristate 'Dummy net driver support' CONFIG_DUMMY

View File

@ -1,48 +0,0 @@
--- ../../../kernel/linux-mips-cvs/drivers/net/Makefile 2004-08-14 20:38:51.000000000 +0200
+++ linux/drivers/net/Makefile 2005-03-16 12:45:24.523263597 +0100
@@ -21,6 +21,16 @@
list-multi := rcpci.o
rcpci-objs := rcpci45.o rclanmtl.o
+subdir-m += diag
+
+ifeq ($(CONFIG_HW_QOS),y)
+subdir-m += port_based_qos
+else
+ ifeq ($(CONFIG_PERFORMANCE),y)
+ subdir-m += port_based_qos
+ endif
+endif
+
ifeq ($(CONFIG_TULIP),y)
obj-y += tulip/tulip.o
endif
@@ -265,6 +275,28 @@
endif
endif
+#
+# Broadcom HND devices
+#
+ifdef CONFIG_HND
+subdir-$(CONFIG_HND) += hnd
+endif
+ifdef CONFIG_ET
+subdir-$(CONFIG_ET) += et
+endif
+ifdef CONFIG_WL
+subdir-$(CONFIG_WL) += wl
+endif
+ifeq ($(CONFIG_HND),y)
+ obj-y += hnd/hnd.o
+endif
+ifeq ($(CONFIG_ET),y)
+ obj-y += et/et.o
+endif
+ifeq ($(CONFIG_WL),y)
+ obj-y += wl/wl.o
+endif
+
include $(TOPDIR)/Rules.make
clean:

View File

@ -1,10 +0,0 @@
--- ../../../kernel/linux-mips-cvs/drivers/parport/Makefile 2004-08-14 20:38:53.000000000 +0200
+++ linux-2.4.29/drivers/parport/Makefile 2005-03-21 13:57:53.338746517 +0100
@@ -22,6 +22,7 @@
obj-$(CONFIG_PARPORT) += parport.o
obj-$(CONFIG_PARPORT_PC) += parport_pc.o
+obj-$(CONFIG_PARPORT_SPLINK) += parport_splink.o
obj-$(CONFIG_PARPORT_PC_PCMCIA) += parport_cs.o
obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o
obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o

View File

@ -1,10 +0,0 @@
--- ../../../kernel/linux-mips-cvs/drivers/parport/Config.in 2004-02-20 02:22:18.000000000 +0100
+++ linux-2.4.29/drivers/parport/Config.in 2005-03-21 13:59:33.958193664 +0100
@@ -11,6 +11,7 @@
tristate 'Parallel port support' CONFIG_PARPORT
if [ "$CONFIG_PARPORT" != "n" ]; then
dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
+ dep_tristate ' Asus WL500g parallel port' CONFIG_PARPORT_SPLINK $CONFIG_PARPORT
if [ "$CONFIG_PARPORT_PC" != "n" -a "$CONFIG_SERIAL" != "n" ]; then
if [ "$CONFIG_SERIAL" = "m" ]; then
define_tristate CONFIG_PARPORT_PC_CML1 m

View File

@ -1,23 +0,0 @@
diff -Nur linux-mips-cvs/drivers/pcmcia/Makefile linux-broadcom/drivers/pcmcia/Makefile
--- linux-mips-cvs/drivers/pcmcia/Makefile 2004-04-16 23:05:25.000000000 +0200
+++ linux-broadcom/drivers/pcmcia/Makefile 2005-01-31 13:13:14.000000000 +0100
@@ -72,6 +72,10 @@
au1000_ss-objs-$(CONFIG_MIPS_HYDROGEN3) += au1000_hydrogen3.o
au1000_ss-objs-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o
+obj-$(CONFIG_PCMCIA_BCM4710) += bcm4710_ss.o
+bcm4710_ss-objs := bcm4710_generic.o
+bcm4710_ss-objs += bcm4710_pcmcia.o
+
obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
obj-$(CONFIG_PCMCIA_SIBYTE) += sibyte_generic.o
@@ -110,5 +114,8 @@
au1x00_ss.o: $(au1000_ss-objs-y)
$(LD) -r -o $@ $(au1000_ss-objs-y)
+bcm4710_ss.o: $(bcm4710_ss-objs)
+ $(LD) -r -o $@ $(bcm4710_ss-objs)
+
yenta_socket.o: $(yenta_socket-objs)
$(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs)

View File

@ -1,37 +0,0 @@
--- linux-mips-cvs/arch/mips/mm/c-r4k.c 2004-11-03 17:43:07.000000000 +0100
+++ linux-cache/arch/mips/mm/c-r4k.c 2005-03-06 23:39:53.000000000 +0100
@@ -1031,9 +1031,34 @@
c->options |= MIPS_CPU_SUBSET_CACHES;
}
+#if defined(CONFIG_BCM4310)
+static void __init _change_cachability(u32 cm)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ change_c0_config(CONF_CM_CMASK, cm);
+ if ((c->processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) ==
+ (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) {
+ cm = read_c0_diag();
+ /* Enable icache */
+ cm |= (1 << 31);
+ /* Enable dcache */
+ cm |= (1 << 30);
+ write_c0_diag(cm);
+ }
+}
+
+static void (*change_cachability)(u32);
+#endif
+
static inline void coherency_setup(void)
{
+#if defined(CONFIG_BCM4310)
+ change_cachability = (void (*)(u32)) KSEG1ADDR((unsigned long)(_change_cachability));
+ change_cachability(CONF_CM_DEFAULT);
+#else
change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
+#endif
/*
* c0_status.cu=0 specifies that updates by the sc instruction use

View File

@ -1,26 +0,0 @@
--- linux-mips-cvs/include/asm-mips/bootinfo.h 2005-01-31 12:59:49.000000000 +0100
+++ linux-broadcom/include/asm-mips/bootinfo.h 2005-01-31 13:13:14.000000000 +0100
@@ -37,6 +37,7 @@
#define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */
#define MACH_GROUP_LASAT 21
#define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */
+#define MACH_GROUP_BRCM 23 /* Broadcom */
/*
* Valid machtype values for group unknown (low order halfword of mips_machtype)
@@ -197,6 +198,15 @@
#define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */
/*
+ * Valid machtypes for group Broadcom
+ */
+#define MACH_BCM93725 0
+#define MACH_BCM93725_VJ 1
+#define MACH_BCM93730 2
+#define MACH_BCM947XX 3
+#define MACH_BCM933XX 4
+
+/*
* Valid machtype for group TITAN
*/
#define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */

View File

@ -1,50 +0,0 @@
--- linux-mips-cvs/include/asm-mips/cpu.h 2004-07-07 20:19:37.000000000 +0200
+++ linux-broadcom/include/asm-mips/cpu.h 2005-01-31 13:13:14.000000000 +0100
@@ -22,6 +22,11 @@
spec.
*/
+#define PRID_COPT_MASK 0xff000000
+#define PRID_COMP_MASK 0x00ff0000
+#define PRID_IMP_MASK 0x0000ff00
+#define PRID_REV_MASK 0x000000ff
+
#define PRID_COMP_LEGACY 0x000000
#define PRID_COMP_MIPS 0x010000
#define PRID_COMP_BROADCOM 0x020000
@@ -58,6 +63,7 @@
#define PRID_IMP_RM7000 0x2700
#define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */
#define PRID_IMP_RM9000 0x3400
+#define PRID_IMP_BCM4710 0x4000
#define PRID_IMP_R5432 0x5400
#define PRID_IMP_R5500 0x5500
#define PRID_IMP_4KC 0x8000
@@ -66,10 +72,16 @@
#define PRID_IMP_4KEC 0x8400
#define PRID_IMP_4KSC 0x8600
#define PRID_IMP_25KF 0x8800
+#define PRID_IMP_BCM3302 0x9000
+#define PRID_IMP_BCM3303 0x9100
#define PRID_IMP_24K 0x9300
#define PRID_IMP_UNKNOWN 0xff00
+#define BCM330X(id) \
+ (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \
+ || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303)))
+
/*
* These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
*/
@@ -174,7 +186,9 @@
#define CPU_AU1550 57
#define CPU_24K 58
#define CPU_AU1200 59
-#define CPU_LAST 59
+#define CPU_BCM4710 60
+#define CPU_BCM3302 61
+#define CPU_LAST 61
/*
* ISA Level encodings

View File

@ -1,24 +0,0 @@
--- linux-mips-cvs/include/asm-mips/serial.h 2004-08-20 00:33:33.000000000 +0200
+++ linux-broadcom/include/asm-mips/serial.h 2005-01-31 13:13:14.000000000 +0100
@@ -223,6 +223,13 @@
#define TXX927_SERIAL_PORT_DEFNS
#endif
+#ifdef CONFIG_BCM947XX
+/* reserve 4 ports to be configured at runtime */
+#define BCM947XX_SERIAL_PORT_DEFNS { 0, }, { 0, }, { 0, }, { 0, },
+#else
+#define BCM947XX_SERIAL_PORT_DEFNS
+#endif
+
#ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT
#define STD_SERIAL_PORT_DEFNS \
/* UART CLK PORT IRQ FLAGS */ \
@@ -470,6 +477,7 @@
#define SERIAL_PORT_DFNS \
ATLAS_SERIAL_PORT_DEFNS \
AU1000_SERIAL_PORT_DEFNS \
+ BCM947XX_SERIAL_PORT_DEFNS \
COBALT_SERIAL_PORT_DEFNS \
DDB5477_SERIAL_PORT_DEFNS \
EV96100_SERIAL_PORT_DEFNS \

View File

@ -1,16 +0,0 @@
--- linux-mips-cvs/init/do_mounts.c 2005-01-20 03:19:24.000000000 +0100
+++ linux-broadcom/init/do_mounts.c 2005-01-31 13:13:14.000000000 +0100
@@ -253,7 +253,13 @@
{ "ftlb", 0x2c08 },
{ "ftlc", 0x2c10 },
{ "ftld", 0x2c18 },
+#if defined(CONFIG_MTD_BLOCK) || defined(CONFIG_MTD_BLOCK_RO)
{ "mtdblock", 0x1f00 },
+ { "mtdblock0",0x1f00 },
+ { "mtdblock1",0x1f01 },
+ { "mtdblock2",0x1f02 },
+ { "mtdblock3",0x1f03 },
+#endif
{ "nb", 0x2b00 },
{ NULL, 0 }
};

View File

@ -1,28 +0,0 @@
--- linux-mips-cvs-21012005/arch/mips/Makefile 2004-11-18 05:16:52.000000000 +0100
+++ linux-broadcom/arch/mips/Makefile 2005-01-24 02:56:02.000000000 +0100
@@ -71,13 +74,13 @@
set_gccflags = $(shell \
while :; do \
cpu=$(1); isa=-$(2); \
- for gcc_opt in -march= -mcpu=; do \
+ for gcc_opt in -march= -mtune=; do \
$(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \
-xc /dev/null > /dev/null 2>&1 && \
break 2; \
done; \
cpu=$(3); isa=-$(4); \
- for gcc_opt in -march= -mcpu=; do \
+ for gcc_opt in -march= -mtune=; do \
$(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \
-xc /dev/null > /dev/null 2>&1 && \
break 2; \
@@ -92,7 +95,7 @@
fi; \
gas_abi=-Wa,-32; gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \
while :; do \
- for gas_opt in -Wa,-march= -Wa,-mcpu=; do \
+ for gas_opt in -Wa,-march= -Wa,-mtune=; do \
$(CC) $$gas_abi $$gas_opt$$cpu $$gas_isa -Wa,-Z -c \
-o /dev/null -xassembler /dev/null > /dev/null 2>&1 && \
break 2; \

View File

@ -1,28 +0,0 @@
--- linux-mips-cvs-21012005/include/linux/netdevice.h 2004-11-19 01:28:51.000000000 +0100
+++ linux-broadcom/include/linux/netdevice.h 2005-01-26 19:51:37.000000000 +0100
@@ -297,7 +297,10 @@
* See <net/iw_handler.h> for details. Jean II */
struct iw_handler_def * wireless_handlers;
+#ifndef CONFIG_BCM4710
struct ethtool_ops *ethtool_ops;
+#endif
+
/*
* This marks the end of the "visible" part of the structure. All
@@ -353,7 +356,14 @@
struct Qdisc *qdisc;
struct Qdisc *qdisc_sleeping;
struct Qdisc *qdisc_ingress;
+ /*
+ * this is needed for the wlan driver binary blob from linksys
+ */
+#ifdef CONFIG_BCM4710
+ struct Qdisc *qdisc_list;
+#else
struct list_head qdisc_list;
+#endif
unsigned long tx_queue_len; /* Max frames per queue allowed */
/* hard_start_xmit synchronizer */

View File

@ -1,24 +0,0 @@
--- linux-mips-cvs-21012005/include/linux/skbuff.h 2005-01-31 12:56:47.000000000 +0100
+++ linux-broadcom/include/linux/skbuff.h 2005-01-31 12:55:24.000000000 +0100
@@ -135,10 +135,6 @@
struct sock *sk; /* Socket we are owned by */
struct timeval stamp; /* Time we arrived */
struct net_device *dev; /* Device we arrived on/are leaving by */
- struct net_device *real_dev; /* For support of point to point protocols
- (e.g. 802.3ad) over bonding, we must save the
- physical device that got the packet before
- replacing skb->dev with the virtual device. */
/* Transport layer header */
union
@@ -219,6 +215,10 @@
#ifdef CONFIG_NET_SCHED
__u32 tc_index; /* traffic control index */
#endif
+ struct net_device *real_dev; /* For support of point to point protocols
+ (e.g. 802.3ad) over bonding, we must save the
+ physical device that got the packet before
+ replacing skb->dev with the virtual device. */
};
#ifdef __KERNEL__

View File

@ -1,28 +0,0 @@
--- linux-mips-cvs-21012005/net/core/Makefile 2004-11-19 01:28:53.000000000 +0100
+++ linux-broadcom/net/core/Makefile 2005-01-26 15:56:36.000000000 +0100
@@ -9,7 +9,11 @@
O_TARGET := core.o
+ifeq ($(CONFIG_BCM4710),y)
+export-objs := netfilter.o profile.o neighbour.o
+else
export-objs := netfilter.o profile.o ethtool.o neighbour.o
+endif
obj-y := sock.o skbuff.o iovec.o datagram.o scm.o
@@ -21,8 +25,13 @@
obj-$(CONFIG_FILTER) += filter.o
+ifeq ($(CONFIG_BCM4710),y)
+obj-$(CONFIG_NET) += dev.o dev_mcast.o dst.o neighbour.o \
+ rtnetlink.o utils.o
+else
obj-$(CONFIG_NET) += dev.o ethtool.o dev_mcast.o dst.o neighbour.o \
rtnetlink.o utils.o
+endif
obj-$(CONFIG_NETFILTER) += netfilter.o
obj-$(CONFIG_NET_DIVERT) += dv.o

View File

@ -1,28 +0,0 @@
--- linux-2.4.30/net/core/dev.c 2005-04-04 05:42:20.000000000 +0400
+++ linux/net/core/dev.c 2005-05-10 14:49:27.809927172 +0400
@@ -2216,6 +2220,9 @@
cmd == SIOCBONDSLAVEINFOQUERY ||
cmd == SIOCBONDINFOQUERY ||
cmd == SIOCBONDCHANGEACTIVE ||
+#ifdef CONFIG_BCM4710
+ cmd == SIOCETHTOOL ||
+#endif
cmd == SIOCGMIIPHY ||
cmd == SIOCGMIIREG ||
cmd == SIOCSMIIREG ||
@@ -2312,6 +2319,7 @@
return ret;
case SIOCETHTOOL:
+#ifndef CONFIG_BCM4710
dev_load(ifr.ifr_name);
rtnl_lock();
ret = dev_ethtool(&ifr);
@@ -2324,6 +2332,7 @@
ret = -EFAULT;
}
return ret;
+#endif
/*
* These ioctl calls:

View File

@ -1,119 +0,0 @@
--- linux-2.4.30/net/sched/sch_api.c 2004-11-17 12:54:22.000000000 +0100
+++ linux-2.4.30-wl/net/sched/sch_api.c 2005-04-24 18:56:03.000000000 +0200
@@ -194,11 +194,12 @@
{
struct Qdisc *q;
- list_for_each_entry(q, &dev->qdisc_list, list) {
+ for (q = dev->qdisc_list; q; q = q->next) {
if (q->handle == handle)
return q;
}
return NULL;
+
}
struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
@@ -371,8 +372,6 @@
unsigned long cl = cops->get(parent, classid);
if (cl) {
err = cops->graft(parent, cl, new, old);
- if (new)
- new->parent = classid;
cops->put(parent, cl);
}
}
@@ -427,7 +426,6 @@
memset(sch, 0, size);
- INIT_LIST_HEAD(&sch->list);
skb_queue_head_init(&sch->q);
if (handle == TC_H_INGRESS)
@@ -453,7 +451,8 @@
if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
write_lock(&qdisc_tree_lock);
- list_add_tail(&sch->list, &dev->qdisc_list);
+ sch->next = dev->qdisc_list;
+ dev->qdisc_list = sch;
write_unlock(&qdisc_tree_lock);
#ifdef CONFIG_NET_ESTIMATOR
if (tca[TCA_RATE-1])
@@ -808,19 +807,16 @@
if (idx > s_idx)
s_q_idx = 0;
read_lock(&qdisc_tree_lock);
- q_idx = 0;
- list_for_each_entry(q, &dev->qdisc_list, list) {
- if (q_idx < s_q_idx) {
- q_idx++;
- continue;
- }
- if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid,
- cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) {
- read_unlock(&qdisc_tree_lock);
- goto done;
- }
- q_idx++;
- }
+ for (q = dev->qdisc_list, q_idx = 0; q;
+ q = q->next, q_idx++) {
+ if (q_idx < s_q_idx)
+ continue;
+ if (tc_fill_qdisc(skb, q, 0, NETLINK_CB(cb->skb).pid,
+ cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) {
+ read_unlock(&qdisc_tree_lock);
+ goto done;
+ }
+ }
read_unlock(&qdisc_tree_lock);
}
@@ -1033,27 +1029,24 @@
t = 0;
read_lock(&qdisc_tree_lock);
- list_for_each_entry(q, &dev->qdisc_list, list) {
- if (t < s_t || !q->ops->cl_ops ||
- (tcm->tcm_parent &&
- TC_H_MAJ(tcm->tcm_parent) != q->handle)) {
- t++;
- continue;
- }
- if (t > s_t)
- memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
- arg.w.fn = qdisc_class_dump;
- arg.skb = skb;
- arg.cb = cb;
- arg.w.stop = 0;
- arg.w.skip = cb->args[1];
- arg.w.count = 0;
- q->ops->cl_ops->walk(q, &arg.w);
- cb->args[1] = arg.w.count;
- if (arg.w.stop)
- break;
- t++;
- }
+ for (q=dev->qdisc_list, t=0; q; q = q->next, t++) {
+ if (t < s_t) continue;
+ if (!q->ops->cl_ops) continue;
+ if (tcm->tcm_parent && TC_H_MAJ(tcm->tcm_parent) != q->handle)
+ continue;
+ if (t > s_t)
+ memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
+ arg.w.fn = qdisc_class_dump;
+ arg.skb = skb;
+ arg.cb = cb;
+ arg.w.stop = 0;
+ arg.w.skip = cb->args[1];
+ arg.w.count = 0;
+ q->ops->cl_ops->walk(q, &arg.w);
+ cb->args[1] = arg.w.count;
+ if (arg.w.stop)
+ break;
+ }
read_unlock(&qdisc_tree_lock);
cb->args[0] = t;

View File

@ -1,64 +0,0 @@
--- linux-2.4.30/net/sched/sch_generic.c 2004-11-17 12:54:22.000000000 +0100
+++ linux-2.4.30-wl/net/sched/sch_generic.c 2005-04-24 18:09:38.000000000 +0200
@@ -392,7 +392,6 @@
return NULL;
memset(sch, 0, size);
- INIT_LIST_HEAD(&sch->list);
skb_queue_head_init(&sch->q);
sch->ops = ops;
sch->enqueue = ops->enqueue;
@@ -422,11 +421,22 @@
void qdisc_destroy(struct Qdisc *qdisc)
{
struct Qdisc_ops *ops = qdisc->ops;
+ struct net_device *dev;
if (qdisc->flags&TCQ_F_BUILTIN ||
!atomic_dec_and_test(&qdisc->refcnt))
return;
- list_del(&qdisc->list);
+
+ dev = qdisc->dev;
+ if (dev) {
+ struct Qdisc *q, **qp;
+ for (qp = &qdisc->dev->qdisc_list; (q=*qp) != NULL; qp = &q->next) {
+ if (q == qdisc) {
+ *qp = q->next;
+ break;
+ }
+ }
+ }
#ifdef CONFIG_NET_ESTIMATOR
qdisc_kill_estimator(&qdisc->stats);
#endif
@@ -455,9 +465,9 @@
return;
}
write_lock(&qdisc_tree_lock);
- list_add_tail(&qdisc->list, &dev->qdisc_list);
+ qdisc->next = dev->qdisc_list;
+ dev->qdisc_list = qdisc;
write_unlock(&qdisc_tree_lock);
-
} else {
qdisc = &noqueue_qdisc;
}
@@ -501,7 +511,7 @@
dev->qdisc = &noop_qdisc;
spin_unlock_bh(&dev->queue_lock);
dev->qdisc_sleeping = &noop_qdisc;
- INIT_LIST_HEAD(&dev->qdisc_list);
+ dev->qdisc_list = NULL;
write_unlock(&qdisc_tree_lock);
dev_watchdog_init(dev);
@@ -523,7 +533,7 @@
qdisc_destroy(qdisc);
}
#endif
- BUG_TRAP(list_empty(&dev->qdisc_list));
+ BUG_TRAP(dev->qdisc_list == NULL);
BUG_TRAP(!timer_pending(&dev->watchdog_timer));
spin_unlock_bh(&dev->queue_lock);
write_unlock(&qdisc_tree_lock);

View File

@ -1,25 +0,0 @@
--- linux-2.4.30/include/net/pkt_sched.h 2004-11-17 12:54:22.000000000 +0100
+++ linux-2.4.30-wl/include/net/pkt_sched.h 2005-04-24 18:32:48.000000000 +0200
@@ -59,7 +59,7 @@
int (*enqueue)(struct sk_buff *, struct Qdisc *);
struct sk_buff * (*dequeue)(struct Qdisc *);
int (*requeue)(struct sk_buff *, struct Qdisc *);
- unsigned int (*drop)(struct Qdisc *);
+ int (*drop)(struct Qdisc *);
int (*init)(struct Qdisc *, struct rtattr *arg);
void (*reset)(struct Qdisc *);
@@ -80,12 +80,11 @@
#define TCQ_F_THROTTLED 2
#define TCQ_F_INGRESS 4
struct Qdisc_ops *ops;
+ struct Qdisc *next;
u32 handle;
- u32 parent;
atomic_t refcnt;
struct sk_buff_head q;
struct net_device *dev;
- struct list_head list;
struct tc_stats stats;
int (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,272 +0,0 @@
--- linux-2.4.30/drivers/net/b44.c 2004-08-08 01:26:05.000000000 +0200
+++ openwrt/build_mipsel/linux-2.4.30/drivers/net/b44.c 2005-05-01 20:10:19.193354917 +0200
@@ -1,7 +1,8 @@
/* b44.c: Broadcom 4400 device driver.
*
* Copyright (C) 2002 David S. Miller (davem@redhat.com)
- * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
+ * Copyright (C) 2004 Pekka Pietikainen (pp@ee.oulu.fi)
+ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
*
* Distribute under GPL.
*/
@@ -25,6 +26,16 @@
#include "b44.h"
+#include <typedefs.h>
+#include <bcmdevs.h>
+#include <bcmutils.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <bcmnvram.h>
+#include <sbconfig.h>
+#include <sbchipc.h>
+#include <sflash.h>
+
#define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.93"
@@ -75,7 +86,7 @@
DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
MODULE_AUTHOR("David S. Miller (davem@redhat.com)");
-MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver");
+MODULE_DESCRIPTION("Broadcom 4400/47xx 10/100 PCI ethernet driver");
MODULE_LICENSE("GPL");
MODULE_PARM(b44_debug, "i");
MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
@@ -89,6 +100,8 @@
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4713,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ } /* terminate list with empty entry */
};
@@ -236,6 +249,8 @@
udelay(1);
}
+static int b44_4713_instance;
+
static int ssb_core_unit(struct b44 *bp)
{
#if 0
@@ -258,6 +273,9 @@
break;
};
#endif
+ if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
+ return b44_4713_instance++;
+ else
return 0;
}
@@ -267,6 +285,28 @@
== SBTMSLOW_CLOCK);
}
+static void __b44_cam_read(struct b44 *bp, unsigned char *data, int index)
+{
+ u32 val;
+
+ bw32(B44_CAM_CTRL, (CAM_CTRL_READ |
+ (index << CAM_CTRL_INDEX_SHIFT)));
+
+ b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);
+
+ val = br32(B44_CAM_DATA_LO);
+
+ data[2] = (val >> 24) & 0xFF;
+ data[3] = (val >> 16) & 0xFF;
+ data[4] = (val >> 8) & 0xFF;
+ data[5] = (val >> 0) & 0xFF;
+
+ val = br32(B44_CAM_DATA_HI);
+
+ data[0] = (val >> 8) & 0xFF;
+ data[1] = (val >> 0) & 0xFF;
+}
+
static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
{
u32 val;
@@ -307,6 +347,9 @@
{
int err;
+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
+ return 0;
+
bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
(MDIO_OP_READ << MDIO_DATA_OP_SHIFT) |
@@ -321,6 +364,9 @@
static int b44_writephy(struct b44 *bp, int reg, u32 val)
{
+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
+ return 0;
+
bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
(MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT) |
@@ -336,6 +382,9 @@
u32 val;
int err;
+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
+ return 0;
+
err = b44_writephy(bp, MII_BMCR, BMCR_RESET);
if (err)
return err;
@@ -406,6 +455,9 @@
u32 val;
int err;
+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
+ return 0;
+
if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0)
goto out;
if ((err = b44_writephy(bp, B44_MII_ALEDCTRL,
@@ -498,6 +550,19 @@
{
u32 bmsr, aux;
+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) {
+ bp->flags |= B44_FLAG_100_BASE_T;
+ bp->flags |= B44_FLAG_FULL_DUPLEX;
+ if (!netif_carrier_ok(bp->dev)) {
+ u32 val = br32(B44_TX_CTRL);
+ val |= TX_CTRL_DUPLEX;
+ bw32(B44_TX_CTRL, val);
+ netif_carrier_on(bp->dev);
+ b44_link_report(bp);
+ }
+ return;
+ }
+
if (!b44_readphy(bp, MII_BMSR, &bmsr) &&
!b44_readphy(bp, B44_MII_AUXCTRL, &aux) &&
(bmsr != 0xffff)) {
@@ -1092,6 +1157,8 @@
/* bp->lock is held. */
static void b44_chip_reset(struct b44 *bp)
{
+ unsigned int sb_clock;
+
if (ssb_is_core_up(bp)) {
bw32(B44_RCV_LAZY, 0);
bw32(B44_ENET_CTRL, ENET_CTRL_DISABLE);
@@ -1105,9 +1172,10 @@
bw32(B44_DMARX_CTRL, 0);
bp->rx_prod = bp->rx_cons = 0;
} else {
- ssb_pci_setup(bp, (bp->core_unit == 0 ?
- SBINTVEC_ENET0 :
- SBINTVEC_ENET1));
+ /*if (bp->pdev->device != PCI_DEVICE_ID_BCM4713)*/
+ ssb_pci_setup(bp, (bp->core_unit == 0 ?
+ SBINTVEC_ENET0 :
+ SBINTVEC_ENET1));
}
ssb_core_reset(bp);
@@ -1115,6 +1183,11 @@
b44_clear_stats(bp);
/* Make PHY accessible. */
+ if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
+ sb_clock = 100000000; /* 100 MHz */
+ else
+ sb_clock = 62500000; /* 62.5 MHz */
+
bw32(B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
(0x0d & MDIO_CTRL_MAXF_MASK)));
br32(B44_MDIO_CTRL);
@@ -1669,20 +1742,42 @@
{
u8 eeprom[128];
int err;
+ unsigned long flags;
- err = b44_read_eeprom(bp, &eeprom[0]);
- if (err)
- goto out;
-
- bp->dev->dev_addr[0] = eeprom[79];
- bp->dev->dev_addr[1] = eeprom[78];
- bp->dev->dev_addr[2] = eeprom[81];
- bp->dev->dev_addr[3] = eeprom[80];
- bp->dev->dev_addr[4] = eeprom[83];
- bp->dev->dev_addr[5] = eeprom[82];
-
- bp->phy_addr = eeprom[90] & 0x1f;
- bp->mdc_port = (eeprom[90] >> 14) & 0x1;
+ if (bp->pdev->device == PCI_DEVICE_ID_BCM4713) {
+ /*
+ * BCM47xx boards don't have a EEPROM. The MAC is stored in
+ * a NVRAM area somewhere in the flash memory. As we don't
+ * know the location and/or the format of the NVRAM area
+ * here, we simply rely on the bootloader to write the
+ * MAC into the CAM.
+ */
+ spin_lock_irqsave(&bp->lock, flags);
+ __b44_cam_read(bp, bp->dev->dev_addr, 0);
+ spin_unlock_irqrestore(&bp->lock, flags);
+
+ /*
+ * BCM47xx boards don't have a PHY. Usually there is a switch
+ * chip with multiple PHYs connected to the PHY port.
+ */
+ bp->phy_addr = B44_PHY_ADDR_NO_PHY;
+ bp->dma_offset = 0;
+ } else {
+ err = b44_read_eeprom(bp, &eeprom[0]);
+ if (err)
+ return err;
+
+ bp->dev->dev_addr[0] = eeprom[79];
+ bp->dev->dev_addr[1] = eeprom[78];
+ bp->dev->dev_addr[2] = eeprom[81];
+ bp->dev->dev_addr[3] = eeprom[80];
+ bp->dev->dev_addr[4] = eeprom[83];
+ bp->dev->dev_addr[5] = eeprom[82];
+
+ bp->phy_addr = eeprom[90] & 0x1f;
+ bp->dma_offset = SB_PCI_DMA;
+ bp->mdc_port = (eeprom[90] >> 14) & 0x1;
+ }
/* With this, plus the rx_header prepended to the data by the
* hardware, we'll land the ethernet header on a 2-byte boundary.
@@ -1692,13 +1787,12 @@
bp->imask = IMASK_DEF;
bp->core_unit = ssb_core_unit(bp);
- bp->dma_offset = ssb_get_addr(bp, SBID_PCI_DMA, 0);
/* XXX - really required?
bp->flags |= B44_FLAG_BUGGY_TXPTR;
*/
-out:
- return err;
+
+ return 0;
}
static int __devinit b44_init_one(struct pci_dev *pdev,
@@ -1819,7 +1913,8 @@
pci_save_state(bp->pdev, bp->pci_cfg_state);
- printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
+ printk(KERN_INFO "%s: Broadcom %s 10/100BaseT Ethernet ", dev->name,
+ (pdev->device == PCI_DEVICE_ID_BCM4713) ? "47xx" : "4400");
for (i = 0; i < 6; i++)
printk("%2.2x%c", dev->dev_addr[i],
i == 5 ? '\n' : ':');

View File

@ -1,20 +0,0 @@
--- ../../buildroot-unpacked/build_mipsel/linux/net/ipv4/netfilter/ip_conntrack_core.c 2004-11-28 22:59:36.000000000 -0500
+++ linux/net/ipv4/netfilter/ip_conntrack_core.c 2004-11-30 05:05:32.000000000 -0500
@@ -1386,7 +1386,7 @@
nf_unregister_sockopt(&so_getorigdst);
}
-static int hashsize = 0;
+static int hashsize = 5953
MODULE_PARM(hashsize, "i");
int __init ip_conntrack_init(void)
@@ -1407,7 +1407,7 @@
if (ip_conntrack_htable_size < 16)
ip_conntrack_htable_size = 16;
}
- ip_conntrack_max = 8 * ip_conntrack_htable_size;
+ ip_conntrack_max = ip_conntrack_htable_size;
printk("ip_conntrack version %s (%u buckets, %d max)"
" - %Zd bytes per conntrack\n", IP_CONNTRACK_VERSION,

View File

@ -1,180 +0,0 @@
diff -urN linux-2.4.30.old/Documentation/Configure.help linux-2.4.30.dev/Documentation/Configure.help
--- linux-2.4.30.old/Documentation/Configure.help 2005-04-27 11:35:46.000000000 +0200
+++ linux-2.4.30.dev/Documentation/Configure.help 2005-04-27 11:43:49.000000000 +0200
@@ -3209,6 +3209,15 @@
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
+TTL target support
+CONFIG_IP_NF_TARGET_TTL
+ This option adds a `TTL' target, which enables the user to set
+ the TTL value or increment / decrement the TTL value by a given
+ amount.
+
+ If you want to compile it as a module, say M here and read
+ Documentation/modules.txt. If unsure, say `N'.
+
ipchains (2.2-style) support
CONFIG_IP_NF_COMPAT_IPCHAINS
This option places ipchains (with masquerading and redirection
diff -urN linux-2.4.30.old/include/linux/netfilter_ipv4/ipt_TTL.h linux-2.4.30.dev/include/linux/netfilter_ipv4/ipt_TTL.h
--- linux-2.4.30.old/include/linux/netfilter_ipv4/ipt_TTL.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.30.dev/include/linux/netfilter_ipv4/ipt_TTL.h 2005-04-27 11:43:49.000000000 +0200
@@ -0,0 +1,21 @@
+/* TTL modification module for IP tables
+ * (C) 2000 by Harald Welte <laforge@gnumonks.org> */
+
+#ifndef _IPT_TTL_H
+#define _IPT_TTL_H
+
+enum {
+ IPT_TTL_SET = 0,
+ IPT_TTL_INC,
+ IPT_TTL_DEC
+};
+
+#define IPT_TTL_MAXMODE IPT_TTL_DEC
+
+struct ipt_TTL_info {
+ u_int8_t mode;
+ u_int8_t ttl;
+};
+
+
+#endif
diff -urN linux-2.4.30.old/net/ipv4/netfilter/Config.in linux-2.4.30.dev/net/ipv4/netfilter/Config.in
--- linux-2.4.30.old/net/ipv4/netfilter/Config.in 2005-04-27 11:35:45.000000000 +0200
+++ linux-2.4.30.dev/net/ipv4/netfilter/Config.in 2005-04-27 11:43:49.000000000 +0200
@@ -129,6 +129,7 @@
dep_tristate ' MARK target support' CONFIG_IP_NF_TARGET_MARK $CONFIG_IP_NF_MANGLE
fi
dep_tristate ' LOG target support' CONFIG_IP_NF_TARGET_LOG $CONFIG_IP_NF_IPTABLES
+ dep_tristate ' TTL target support' CONFIG_IP_NF_TARGET_TTL $CONFIG_IP_NF_IPTABLES
dep_tristate ' ULOG target support' CONFIG_IP_NF_TARGET_ULOG $CONFIG_IP_NF_IPTABLES
dep_tristate ' TCPMSS target support' CONFIG_IP_NF_TARGET_TCPMSS $CONFIG_IP_NF_IPTABLES
fi
diff -urN linux-2.4.30.old/net/ipv4/netfilter/ipt_TTL.c linux-2.4.30.dev/net/ipv4/netfilter/ipt_TTL.c
--- linux-2.4.30.old/net/ipv4/netfilter/ipt_TTL.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.30.dev/net/ipv4/netfilter/ipt_TTL.c 2005-04-27 11:43:49.000000000 +0200
@@ -0,0 +1,110 @@
+/* TTL modification target for IP tables
+ * (C) 2000 by Harald Welte <laforge@gnumonks.org>
+ *
+ * Version: $Revision$
+ *
+ * This software is distributed under the terms of GNU GPL
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <net/checksum.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_TTL.h>
+
+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_DESCRIPTION("IP tables TTL modification module");
+MODULE_LICENSE("GPL");
+
+static unsigned int ipt_ttl_target(struct sk_buff **pskb, unsigned int hooknum,
+ const struct net_device *in, const struct net_device *out,
+ const void *targinfo, void *userinfo)
+{
+ struct iphdr *iph = (*pskb)->nh.iph;
+ const struct ipt_TTL_info *info = targinfo;
+ u_int16_t diffs[2];
+ int new_ttl;
+
+ switch (info->mode) {
+ case IPT_TTL_SET:
+ new_ttl = info->ttl;
+ break;
+ case IPT_TTL_INC:
+ new_ttl = iph->ttl + info->ttl;
+ if (new_ttl > 255)
+ new_ttl = 255;
+ break;
+ case IPT_TTL_DEC:
+ new_ttl = iph->ttl - info->ttl;
+ if (new_ttl < 0)
+ new_ttl = 0;
+ break;
+ default:
+ new_ttl = iph->ttl;
+ break;
+ }
+
+ if (new_ttl != iph->ttl) {
+ diffs[0] = htons(((unsigned)iph->ttl) << 8) ^ 0xFFFF;
+ iph->ttl = new_ttl;
+ diffs[1] = htons(((unsigned)iph->ttl) << 8);
+ iph->check = csum_fold(csum_partial((char *)diffs,
+ sizeof(diffs),
+ iph->check^0xFFFF));
+ (*pskb)->nfcache |= NFC_ALTERED;
+ }
+
+ return IPT_CONTINUE;
+}
+
+static int ipt_ttl_checkentry(const char *tablename,
+ const struct ipt_entry *e,
+ void *targinfo,
+ unsigned int targinfosize,
+ unsigned int hook_mask)
+{
+ struct ipt_TTL_info *info = targinfo;
+
+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_TTL_info))) {
+ printk(KERN_WARNING "TTL: targinfosize %u != %Zu\n",
+ targinfosize,
+ IPT_ALIGN(sizeof(struct ipt_TTL_info)));
+ return 0;
+ }
+
+ if (strcmp(tablename, "mangle")) {
+ printk(KERN_WARNING "TTL: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
+ return 0;
+ }
+
+ if (info->mode > IPT_TTL_MAXMODE) {
+ printk(KERN_WARNING "TTL: invalid or unknown Mode %u\n",
+ info->mode);
+ return 0;
+ }
+
+ if ((info->mode != IPT_TTL_SET) && (info->ttl == 0)) {
+ printk(KERN_WARNING "TTL: increment/decrement doesn't make sense with value 0\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+static struct ipt_target ipt_TTL = { { NULL, NULL }, "TTL",
+ ipt_ttl_target, ipt_ttl_checkentry, NULL, THIS_MODULE };
+
+static int __init init(void)
+{
+ return ipt_register_target(&ipt_TTL);
+}
+
+static void __exit fini(void)
+{
+ ipt_unregister_target(&ipt_TTL);
+}
+
+module_init(init);
+module_exit(fini);
diff -urN linux-2.4.30.old/net/ipv4/netfilter/Makefile linux-2.4.30.dev/net/ipv4/netfilter/Makefile
--- linux-2.4.30.old/net/ipv4/netfilter/Makefile 2005-04-27 11:35:45.000000000 +0200
+++ linux-2.4.30.dev/net/ipv4/netfilter/Makefile 2005-04-27 11:43:49.000000000 +0200
@@ -112,6 +112,7 @@
obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o
obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
+obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o

View File

@ -1,11 +0,0 @@
--- linux-2.4.30/drivers/net/b44.h 2003-08-25 13:44:42.000000000 +0200
+++ openwrt/build_mipsel/linux-2.4.30/drivers/net/b44.h 2005-05-01 14:43:20.000000000 +0200
@@ -461,6 +461,8 @@
};
#define B44_MCAST_TABLE_SIZE 32
+#define B44_PHY_ADDR_NO_PHY 30
+#define B44_MDC_RATIO 5000000
/* SW copy of device statistics, kept up to date by periodic timer
* which probes HW values. Must have same relative layout as HW

View File

@ -1,10 +0,0 @@
--- linux-2.4.30/include/linux/pci_ids.h 2005-04-04 03:42:20.000000000 +0200
+++ openwrt/build_mipsel/linux-2.4.30/include/linux/pci_ids.h 2005-05-01 14:43:20.000000000 +0200
@@ -1735,6 +1735,7 @@
#define PCI_DEVICE_ID_TIGON3_5901_2 0x170e
#define PCI_DEVICE_ID_BCM4401 0x4401
#define PCI_DEVICE_ID_BCM4401B0 0x4402
+#define PCI_DEVICE_ID_BCM4713 0x4713
#define PCI_VENDOR_ID_ENE 0x1524
#define PCI_DEVICE_ID_ENE_1211 0x1211

View File

@ -1,89 +0,0 @@
--- linux-2.4.30.old/drivers/net/b44.c 2005-05-01 23:30:22.000000000 +0400
+++ linux-2.4.30/drivers/net/b44.c 2005-05-10 16:51:24.410654488 +0400
@@ -343,17 +343,14 @@
bw32(B44_IMASK, bp->imask);
}
-static int b44_readphy(struct b44 *bp, int reg, u32 *val)
+static int __b44_readphy(struct b44 *bp, int phy_addr, int reg, u32 *val)
{
int err;
- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
- return 0;
-
bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
(MDIO_OP_READ << MDIO_DATA_OP_SHIFT) |
- (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
+ (phy_addr << MDIO_DATA_PMD_SHIFT) |
(reg << MDIO_DATA_RA_SHIFT) |
(MDIO_TA_VALID << MDIO_DATA_TA_SHIFT)));
err = b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
@@ -362,21 +359,34 @@
return err;
}
-static int b44_writephy(struct b44 *bp, int reg, u32 val)
+static int b44_readphy(struct b44 *bp, int reg, u32 *val)
{
if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
return 0;
+ return __b44_readphy(bp, bp->phy_addr, reg, val);
+}
+
+static int __b44_writephy(struct b44 *bp, int phy_addr, int reg, u32 val)
+{
bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
(MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT) |
- (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
+ (phy_addr << MDIO_DATA_PMD_SHIFT) |
(reg << MDIO_DATA_RA_SHIFT) |
(MDIO_TA_VALID << MDIO_DATA_TA_SHIFT) |
(val & MDIO_DATA_DATA)));
return b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
}
+static int b44_writephy(struct b44 *bp, int reg, u32 val)
+{
+ if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
+ return 0;
+
+ return __b44_writephy(bp, bp->phy_addr, reg, val);
+}
+
static int b44_phy_reset(struct b44 *bp)
{
u32 val;
@@ -1701,7 +1711,7 @@
u32 mii_regval;
spin_lock_irq(&bp->lock);
- err = b44_readphy(bp, data->reg_num & 0x1f, &mii_regval);
+ err = __b44_readphy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, &mii_regval);
spin_unlock_irq(&bp->lock);
data->val_out = mii_regval;
@@ -1714,7 +1724,7 @@
return -EPERM;
spin_lock_irq(&bp->lock);
- err = b44_writephy(bp, data->reg_num & 0x1f, data->val_in);
+ err = __b44_writephy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
spin_unlock_irq(&bp->lock);
return err;
@@ -1919,6 +1929,11 @@
printk("%2.2x%c", dev->dev_addr[i],
i == 5 ? '\n' : ':');
+ /* Initialize phy */
+ spin_lock_irq(&bp->lock);
+ b44_chip_reset(bp);
+ spin_unlock_irq(&bp->lock);
+
return 0;
err_out_iounmap:

File diff suppressed because it is too large Load Diff

View File

@ -1,296 +0,0 @@
diff -urN linux-2.4.26-pre5/Documentation/Configure.help linux-2.4.26-pre5-netdev-core/Documentation/Configure.help
--- linux-2.4.26-pre5/Documentation/Configure.help Sat Mar 20 10:08:18 2004
+++ linux-2.4.26-pre5-netdev-core/Documentation/Configure.help Sun Mar 21 10:16:14 2004
@@ -10419,6 +10419,20 @@
If you don't know what to use this for, you don't need it.
+Allow Net Devices to contribute to /dev/random
+CONFIG_NET_RANDOM
+ If you say Y here, network device interrupts will contribute to the
+ kernel entropy pool. Normally, block devices and some other devices
+ feed the pool. Some systems, such as those that are headless or diskless,
+ need additional entropy sources. Some people, however, feel that network
+ devices should not contribute to /dev/random because an external attacker
+ could observe incoming packets in an attempt to learn the entropy pool's
+ state. If you say N, no network device will contribute entropy.
+
+ If you believe there is a chance of your network packets being observed
+ and you doubt the security of the entropy pool's one-way hash, do not
+ enable this. If unsure, say N.
+
Ethertap network tap (OBSOLETE)
CONFIG_ETHERTAP
If you say Y here (and have said Y to "Kernel/User network link
diff -urN linux-2.4.26-pre5/drivers/net/Config.in linux-2.4.26-pre5-netdev-core/drivers/net/Config.in
--- linux-2.4.26-pre5/drivers/net/Config.in Sat Mar 20 10:08:18 2004
+++ linux-2.4.26-pre5-netdev-core/drivers/net/Config.in Sun Mar 21 10:16:14 2004
@@ -8,6 +8,7 @@
tristate 'Bonding driver support' CONFIG_BONDING
tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
tristate 'Universal TUN/TAP device driver support' CONFIG_TUN
+bool 'Allow Net Devices to contribute to /dev/random' CONFIG_NET_RANDOM
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
fi
diff -urN linux-2.4.26-pre5/include/asm-alpha/signal.h linux-2.4.26-pre5-netdev-core/include/asm-alpha/signal.h
--- linux-2.4.26-pre5/include/asm-alpha/signal.h Sat Dec 1 18:27:14 2001
+++ linux-2.4.26-pre5-netdev-core/include/asm-alpha/signal.h Sun Mar 21 10:16:14 2004
@@ -121,7 +121,14 @@
#define SA_PROBE SA_ONESHOT
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_SHIRQ 0x40000000
+
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
#endif
+
+#endif /* __KERNEL__ */
#define SIG_BLOCK 1 /* for blocking signals */
#define SIG_UNBLOCK 2 /* for unblocking signals */
diff -urN linux-2.4.26-pre5/include/asm-arm/signal.h linux-2.4.26-pre5-netdev-core/include/asm-arm/signal.h
--- linux-2.4.26-pre5/include/asm-arm/signal.h Sat Sep 13 07:57:29 2003
+++ linux-2.4.26-pre5-netdev-core/include/asm-arm/signal.h Sun Mar 21 10:16:14 2004
@@ -125,7 +125,14 @@
#define SA_PROBE 0x80000000
#define SA_SAMPLE_RANDOM 0x10000000
#define SA_SHIRQ 0x04000000
+
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
#endif
+
+#endif /* __KERNEL__ */
#define SIG_BLOCK 0 /* for blocking signals */
#define SIG_UNBLOCK 1 /* for unblocking signals */
diff -urN linux-2.4.26-pre5/include/asm-cris/signal.h linux-2.4.26-pre5-netdev-core/include/asm-cris/signal.h
--- linux-2.4.26-pre5/include/asm-cris/signal.h Sat Dec 1 18:27:14 2001
+++ linux-2.4.26-pre5-netdev-core/include/asm-cris/signal.h Sun Mar 21 10:16:14 2004
@@ -120,7 +120,14 @@
#define SA_PROBE SA_ONESHOT
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_SHIRQ 0x04000000
+
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
#endif
+
+#endif /* __KERNEL__ */
#define SIG_BLOCK 0 /* for blocking signals */
#define SIG_UNBLOCK 1 /* for unblocking signals */
diff -urN linux-2.4.26-pre5/include/asm-i386/signal.h linux-2.4.26-pre5-netdev-core/include/asm-i386/signal.h
--- linux-2.4.26-pre5/include/asm-i386/signal.h Sun Mar 21 00:00:43 2004
+++ linux-2.4.26-pre5-netdev-core/include/asm-i386/signal.h Sun Mar 21 10:16:14 2004
@@ -119,7 +119,14 @@
#define SA_PROBE SA_ONESHOT
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_SHIRQ 0x04000000
+
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
#endif
+
+#endif /* __KERNEL__ */
#define SIG_BLOCK 0 /* for blocking signals */
#define SIG_UNBLOCK 1 /* for unblocking signals */
diff -urN linux-2.4.26-pre5/include/asm-ia64/signal.h linux-2.4.26-pre5-netdev-core/include/asm-ia64/signal.h
--- linux-2.4.26-pre5/include/asm-ia64/signal.h Sat Mar 20 10:08:20 2004
+++ linux-2.4.26-pre5-netdev-core/include/asm-ia64/signal.h Sun Mar 21 10:16:14 2004
@@ -117,6 +117,12 @@
#define SA_SHIRQ 0x04000000
#define SA_PERCPU_IRQ 0x02000000
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
+#endif
+
#endif /* __KERNEL__ */
#define SIG_BLOCK 0 /* for blocking signals */
diff -urN linux-2.4.26-pre5/include/asm-m68k/signal.h linux-2.4.26-pre5-netdev-core/include/asm-m68k/signal.h
--- linux-2.4.26-pre5/include/asm-m68k/signal.h Fri Feb 20 07:38:33 2004
+++ linux-2.4.26-pre5-netdev-core/include/asm-m68k/signal.h Sun Mar 21 10:16:14 2004
@@ -116,7 +116,14 @@
#define SA_PROBE SA_ONESHOT
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_SHIRQ 0x04000000
+
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
#endif
+
+#endif /* __KERNEL__ */
#define SIG_BLOCK 0 /* for blocking signals */
#define SIG_UNBLOCK 1 /* for unblocking signals */
diff -urN linux-2.4.26-pre5/include/asm-mips/signal.h linux-2.4.26-pre5-netdev-core/include/asm-mips/signal.h
--- linux-2.4.26-pre5/include/asm-mips/signal.h Sat Sep 13 07:57:31 2003
+++ linux-2.4.26-pre5-netdev-core/include/asm-mips/signal.h Sun Mar 21 10:16:14 2004
@@ -111,6 +111,12 @@
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_SHIRQ 0x02000000
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
+#endif
+
#endif /* __KERNEL__ */
#define SIG_BLOCK 1 /* for blocking signals */
diff -urN linux-2.4.26-pre5/include/asm-mips64/signal.h linux-2.4.26-pre5-netdev-core/include/asm-mips64/signal.h
--- linux-2.4.26-pre5/include/asm-mips64/signal.h Sat Sep 13 07:57:32 2003
+++ linux-2.4.26-pre5-netdev-core/include/asm-mips64/signal.h Sun Mar 21 10:16:14 2004
@@ -119,6 +119,12 @@
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_SHIRQ 0x02000000
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
+#endif
+
#endif /* __KERNEL__ */
#define SIG_BLOCK 1 /* for blocking signals */
diff -urN linux-2.4.26-pre5/include/asm-parisc/signal.h linux-2.4.26-pre5-netdev-core/include/asm-parisc/signal.h
--- linux-2.4.26-pre5/include/asm-parisc/signal.h Sun Jan 11 18:48:21 2004
+++ linux-2.4.26-pre5-netdev-core/include/asm-parisc/signal.h Sun Mar 21 10:16:14 2004
@@ -100,6 +100,12 @@
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_SHIRQ 0x04000000
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
+#endif
+
#endif /* __KERNEL__ */
#define SIG_BLOCK 0 /* for blocking signals */
diff -urN linux-2.4.26-pre5/include/asm-ppc/signal.h linux-2.4.26-pre5-netdev-core/include/asm-ppc/signal.h
--- linux-2.4.26-pre5/include/asm-ppc/signal.h Sat Sep 13 07:57:32 2003
+++ linux-2.4.26-pre5-netdev-core/include/asm-ppc/signal.h Sun Mar 21 10:16:14 2004
@@ -111,6 +111,13 @@
#define SA_PROBE SA_ONESHOT
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_SHIRQ 0x04000000
+
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
+#endif
+
#endif /* __KERNEL__ */
#define SIG_BLOCK 0 /* for blocking signals */
diff -urN linux-2.4.26-pre5/include/asm-s390/signal.h linux-2.4.26-pre5-netdev-core/include/asm-s390/signal.h
--- linux-2.4.26-pre5/include/asm-s390/signal.h Fri Feb 20 07:38:34 2004
+++ linux-2.4.26-pre5-netdev-core/include/asm-s390/signal.h Sun Mar 21 10:16:14 2004
@@ -129,7 +129,14 @@
#define SA_SHIRQ 0x04000000
#define SA_DOPATHGROUP 0x00100000
#define SA_FORCE 0x00200000
+
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
#endif
+
+#endif /* __KERNEL__ */
#define SIG_BLOCK 0 /* for blocking signals */
#define SIG_UNBLOCK 1 /* for unblocking signals */
diff -urN linux-2.4.26-pre5/include/asm-s390x/signal.h linux-2.4.26-pre5-netdev-core/include/asm-s390x/signal.h
--- linux-2.4.26-pre5/include/asm-s390x/signal.h Fri Feb 20 07:38:34 2004
+++ linux-2.4.26-pre5-netdev-core/include/asm-s390x/signal.h Sun Mar 21 10:16:14 2004
@@ -129,7 +129,14 @@
#define SA_SHIRQ 0x04000000
#define SA_DOPATHGROUP 0x00100000
#define SA_FORCE 0x00200000
+
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
#endif
+
+#endif /* __KERNEL__ */
#define SIG_BLOCK 0 /* for blocking signals */
#define SIG_UNBLOCK 1 /* for unblocking signals */
diff -urN linux-2.4.26-pre5/include/asm-sh/signal.h linux-2.4.26-pre5-netdev-core/include/asm-sh/signal.h
--- linux-2.4.26-pre5/include/asm-sh/signal.h Sat Dec 1 18:27:13 2001
+++ linux-2.4.26-pre5-netdev-core/include/asm-sh/signal.h Sun Mar 21 10:16:14 2004
@@ -107,7 +107,14 @@
#define SA_PROBE SA_ONESHOT
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_SHIRQ 0x04000000
+
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
#endif
+
+#endif /* __KERNEL__ */
#define SIG_BLOCK 0 /* for blocking signals */
#define SIG_UNBLOCK 1 /* for unblocking signals */
diff -urN linux-2.4.26-pre5/include/asm-sparc/signal.h linux-2.4.26-pre5-netdev-core/include/asm-sparc/signal.h
--- linux-2.4.26-pre5/include/asm-sparc/signal.h Sat Dec 1 18:27:14 2001
+++ linux-2.4.26-pre5-netdev-core/include/asm-sparc/signal.h Sun Mar 21 10:16:14 2004
@@ -176,7 +176,14 @@
#define SA_PROBE SA_ONESHOT
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_STATIC_ALLOC 0x80
+
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
#endif
+
+#endif /* __KERNEL__ */
/* Type of a signal handler. */
#ifdef __KERNEL__
diff -urN linux-2.4.26-pre5/include/asm-sparc64/signal.h linux-2.4.26-pre5-netdev-core/include/asm-sparc64/signal.h
--- linux-2.4.26-pre5/include/asm-sparc64/signal.h Sat Dec 1 18:27:14 2001
+++ linux-2.4.26-pre5-netdev-core/include/asm-sparc64/signal.h Sun Mar 21 10:16:14 2004
@@ -192,7 +192,14 @@
#define SA_PROBE SA_ONESHOT
#define SA_SAMPLE_RANDOM SA_RESTART
#define SA_STATIC_ALLOC 0x80
+
+#ifdef CONFIG_NET_RANDOM
+#define SA_NET_RANDOM SA_SAMPLE_RANDOM
+#else
+#define SA_NET_RANDOM 0
#endif
+
+#endif /* __KERNEL__ */
/* Type of a signal handler. */
#ifdef __KERNEL__

View File

@ -1,11 +0,0 @@
--- linux-2.4.30.old/drivers/net/et/et_linux.c 2005-05-05 02:53:35.000000000 +0200
+++ linux-2.4.30/drivers/net/et/et_linux.c 2005-05-05 02:54:01.000000000 +0200
@@ -192,7 +192,7 @@
#endif
/* register our interrupt handler */
- if (request_irq(pdev->irq, et_isr, SA_SHIRQ, dev->name, et)) {
+ if (request_irq(pdev->irq, et_isr, SA_SHIRQ | SA_NET_RANDOM, dev->name, et)) {
ET_ERROR(("et%d: request_irq() failed\n", unit));
goto fail;
}

View File

@ -1,23 +0,0 @@
#
# Makefile for Broadcom BCM947XX boards
#
# 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.
#
# $Id$
#
O_TARGET := bcm947xx.o
export-objs := nvram_linux.o setup.o
obj-y := prom.o setup.o time.o sbmips.o sbpci.o pcibios.o perfcntr.o gpio.o
obj-y += sflash.o nvram.o nvram_linux.o
vpath %.c $(SRCBASE)/shared $(SRCBASE)/shared/nvram
include $(TOPDIR)/Rules.make

View File

@ -1,33 +0,0 @@
#
# Makefile for Broadcom BCM947XX boards
#
# Copyright 2001-2003, 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.
#
# $Id$
#
OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S
SYSTEM ?= $(TOPDIR)/vmlinux
all: vmlinuz
# Don't build dependencies, this may die if $(CC) isn't gcc
dep:
# Create a gzipped version named vmlinuz for compatibility
vmlinuz: piggy
gzip -c9 $< > $@
piggy: $(SYSTEM)
$(OBJCOPY) $< $@
mrproper: clean
clean:
rm -f vmlinuz piggy

View File

@ -1,158 +0,0 @@
/*
* GPIO char driver
*
* 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.
*
* $Id$
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <typedefs.h>
#include <bcmutils.h>
#include <sbutils.h>
#include <bcmdevs.h>
static void *gpio_sbh;
static int gpio_major;
static devfs_handle_t gpio_dir;
static struct {
char *name;
devfs_handle_t handle;
} gpio_file[] = {
{ "in", NULL },
{ "out", NULL },
{ "outen", NULL },
{ "control", NULL }
};
static int
gpio_open(struct inode *inode, struct file * file)
{
if (MINOR(inode->i_rdev) > ARRAYSIZE(gpio_file))
return -ENODEV;
MOD_INC_USE_COUNT;
return 0;
}
static int
gpio_release(struct inode *inode, struct file * file)
{
MOD_DEC_USE_COUNT;
return 0;
}
static ssize_t
gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
u32 val;
switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
case 0:
val = sb_gpioin(gpio_sbh);
break;
case 1:
val = sb_gpioout(gpio_sbh, 0, 0);
break;
case 2:
val = sb_gpioouten(gpio_sbh, 0, 0);
break;
case 3:
val = sb_gpiocontrol(gpio_sbh, 0, 0);
break;
default:
return -ENODEV;
}
if (put_user(val, (u32 *) buf))
return -EFAULT;
return sizeof(val);
}
static ssize_t
gpio_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
u32 val;
if (get_user(val, (u32 *) buf))
return -EFAULT;
switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
case 0:
return -EACCES;
case 1:
sb_gpioout(gpio_sbh, ~0, val);
break;
case 2:
sb_gpioouten(gpio_sbh, ~0, val);
break;
case 3:
sb_gpiocontrol(gpio_sbh, ~0, val);
break;
default:
return -ENODEV;
}
return sizeof(val);
}
static struct file_operations gpio_fops = {
owner: THIS_MODULE,
open: gpio_open,
release: gpio_release,
read: gpio_read,
write: gpio_write,
};
static int __init
gpio_init(void)
{
int i;
if (!(gpio_sbh = sb_kattach()))
return -ENODEV;
sb_gpiosetcore(gpio_sbh);
if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0)
return gpio_major;
gpio_dir = devfs_mk_dir(NULL, "gpio", NULL);
for (i = 0; i < ARRAYSIZE(gpio_file); i++) {
gpio_file[i].handle = devfs_register(gpio_dir,
gpio_file[i].name,
DEVFS_FL_DEFAULT, gpio_major, i,
S_IFCHR | S_IRUGO | S_IWUGO,
&gpio_fops, NULL);
}
return 0;
}
static void __exit
gpio_exit(void)
{
int i;
for (i = 0; i < ARRAYSIZE(gpio_file); i++)
devfs_unregister(gpio_file[i].handle);
devfs_unregister(gpio_dir);
devfs_unregister_chrdev(gpio_major, "gpio");
sb_detach(gpio_sbh);
}
module_init(gpio_init);
module_exit(gpio_exit);

View File

@ -1,317 +0,0 @@
/*
* NVRAM variable manipulation (common)
*
* 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.
*
* $Id$
*/
#include <typedefs.h>
#include <osl.h>
#include <bcmendian.h>
#include <bcmnvram.h>
#include <bcmutils.h>
#include <sbsdram.h>
extern struct nvram_tuple * _nvram_realloc(struct nvram_tuple *t, const char *name, const char *value);
extern void _nvram_free(struct nvram_tuple *t);
extern int _nvram_read(void *buf);
char * _nvram_get(const char *name);
int _nvram_set(const char *name, const char *value);
int _nvram_unset(const char *name);
int _nvram_getall(char *buf, int count);
int _nvram_commit(struct nvram_header *header);
int _nvram_init(void);
void _nvram_exit(void);
static struct nvram_tuple * nvram_hash[257];
static struct nvram_tuple * nvram_dead;
/* Free all tuples. Should be locked. */
static void
nvram_free(void)
{
uint i;
struct nvram_tuple *t, *next;
/* Free hash table */
for (i = 0; i < ARRAYSIZE(nvram_hash); i++) {
for (t = nvram_hash[i]; t; t = next) {
next = t->next;
_nvram_free(t);
}
nvram_hash[i] = NULL;
}
/* Free dead table */
for (t = nvram_dead; t; t = next) {
next = t->next;
_nvram_free(t);
}
nvram_dead = NULL;
/* Indicate to per-port code that all tuples have been freed */
_nvram_free(NULL);
}
/* String hash */
static INLINE uint
hash(const char *s)
{
uint hash = 0;
while (*s)
hash = 31 * hash + *s++;
return hash;
}
/* (Re)initialize the hash table. Should be locked. */
static int
nvram_rehash(struct nvram_header *header)
{
char buf[] = "0xXXXXXXXX", *name, *value, *end, *eq;
/* (Re)initialize hash table */
nvram_free();
/* Parse and set "name=value\0 ... \0\0" */
name = (char *) &header[1];
end = (char *) header + NVRAM_SPACE - 2;
end[0] = end[1] = '\0';
for (; *name; name = value + strlen(value) + 1) {
if (!(eq = strchr(name, '=')))
break;
*eq = '\0';
value = eq + 1;
_nvram_set(name, value);
*eq = '=';
}
/* Set special SDRAM parameters */
if (!_nvram_get("sdram_init")) {
sprintf(buf, "0x%04X", (uint16)(header->crc_ver_init >> 16));
_nvram_set("sdram_init", buf);
}
if (!_nvram_get("sdram_config")) {
sprintf(buf, "0x%04X", (uint16)(header->config_refresh & 0xffff));
_nvram_set("sdram_config", buf);
}
if (!_nvram_get("sdram_refresh")) {
sprintf(buf, "0x%04X", (uint16)((header->config_refresh >> 16) & 0xffff));
_nvram_set("sdram_refresh", buf);
}
if (!_nvram_get("sdram_ncdl")) {
sprintf(buf, "0x%08X", header->config_ncdl);
_nvram_set("sdram_ncdl", buf);
}
return 0;
}
/* Get the value of an NVRAM variable. Should be locked. */
char *
_nvram_get(const char *name)
{
uint i;
struct nvram_tuple *t;
char *value;
if (!name)
return NULL;
/* Hash the name */
i = hash(name) % ARRAYSIZE(nvram_hash);
/* Find the associated tuple in the hash table */
for (t = nvram_hash[i]; t && strcmp(t->name, name); t = t->next);
value = t ? t->value : NULL;
return value;
}
/* Get the value of an NVRAM variable. Should be locked. */
int
_nvram_set(const char *name, const char *value)
{
uint i;
struct nvram_tuple *t, *u, **prev;
/* Hash the name */
i = hash(name) % ARRAYSIZE(nvram_hash);
/* Find the associated tuple in the hash table */
for (prev = &nvram_hash[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev);
/* (Re)allocate tuple */
if (!(u = _nvram_realloc(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 = nvram_dead;
nvram_dead = t;
}
/* Add new tuple to the hash table */
u->next = nvram_hash[i];
nvram_hash[i] = u;
return 0;
}
/* Unset the value of an NVRAM variable. Should be locked. */
int
_nvram_unset(const char *name)
{
uint i;
struct nvram_tuple *t, **prev;
if (!name)
return 0;
/* Hash the name */
i = hash(name) % ARRAYSIZE(nvram_hash);
/* Find the associated tuple in the hash table */
for (prev = &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 = nvram_dead;
nvram_dead = t;
}
return 0;
}
/* Get all NVRAM variables. Should be locked. */
int
_nvram_getall(char *buf, int count)
{
uint i;
struct nvram_tuple *t;
int len = 0;
bzero(buf, count);
/* Write name=value\0 ... \0\0 */
for (i = 0; i < ARRAYSIZE(nvram_hash); i++) {
for (t = nvram_hash[i]; t; t = t->next) {
if ((count - len) > (strlen(t->name) + 1 + strlen(t->value) + 1))
len += sprintf(buf + len, "%s=%s", t->name, t->value) + 1;
else
break;
}
}
return 0;
}
/* Regenerate NVRAM. Should be locked. */
int
_nvram_commit(struct nvram_header *header)
{
char *init, *config, *refresh, *ncdl;
char *ptr, *end;
int i;
struct nvram_tuple *t;
struct nvram_header tmp;
uint8 crc;
/* Regenerate header */
header->magic = NVRAM_MAGIC;
header->crc_ver_init = (NVRAM_VERSION << 8);
if (!(init = _nvram_get("sdram_init")) ||
!(config = _nvram_get("sdram_config")) ||
!(refresh = _nvram_get("sdram_refresh")) ||
!(ncdl = _nvram_get("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 |= (bcm_strtoul(init, NULL, 0) & 0xffff) << 16;
header->config_refresh = bcm_strtoul(config, NULL, 0) & 0xffff;
header->config_refresh |= (bcm_strtoul(refresh, NULL, 0) & 0xffff) << 16;
header->config_ncdl = bcm_strtoul(ncdl, NULL, 0);
}
/* Clear data area */
ptr = (char *) header + sizeof(struct nvram_header);
bzero(ptr, NVRAM_SPACE - sizeof(struct nvram_header));
/* Leave space for a double NUL at the end */
end = (char *) header + NVRAM_SPACE - 2;
/* Write out all tuples */
for (i = 0; i < ARRAYSIZE(nvram_hash); i++) {
for (t = 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 NUL */
ptr += 2;
/* Set new length */
header->len = ROUNDUP(ptr - (char *) header, 4);
/* Little-endian CRC8 over the last 11 bytes of the header */
tmp.crc_ver_init = htol32(header->crc_ver_init);
tmp.config_refresh = htol32(header->config_refresh);
tmp.config_ncdl = htol32(header->config_ncdl);
crc = crc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE);
/* Continue CRC8 over data bytes */
crc = crc8((char *) &header[1], header->len - sizeof(struct nvram_header), crc);
/* Set new CRC8 */
header->crc_ver_init |= crc;
/* Reinitialize hash table */
return nvram_rehash(header);
}
/* Initialize hash table. Should be locked. */
int
_nvram_init(void)
{
struct nvram_header *header;
int ret;
if (!(header = (struct nvram_header *) MALLOC(NVRAM_SPACE))) {
printf("nvram_init: out of memory\n");
return -12; /* -ENOMEM */
}
if ((ret = _nvram_read(header)) == 0 &&
header->magic == NVRAM_MAGIC)
nvram_rehash(header);
MFREE(header, NVRAM_SPACE);
return ret;
}
/* Free hash table. Should be locked. */
void
_nvram_exit(void)
{
nvram_free();
}

View File

@ -1,638 +0,0 @@
/*
* NVRAM variable manipulation (Linux kernel half)
*
* 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.
*
* $Id$
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/bootmem.h>
#include <linux/wrapper.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/mtd/mtd.h>
#include <asm/addrspace.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <typedefs.h>
#include <bcmendian.h>
#include <bcmnvram.h>
#include <bcmutils.h>
#include <sbconfig.h>
#include <sbchipc.h>
#include <sbutils.h>
#include <sbmips.h>
#include <sflash.h>
/* In BSS to minimize text size and page aligned so it can be mmap()-ed */
static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE)));
#ifdef MODULE
#define early_nvram_get(name) nvram_get(name)
#else /* !MODULE */
/* Global SB handle */
extern void *bcm947xx_sbh;
extern spinlock_t bcm947xx_sbh_lock;
/* Convenience */
#define sbh bcm947xx_sbh
#define sbh_lock bcm947xx_sbh_lock
#define KB * 1024
#define MB * 1024 * 1024
/* Probe for NVRAM header */
static void __init
early_nvram_init(void)
{
struct nvram_header *header;
chipcregs_t *cc;
struct sflash *info = NULL;
int i;
uint32 base, off, lim;
if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) {
base = CC_FLASH_BASE;
switch (readl(&cc->capabilities) & CAP_FLASH_MASK) {
case PFLASH:
lim = CC_FLASH_MAX;
break;
case SFLASH_ST:
case SFLASH_AT:
if ((info = sflash_init(cc)) == NULL)
return;
lim = info->size;
break;
case FLASH_NONE:
default:
return;
}
} else {
/* extif assumed, Stop at 4 MB */
base = FLASH_BASE;
lim = FLASH_MAX;
}
off = FLASH_MIN;
while (off <= lim) {
/* Windowed flash access */
header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
if (header->magic == NVRAM_MAGIC) {
u32 *src = (u32 *) header;
u32 *dst = (u32 *) nvram_buf;
for (i = 0; i < sizeof(struct nvram_header); i += 4)
*dst++ = *src++;
for (; i < header->len && i < NVRAM_SPACE; i += 4)
*dst++ = ltoh32(*src++);
return;
}
/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
if (off == 1 KB)
break;
else if (off == 4 KB)
off = 1 KB;
else if (off == lim)
off = 4 KB;
else
off <<= 1;
}
}
/* Early (before mm or mtd) read-only access to NVRAM */
static char * __init
early_nvram_get(const char *name)
{
char *var, *value, *end, *eq;
if (!name)
return NULL;
if (!nvram_buf[0])
early_nvram_init();
/* Look for name=value and return value */
var = &nvram_buf[sizeof(struct nvram_header)];
end = nvram_buf + sizeof(nvram_buf) - 2;
end[0] = end[1] = '\0';
for (; *var; var = value + strlen(value) + 1) {
if (!(eq = strchr(var, '=')))
break;
value = eq + 1;
if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0)
return value;
}
return NULL;
}
#endif /* !MODULE */
extern char * _nvram_get(const char *name);
extern int _nvram_set(const char *name, const char *value);
extern int _nvram_unset(const char *name);
extern int _nvram_getall(char *buf, int count);
extern int _nvram_commit(struct nvram_header *header);
extern int _nvram_init(void);
extern void _nvram_exit(void);
/* Globals */
static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED;
static struct semaphore nvram_sem;
static unsigned long nvram_offset = 0;
static int nvram_major = -1;
static devfs_handle_t nvram_handle = NULL;
static struct mtd_info *nvram_mtd = NULL;
int
_nvram_read(char *buf)
{
struct nvram_header *header = (struct nvram_header *) buf;
size_t len;
if (!nvram_mtd ||
MTD_READ(nvram_mtd, nvram_mtd->size - NVRAM_SPACE, NVRAM_SPACE, &len, buf) ||
len != NVRAM_SPACE ||
header->magic != NVRAM_MAGIC) {
/* Maybe we can recover some data from early initialization */
memcpy(buf, nvram_buf, NVRAM_SPACE);
}
return 0;
}
struct nvram_tuple *
_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value)
{
if ((nvram_offset + strlen(value) + 1) > NVRAM_SPACE)
return NULL;
if (!t) {
if (!(t = kmalloc(sizeof(struct nvram_tuple) + strlen(name) + 1, GFP_ATOMIC)))
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)) {
t->value = &nvram_buf[nvram_offset];
strcpy(t->value, value);
nvram_offset += strlen(value) + 1;
}
return t;
}
void
_nvram_free(struct nvram_tuple *t)
{
if (!t)
nvram_offset = 0;
else
kfree(t);
}
int
nvram_set(const char *name, const char *value)
{
unsigned long flags;
int ret;
struct nvram_header *header;
spin_lock_irqsave(&nvram_lock, flags);
if ((ret = _nvram_set(name, value))) {
/* Consolidate space and try again */
if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) {
if (_nvram_commit(header) == 0)
ret = _nvram_set(name, value);
kfree(header);
}
}
spin_unlock_irqrestore(&nvram_lock, flags);
return ret;
}
char *
real_nvram_get(const char *name)
{
unsigned long flags;
char *value;
spin_lock_irqsave(&nvram_lock, flags);
value = _nvram_get(name);
spin_unlock_irqrestore(&nvram_lock, flags);
return value;
}
char *
nvram_get(const char *name)
{
if (nvram_major >= 0)
return real_nvram_get(name);
else
return early_nvram_get(name);
}
int
nvram_unset(const char *name)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&nvram_lock, flags);
ret = _nvram_unset(name);
spin_unlock_irqrestore(&nvram_lock, flags);
return ret;
}
static void
erase_callback(struct erase_info *done)
{
wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv;
wake_up(wait_q);
}
int
nvram_commit(void)
{
char *buf;
size_t erasesize, len;
unsigned int i;
int ret;
struct nvram_header *header;
unsigned long flags;
u_int32_t offset;
DECLARE_WAITQUEUE(wait, current);
wait_queue_head_t wait_q;
struct erase_info erase;
printk("nvram_commit(): init\n");
if (!nvram_mtd) {
printk("nvram_commit: NVRAM not found\n");
return -ENODEV;
}
if (in_interrupt()) {
printk("nvram_commit: not committing in interrupt\n");
return -EINVAL;
}
/* Backup sector blocks to be erased */
erasesize = ROUNDUP(NVRAM_SPACE, nvram_mtd->erasesize);
if (!(buf = kmalloc(erasesize, GFP_KERNEL))) {
printk("nvram_commit: out of memory\n");
return -ENOMEM;
}
down(&nvram_sem);
#if 0
offset = nvram_mtd->size - erasesize;
i = erasesize - NVRAM_SPACE;
ret = MTD_READ(nvram_mtd, offset, i, &len, buf);
if (ret || len != i) {
printk("nvram_commit: read error\n");
ret = -EIO;
goto done;
#endif
if ((i = erasesize - NVRAM_SPACE) > 0) {
offset = nvram_mtd->size - erasesize;
len = 0;
ret = MTD_READ(nvram_mtd, offset, i, &len, buf);
if (ret || len != i) {
printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i);
ret = -EIO;
goto done;
}
header = (struct nvram_header *)(buf + i);
} else {
offset = nvram_mtd->size - NVRAM_SPACE;
header = (struct nvram_header *)buf;
}
/* Regenerate NVRAM */
spin_lock_irqsave(&nvram_lock, flags);
ret = _nvram_commit(header);
spin_unlock_irqrestore(&nvram_lock, flags);
if (ret)
goto done;
/* Erase sector blocks */
init_waitqueue_head(&wait_q);
for (; offset < nvram_mtd->size - NVRAM_SPACE + header->len; offset += nvram_mtd->erasesize) {
erase.mtd = nvram_mtd;
erase.addr = offset;
erase.len = nvram_mtd->erasesize;
erase.callback = erase_callback;
erase.priv = (u_long) &wait_q;
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&wait_q, &wait);
/* Unlock sector blocks */
if (nvram_mtd->unlock)
nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize);
if ((ret = MTD_ERASE(nvram_mtd, &erase))) {
set_current_state(TASK_RUNNING);
remove_wait_queue(&wait_q, &wait);
printk("nvram_commit: erase error\n");
goto done;
}
/* Wait for erase to finish */
schedule();
remove_wait_queue(&wait_q, &wait);
}
/* Write partition up to end of data area */
offset = nvram_mtd->size - erasesize;
i = erasesize - NVRAM_SPACE + header->len;
ret = MTD_WRITE(nvram_mtd, offset, i, &len, buf);
if (ret || len != i) {
printk("nvram_commit: write error\n");
ret = -EIO;
goto done;
}
/*
* Reading a few bytes back here will put the device
* back to the correct mode on certain flashes */
offset = nvram_mtd->size - erasesize;
ret = MTD_READ(nvram_mtd, offset, 4, &len, buf);
done:
up(&nvram_sem);
kfree(buf);
printk("nvram_commit(): end\n");
return ret;
}
int
nvram_getall(char *buf, int count)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&nvram_lock, flags);
ret = _nvram_getall(buf, count);
spin_unlock_irqrestore(&nvram_lock, flags);
return ret;
}
EXPORT_SYMBOL(nvram_get);
EXPORT_SYMBOL(nvram_getall);
EXPORT_SYMBOL(nvram_set);
EXPORT_SYMBOL(nvram_unset);
EXPORT_SYMBOL(nvram_commit);
/* User mode interface below */
static ssize_t
dev_nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
char tmp[100], *name = tmp, *value;
ssize_t ret;
unsigned long off;
if (count > sizeof(tmp)) {
if (!(name = kmalloc(count, GFP_KERNEL)))
return -ENOMEM;
}
if (copy_from_user(name, buf, count)) {
ret = -EFAULT;
goto done;
}
if (*name == '\0') {
/* Get all variables */
ret = nvram_getall(name, count);
if (ret == 0) {
if (copy_to_user(buf, name, count)) {
ret = -EFAULT;
goto done;
}
ret = count;
}
} else {
if (!(value = nvram_get(name))) {
ret = 0;
goto done;
}
/* Provide the offset into mmap() space */
off = (unsigned long) value - (unsigned long) nvram_buf;
if (put_user(off, (unsigned long *) buf)) {
ret = -EFAULT;
goto done;
}
ret = sizeof(unsigned long);
}
flush_cache_all();
done:
if (name != tmp)
kfree(name);
return ret;
}
static ssize_t
dev_nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
char tmp[100], *name = tmp, *value;
ssize_t ret;
if (count > sizeof(tmp)) {
if (!(name = kmalloc(count, GFP_KERNEL)))
return -ENOMEM;
}
if (copy_from_user(name, buf, count)) {
ret = -EFAULT;
goto done;
}
value = name;
name = strsep(&value, "=");
if (value)
ret = nvram_set(name, value) ? : count;
else
ret = nvram_unset(name) ? : count;
done:
if (name != tmp)
kfree(name);
return ret;
}
static int
dev_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
if (cmd != NVRAM_MAGIC)
return -EINVAL;
return nvram_commit();
}
static int
dev_nvram_mmap(struct file *file, struct vm_area_struct *vma)
{
unsigned long offset = virt_to_phys(nvram_buf);
if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
return 0;
}
static int
dev_nvram_open(struct inode *inode, struct file * file)
{
MOD_INC_USE_COUNT;
return 0;
}
static int
dev_nvram_release(struct inode *inode, struct file * file)
{
MOD_DEC_USE_COUNT;
return 0;
}
static struct file_operations dev_nvram_fops = {
owner: THIS_MODULE,
open: dev_nvram_open,
release: dev_nvram_release,
read: dev_nvram_read,
write: dev_nvram_write,
ioctl: dev_nvram_ioctl,
mmap: dev_nvram_mmap,
};
static void
dev_nvram_exit(void)
{
int order = 0;
struct page *page, *end;
if (nvram_handle)
devfs_unregister(nvram_handle);
if (nvram_major >= 0)
devfs_unregister_chrdev(nvram_major, "nvram");
if (nvram_mtd)
put_mtd_device(nvram_mtd);
while ((PAGE_SIZE << order) < NVRAM_SPACE)
order++;
end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
for (page = virt_to_page(nvram_buf); page <= end; page++)
mem_map_unreserve(page);
_nvram_exit();
}
static int __init
dev_nvram_init(void)
{
int order = 0, ret = 0;
struct page *page, *end;
unsigned int i;
/* Allocate and reserve memory to mmap() */
while ((PAGE_SIZE << order) < NVRAM_SPACE)
order++;
end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
for (page = virt_to_page(nvram_buf); page <= end; page++)
mem_map_reserve(page);
#ifdef CONFIG_MTD
/* Find associated MTD device */
for (i = 0; i < MAX_MTD_DEVICES; i++) {
nvram_mtd = get_mtd_device(NULL, i);
if (nvram_mtd) {
if (!strcmp(nvram_mtd->name, "nvram") &&
nvram_mtd->size >= NVRAM_SPACE)
break;
put_mtd_device(nvram_mtd);
}
}
if (i >= MAX_MTD_DEVICES)
nvram_mtd = NULL;
#endif
/* Initialize hash table lock */
spin_lock_init(&nvram_lock);
/* Initialize commit semaphore */
init_MUTEX(&nvram_sem);
/* Register char device */
if ((nvram_major = devfs_register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) {
ret = nvram_major;
goto err;
}
/* Initialize hash table */
_nvram_init();
/* Create /dev/nvram handle */
nvram_handle = devfs_register(NULL, "nvram", DEVFS_FL_NONE, nvram_major, 0,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &dev_nvram_fops, NULL);
/* Set the SDRAM NCDL value into NVRAM if not already done */
if (getintvar(NULL, "sdram_ncdl") == 0) {
unsigned int ncdl;
char buf[] = "0x00000000";
if ((ncdl = sb_memc_get_ncdl(sbh))) {
sprintf(buf, "0x%08x", ncdl);
nvram_set("sdram_ncdl", buf);
nvram_commit();
}
}
return 0;
err:
dev_nvram_exit();
return ret;
}
module_init(dev_nvram_init);
module_exit(dev_nvram_exit);

View File

@ -1,352 +0,0 @@
/*
* Low-Level PCI and SB support for BCM47xx (Linux support code)
*
* 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.
*
* $Id$
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/paccess.h>
#include <typedefs.h>
#include <bcmutils.h>
#include <sbconfig.h>
#include <sbpci.h>
#include <pcicfg.h>
#include <sbutils.h>
#include <bcmdevs.h>
#include <bcmnvram.h>
/* Global SB handle */
extern void *bcm947xx_sbh;
extern spinlock_t bcm947xx_sbh_lock;
/* Convenience */
#define sbh bcm947xx_sbh
#define sbh_lock bcm947xx_sbh_lock
static int
sbpci_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static int
sbpci_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static int
sbpci_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static int
sbpci_write_config_byte(struct pci_dev *dev, int where, u8 value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static int
sbpci_write_config_word(struct pci_dev *dev, int where, u16 value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static int
sbpci_write_config_dword(struct pci_dev *dev, int where, u32 value)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&sbh_lock, flags);
ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value));
spin_unlock_irqrestore(&sbh_lock, flags);
return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
}
static struct pci_ops pcibios_ops = {
sbpci_read_config_byte,
sbpci_read_config_word,
sbpci_read_config_dword,
sbpci_write_config_byte,
sbpci_write_config_word,
sbpci_write_config_dword
};
void __init
pcibios_init(void)
{
ulong flags;
if (!(sbh = sb_kattach()))
panic("sb_kattach failed");
spin_lock_init(&sbh_lock);
spin_lock_irqsave(&sbh_lock, flags);
sbpci_init(sbh);
spin_unlock_irqrestore(&sbh_lock, flags);
set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000));
/* Scan the SB bus */
pci_scan_bus(0, &pcibios_ops, NULL);
}
char * __init
pcibios_setup(char *str)
{
if (!strncmp(str, "ban=", 4)) {
sbpci_ban(simple_strtoul(str + 4, NULL, 0));
return NULL;
}
return (str);
}
static u32 pci_iobase = 0x100;
static u32 pci_membase = SB_PCI_DMA;
void __init
pcibios_fixup_bus(struct pci_bus *b)
{
struct list_head *ln;
struct pci_dev *d;
struct resource *res;
int pos, size;
u32 *base;
u8 irq;
printk("PCI: Fixing up bus %d\n", b->number);
/* Fix up SB */
if (b->number == 0) {
for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
d = pci_dev_b(ln);
/* Fix up interrupt lines */
pci_read_config_byte(d, PCI_INTERRUPT_LINE, &irq);
d->irq = irq + 2;
pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
}
}
/* Fix up external PCI */
else {
for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
d = pci_dev_b(ln);
/* Fix up resource bases */
for (pos = 0; pos < 6; pos++) {
res = &d->resource[pos];
base = (res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase;
if (res->end) {
size = res->end - res->start + 1;
if (*base & (size - 1))
*base = (*base + size) & ~(size - 1);
res->start = *base;
res->end = res->start + size - 1;
*base += size;
pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
}
/* Fix up PCI bridge BAR0 only */
if (b->number == 1 && PCI_SLOT(d->devfn) == 0)
break;
}
/* Fix up interrupt lines */
if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
}
}
}
unsigned int
pcibios_assign_all_busses(void)
{
return 1;
}
void
pcibios_align_resource(void *data, struct resource *res,
unsigned long size, unsigned long align)
{
}
int
pcibios_enable_resources(struct pci_dev *dev)
{
u16 cmd, old_cmd;
int idx;
struct resource *r;
/* External PCI only */
if (dev->bus->number == 0)
return 0;
pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
for(idx=0; idx<6; idx++) {
r = &dev->resource[idx];
if (r->flags & IORESOURCE_IO)
cmd |= PCI_COMMAND_IO;
if (r->flags & IORESOURCE_MEM)
cmd |= PCI_COMMAND_MEMORY;
}
if (dev->resource[PCI_ROM_RESOURCE].start)
cmd |= PCI_COMMAND_MEMORY;
if (cmd != old_cmd) {
printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
return 0;
}
int
pcibios_enable_device(struct pci_dev *dev, int mask)
{
ulong flags;
uint coreidx;
/* External PCI device enable */
if (dev->bus->number != 0)
return pcibios_enable_resources(dev);
/* These cores come out of reset enabled */
if (dev->device == SB_MIPS ||
dev->device == SB_MIPS33 ||
dev->device == SB_EXTIF ||
dev->device == SB_CC)
return 0;
spin_lock_irqsave(&sbh_lock, flags);
coreidx = sb_coreidx(sbh);
if (!sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)))
return PCIBIOS_DEVICE_NOT_FOUND;
/*
* The USB core requires a special bit to be set during core
* reset to enable host (OHCI) mode. Resetting the SB core in
* pcibios_enable_device() is a hack for compatibility with
* vanilla usb-ohci so that it does not have to know about
* SB. A driver that wants to use the USB core in device mode
* should know about SB and should reset the bit back to 0
* after calling pcibios_enable_device().
*/
if (sb_coreid(sbh) == SB_USB) {
sb_core_disable(sbh, sb_coreflags(sbh, 0, 0));
sb_core_reset(sbh, 1 << 29);
} else
sb_core_reset(sbh, 0);
sb_setcoreidx(sbh, coreidx);
spin_unlock_irqrestore(&sbh_lock, flags);
return 0;
}
void
pcibios_update_resource(struct pci_dev *dev, struct resource *root,
struct resource *res, int resource)
{
unsigned long where, size;
u32 reg;
/* External PCI only */
if (dev->bus->number == 0)
return;
where = PCI_BASE_ADDRESS_0 + (resource * 4);
size = res->end - res->start;
pci_read_config_dword(dev, where, &reg);
reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
pci_write_config_dword(dev, where, reg);
}
static void __init
quirk_sbpci_bridge(struct pci_dev *dev)
{
if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
return;
printk("PCI: Fixing up bridge\n");
/* Enable PCI bridge bus mastering and memory space */
pci_set_master(dev);
pcibios_enable_resources(dev);
/* Enable PCI bridge BAR1 prefetch and burst */
pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
}
/*
* If we set up a device for bus mastering, we need to check the latency
* timer as certain crappy BIOSes forget to set it properly.
*/
unsigned int pcibios_max_latency = 255;
void pcibios_set_master(struct pci_dev *dev)
{
u8 lat;
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
if (lat < 16)
lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
else if (lat > pcibios_max_latency)
lat = pcibios_max_latency;
else
return;
printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
}
struct pci_fixup pcibios_fixups[] = {
{ PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, quirk_sbpci_bridge },
{ 0 }
};

View File

@ -1,67 +0,0 @@
/*
* Broadcom BCM47xx Performance Counter /proc/cpuinfo support
*
* 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.
*
* $Id$
*/
#include <asm/mipsregs.h>
/*
* BCM4710 performance counter register select values
* No even-odd control-counter mapping, just counters
*/
#define PERF_DCACHE_HIT 0
#define PERF_DCACHE_MISS 1
#define PERF_ICACHE_HIT 2
#define PERF_ICACHE_MISS 3
#define PERF_ICOUNT 4
/*
* Move from Coprocessor 0 Register 25 Select n
* data <- CPR[0,25,n]
* GPR[1] <- data
*/
#define read_bcm4710_perf_cntr(n) \
({ int __res; \
__asm__ __volatile__( \
".set\tnoreorder\n\t" \
".set\tnoat\n\t" \
".word\t"STR(0x4001c800|(n))"\n\t" \
"move\t%0,$1\n\t" \
".set\tat\n\t" \
".set\treorder" \
:"=r" (__res)); \
__res;})
asmlinkage unsigned int read_perf_cntr(unsigned int counter)
{
switch (counter) {
case PERF_DCACHE_HIT: return read_bcm4710_perf_cntr(PERF_DCACHE_HIT);
case PERF_DCACHE_MISS: return read_bcm4710_perf_cntr(PERF_DCACHE_MISS);
case PERF_ICACHE_HIT: return read_bcm4710_perf_cntr(PERF_ICACHE_HIT);
case PERF_ICACHE_MISS: return read_bcm4710_perf_cntr(PERF_ICACHE_MISS);
case PERF_ICOUNT: return read_bcm4710_perf_cntr(PERF_ICOUNT);
}
return 0;
}
asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val)
{
}
asmlinkage unsigned int read_perf_cntl(unsigned int counter)
{
return 0;
}
asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val)
{
}

View File

@ -1,41 +0,0 @@
/*
* Early initialization code for BCM94710 boards
*
* 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.
*
* $Id$
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/bootinfo.h>
void __init
prom_init(int argc, const char **argv)
{
unsigned long mem;
mips_machgroup = MACH_GROUP_BRCM;
mips_machtype = MACH_BCM947XX;
/* Figure out memory size by finding aliases */
for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
if (*(unsigned long *)((unsigned long)(prom_init) + mem) ==
*(unsigned long *)(prom_init))
break;
}
add_memory_region(0, mem, BOOT_MEM_RAM);
}
void __init
prom_free_prom_memory(void)
{
}

View File

@ -1,951 +0,0 @@
/*
* BCM47XX Sonics SiliconBackplane MIPS core routines
*
* 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.
*
* $Id$
*/
#include <typedefs.h>
#include <osl.h>
#include <sbutils.h>
#include <bcmdevs.h>
#include <bcmnvram.h>
#include <bcmutils.h>
#include <hndmips.h>
#include <sbconfig.h>
#include <sbextif.h>
#include <sbchipc.h>
#include <sbmemc.h>
/*
* Memory segments (32bit kernel mode addresses)
*/
#undef KUSEG
#undef KSEG0
#undef KSEG1
#undef KSEG2
#undef KSEG3
#define KUSEG 0x00000000
#define KSEG0 0x80000000
#define KSEG1 0xa0000000
#define KSEG2 0xc0000000
#define KSEG3 0xe0000000
/*
* Map an address to a certain kernel segment
*/
#undef KSEG0ADDR
#undef KSEG1ADDR
#undef KSEG2ADDR
#undef KSEG3ADDR
#define KSEG0ADDR(a) (((a) & 0x1fffffff) | KSEG0)
#define KSEG1ADDR(a) (((a) & 0x1fffffff) | KSEG1)
#define KSEG2ADDR(a) (((a) & 0x1fffffff) | KSEG2)
#define KSEG3ADDR(a) (((a) & 0x1fffffff) | KSEG3)
/*
* The following macros are especially useful for __asm__
* inline assembler.
*/
#ifndef __STR
#define __STR(x) #x
#endif
#ifndef STR
#define STR(x) __STR(x)
#endif
/* *********************************************************************
* CP0 Registers
********************************************************************* */
#define C0_INX 0 /* CP0: TLB Index */
#define C0_RAND 1 /* CP0: TLB Random */
#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */
#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */
#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */
#define C0_CTEXT 4 /* CP0: Context */
#define C0_PGMASK 5 /* CP0: TLB PageMask */
#define C0_WIRED 6 /* CP0: TLB Wired */
#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */
#define C0_COUNT 9 /* CP0: Count */
#define C0_TLBHI 10 /* CP0: TLB EntryHi */
#define C0_COMPARE 11 /* CP0: Compare */
#define C0_SR 12 /* CP0: Processor Status */
#define C0_STATUS C0_SR /* CP0: Processor Status */
#define C0_CAUSE 13 /* CP0: Exception Cause */
#define C0_EPC 14 /* CP0: Exception PC */
#define C0_PRID 15 /* CP0: Processor Revision Indentifier */
#define C0_CONFIG 16 /* CP0: Config */
#define C0_LLADDR 17 /* CP0: LLAddr */
#define C0_WATCHLO 18 /* CP0: WatchpointLo */
#define C0_WATCHHI 19 /* CP0: WatchpointHi */
#define C0_XCTEXT 20 /* CP0: XContext */
#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */
#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */
#define C0_ECC 26 /* CP0: ECC */
#define C0_CACHEERR 27 /* CP0: CacheErr */
#define C0_TAGLO 28 /* CP0: TagLo */
#define C0_TAGHI 29 /* CP0: TagHi */
#define C0_ERREPC 30 /* CP0: ErrorEPC */
/*
* Macros to access the system control coprocessor
*/
#define MFC0(source, sel) \
({ \
int __res; \
__asm__ __volatile__( \
".set\tnoreorder\n\t" \
".set\tnoat\n\t" \
".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \
"move\t%0,$1\n\t" \
".set\tat\n\t" \
".set\treorder" \
:"=r" (__res) \
: \
:"$1"); \
__res; \
})
#define MTC0(source, sel, value) \
do { \
__asm__ __volatile__( \
".set\tnoreorder\n\t" \
".set\tnoat\n\t" \
"move\t$1,%z0\n\t" \
".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \
".set\tat\n\t" \
".set\treorder" \
: \
:"Jr" (value) \
:"$1"); \
} while (0)
/*
* R4x00 interrupt enable / cause bits
*/
#undef IE_SW0
#undef IE_SW1
#undef IE_IRQ0
#undef IE_IRQ1
#undef IE_IRQ2
#undef IE_IRQ3
#undef IE_IRQ4
#undef IE_IRQ5
#define IE_SW0 (1<< 8)
#define IE_SW1 (1<< 9)
#define IE_IRQ0 (1<<10)
#define IE_IRQ1 (1<<11)
#define IE_IRQ2 (1<<12)
#define IE_IRQ3 (1<<13)
#define IE_IRQ4 (1<<14)
#define IE_IRQ5 (1<<15)
/*
* Bitfields in the R4xx0 cp0 status register
*/
#define ST0_IE 0x00000001
#define ST0_EXL 0x00000002
#define ST0_ERL 0x00000004
#define ST0_KSU 0x00000018
# define KSU_USER 0x00000010
# define KSU_SUPERVISOR 0x00000008
# define KSU_KERNEL 0x00000000
#define ST0_UX 0x00000020
#define ST0_SX 0x00000040
#define ST0_KX 0x00000080
#define ST0_DE 0x00010000
#define ST0_CE 0x00020000
/*
* Status register bits available in all MIPS CPUs.
*/
#define ST0_IM 0x0000ff00
#define ST0_CH 0x00040000
#define ST0_SR 0x00100000
#define ST0_TS 0x00200000
#define ST0_BEV 0x00400000
#define ST0_RE 0x02000000
#define ST0_FR 0x04000000
#define ST0_CU 0xf0000000
#define ST0_CU0 0x10000000
#define ST0_CU1 0x20000000
#define ST0_CU2 0x40000000
#define ST0_CU3 0x80000000
#define ST0_XX 0x80000000 /* MIPS IV naming */
/*
* Cache Operations
*/
#ifndef Fill_I
#define Fill_I 0x14
#endif
#define cache_unroll(base,op) \
__asm__ __volatile__(" \
.set noreorder; \
.set mips3; \
cache %1, (%0); \
.set mips0; \
.set reorder" \
: \
: "r" (base), \
"i" (op));
/*
* These are the UART port assignments, expressed as offsets from the base
* register. These assignments should hold for any serial port based on
* a 8250, 16450, or 16550(A).
*/
#define UART_MCR 4 /* Out: Modem Control Register */
#define UART_MSR 6 /* In: Modem Status Register */
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
/*
* Returns TRUE if an external UART exists at the given base
* register.
*/
static bool
serial_exists(uint8 *regs)
{
uint8 save_mcr, status1;
save_mcr = R_REG(&regs[UART_MCR]);
W_REG(&regs[UART_MCR], UART_MCR_LOOP | 0x0a);
status1 = R_REG(&regs[UART_MSR]) & 0xf0;
W_REG(&regs[UART_MCR], save_mcr);
return (status1 == 0x90);
}
/*
* Initializes UART access. The callback function will be called once
* per found UART.
*/
void
sb_serial_init(void *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift))
{
void *regs;
ulong base;
uint irq;
int i, n;
if ((regs = sb_setcore(sbh, SB_EXTIF, 0))) {
extifregs_t *eir = (extifregs_t *) regs;
sbconfig_t *sb;
/* Determine external UART register base */
sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF);
base = EXTIF_CFGIF_BASE(sb_base(R_REG(&sb->sbadmatch1)));
/* Determine IRQ */
irq = sb_irq(sbh);
/* Disable GPIO interrupt initially */
W_REG(&eir->gpiointpolarity, 0);
W_REG(&eir->gpiointmask, 0);
/* Search for external UARTs */
n = 2;
for (i = 0; i < 2; i++) {
regs = (void *) REG_MAP(base + (i * 8), 8);
if (serial_exists(regs)) {
/* Set GPIO 1 to be the external UART IRQ */
W_REG(&eir->gpiointmask, 2);
if (add)
add(regs, irq, 13500000, 0);
}
}
/* Add internal UART if enabled */
if (R_REG(&eir->corecontrol) & CC_UE)
if (add)
add((void *) &eir->uartdata, irq, sb_clock(sbh), 2);
} else if ((regs = sb_setcore(sbh, SB_CC, 0))) {
chipcregs_t *cc = (chipcregs_t *) regs;
uint32 rev, cap, pll, baud_base, div;
/* Determine core revision and capabilities */
rev = sb_corerev(sbh);
cap = R_REG(&cc->capabilities);
pll = cap & CAP_PLL_MASK;
/* Determine IRQ */
irq = sb_irq(sbh);
if (pll == PLL_TYPE1) {
/* PLL clock */
baud_base = sb_clock_rate(pll,
R_REG(&cc->clockcontrol_n),
R_REG(&cc->clockcontrol_m2));
div = 1;
} else if (rev >= 3) {
/* Internal backplane clock */
baud_base = sb_clock_rate(pll,
R_REG(&cc->clockcontrol_n),
R_REG(&cc->clockcontrol_sb));
div = 2; /* Minimum divisor */
W_REG(&cc->clkdiv, ((R_REG(&cc->clkdiv) & ~CLKD_UART) | div));
} else {
/* Fixed internal backplane clock */
baud_base = 88000000;
div = 48;
}
/* Clock source depends on strapping if UartClkOverride is unset */
if ((rev > 0) && ((R_REG(&cc->corecontrol) & CC_UARTCLKO) == 0)) {
if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) {
/* Internal divided backplane clock */
baud_base /= div;
} else {
/* Assume external clock of 1.8432 MHz */
baud_base = 1843200;
}
}
/* Add internal UARTs */
n = cap & CAP_UARTS_MASK;
for (i = 0; i < n; i++) {
/* Register offset changed after revision 0 */
if (rev)
regs = (void *)((ulong) &cc->uart0data + (i * 256));
else
regs = (void *)((ulong) &cc->uart0data + (i * 8));
if (add)
add(regs, irq, baud_base, 0);
}
}
}
/* Returns the SB interrupt flag of the current core. */
uint32
sb_flag(void *sbh)
{
void *regs;
sbconfig_t *sb;
regs = sb_coreregs(sbh);
sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
return (R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK);
}
static const uint32 sbips_int_mask[] = {
0,
SBIPS_INT1_MASK,
SBIPS_INT2_MASK,
SBIPS_INT3_MASK,
SBIPS_INT4_MASK
};
static const uint32 sbips_int_shift[] = {
0,
0,
SBIPS_INT2_SHIFT,
SBIPS_INT3_SHIFT,
SBIPS_INT4_SHIFT
};
/*
* Returns the MIPS IRQ assignment of the current core. If unassigned,
* 0 is returned.
*/
uint
sb_irq(void *sbh)
{
uint idx;
void *regs;
sbconfig_t *sb;
uint32 flag, sbipsflag;
uint irq = 0;
flag = sb_flag(sbh);
idx = sb_coreidx(sbh);
if ((regs = sb_setcore(sbh, SB_MIPS, 0)) ||
(regs = sb_setcore(sbh, SB_MIPS33, 0))) {
sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
/* sbipsflag specifies which core is routed to interrupts 1 to 4 */
sbipsflag = R_REG(&sb->sbipsflag);
for (irq = 1; irq <= 4; irq++) {
if (((sbipsflag & sbips_int_mask[irq]) >> sbips_int_shift[irq]) == flag)
break;
}
if (irq == 5)
irq = 0;
}
sb_setcoreidx(sbh, idx);
return irq;
}
/* Clears the specified MIPS IRQ. */
static void
sb_clearirq(void *sbh, uint irq)
{
void *regs;
sbconfig_t *sb;
if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) &&
!(regs = sb_setcore(sbh, SB_MIPS33, 0)))
ASSERT(regs);
sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
if (irq == 0)
W_REG(&sb->sbintvec, 0);
else
OR_REG(&sb->sbipsflag, sbips_int_mask[irq]);
}
/*
* Assigns the specified MIPS IRQ to the specified core. Shared MIPS
* IRQ 0 may be assigned more than once.
*/
static void
sb_setirq(void *sbh, uint irq, uint coreid, uint coreunit)
{
void *regs;
sbconfig_t *sb;
uint32 flag;
regs = sb_setcore(sbh, coreid, coreunit);
ASSERT(regs);
flag = sb_flag(sbh);
if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) &&
!(regs = sb_setcore(sbh, SB_MIPS33, 0)))
ASSERT(regs);
sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
if (irq == 0)
OR_REG(&sb->sbintvec, 1 << flag);
else {
flag <<= sbips_int_shift[irq];
ASSERT(!(flag & ~sbips_int_mask[irq]));
flag |= R_REG(&sb->sbipsflag) & ~sbips_int_mask[irq];
W_REG(&sb->sbipsflag, flag);
}
}
/*
* Initializes clocks and interrupts. SB and NVRAM access must be
* initialized prior to calling.
*/
void
sb_mips_init(void *sbh)
{
ulong hz, ns, tmp;
extifregs_t *eir;
chipcregs_t *cc;
char *value;
uint irq;
/* Figure out current SB clock speed */
if ((hz = sb_clock(sbh)) == 0)
hz = 100000000;
ns = 1000000000 / hz;
/* Setup external interface timing */
if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) {
/* Initialize extif so we can get to the LEDs and external UART */
W_REG(&eir->prog_config, CF_EN);
/* Set timing for the flash */
tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */
tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */
/* Set programmable interface timing for external uart */
tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */
tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */
tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */
} else if ((cc = sb_setcore(sbh, SB_CC, 0))) {
/* Set timing for the flash */
tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
tmp |= CEIL(10, ns) << FW_W1_SHIFT; /* W1 = 10nS */
tmp |= CEIL(120, ns); /* W0 = 120nS */
W_REG(&cc->flash_waitcount, tmp);
W_REG(&cc->pcmcia_memwait, tmp);
}
/* Chip specific initialization */
switch (sb_chip(sbh)) {
case BCM4710_DEVICE_ID:
/* Clear interrupt map */
for (irq = 0; irq <= 4; irq++)
sb_clearirq(sbh, irq);
sb_setirq(sbh, 0, SB_CODEC, 0);
sb_setirq(sbh, 0, SB_EXTIF, 0);
sb_setirq(sbh, 2, SB_ENET, 1);
sb_setirq(sbh, 3, SB_ILINE20, 0);
sb_setirq(sbh, 4, SB_PCI, 0);
ASSERT(eir);
value = nvram_get("et0phyaddr");
if (value && !strcmp(value, "31")) {
/* Enable internal UART */
W_REG(&eir->corecontrol, CC_UE);
/* Give USB its own interrupt */
sb_setirq(sbh, 1, SB_USB, 0);
} else {
/* Disable internal UART */
W_REG(&eir->corecontrol, 0);
/* Give Ethernet its own interrupt */
sb_setirq(sbh, 1, SB_ENET, 0);
sb_setirq(sbh, 0, SB_USB, 0);
}
break;
case BCM4310_DEVICE_ID:
MTC0(C0_BROADCOM, 0, MFC0(C0_BROADCOM, 0) & ~(1 << 22));
break;
}
}
uint32
sb_mips_clock(void *sbh)
{
extifregs_t *eir;
chipcregs_t *cc;
uint32 n, m;
uint idx;
uint32 pll_type, rate = 0;
/* get index of the current core */
idx = sb_coreidx(sbh);
pll_type = PLL_TYPE1;
/* switch to extif or chipc core */
if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
n = R_REG(&eir->clockcontrol_n);
m = R_REG(&eir->clockcontrol_sb);
} else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK;
n = R_REG(&cc->clockcontrol_n);
if ((pll_type == PLL_TYPE2) || (pll_type == PLL_TYPE4))
m = R_REG(&cc->clockcontrol_mips);
else if (pll_type == PLL_TYPE3) {
rate = 200000000;
goto out;
} else
m = R_REG(&cc->clockcontrol_sb);
} else
goto out;
/* calculate rate */
rate = sb_clock_rate(pll_type, n, m);
out:
/* switch back to previous core */
sb_setcoreidx(sbh, idx);
return rate;
}
static void
icache_probe(int *size, int *lsize)
{
uint32 config1;
uint sets, ways;
config1 = MFC0(C0_CONFIG, 1);
/* Instruction Cache Size = Associativity * Line Size * Sets Per Way */
if ((*lsize = ((config1 >> 19) & 7)))
*lsize = 2 << *lsize;
sets = 64 << ((config1 >> 22) & 7);
ways = 1 + ((config1 >> 16) & 7);
*size = *lsize * sets * ways;
}
#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
static void
handler(void)
{
/* Step 11 */
__asm__ (
".set\tmips32\n\t"
"ssnop\n\t"
"ssnop\n\t"
/* Disable interrupts */
/* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */
"mfc0 $15, $12\n\t"
"and $15, $15, -31746\n\t"
"mtc0 $15, $12\n\t"
"eret\n\t"
"nop\n\t"
"nop\n\t"
".set\tmips0"
);
}
/* The following MUST come right after handler() */
static void
afterhandler(void)
{
}
/*
* Set the MIPS, backplane and PCI clocks as closely as possible.
*/
bool
sb_mips_setclock(void *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock)
{
extifregs_t *eir = NULL;
chipcregs_t *cc = NULL;
mipsregs_t *mipsr = NULL;
volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci;
uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, new_ratio;
uint32 pll_type, sync_mode;
uint idx, i;
typedef struct {
uint32 mipsclock;
uint16 n;
uint32 sb;
uint32 pci33;
uint32 pci25;
} n3m_table_t;
static n3m_table_t type1_table[] = {
{ 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /* 96.000 32.000 24.000 */
{ 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */
{ 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */
{ 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, /* 108.000 32.400 24.923 */
{ 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, /* 112.000 32.000 24.889 */
{ 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, /* 115.200 32.000 24.000 */
{ 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, /* 120.000 30.000 24.000 */
{ 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, /* 124.800 31.200 24.960 */
{ 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, /* 128.000 32.000 24.000 */
{ 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, /* 132.000 33.000 24.750 */
{ 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, /* 136.000 32.640 24.727 */
{ 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, /* 140.000 30.000 24.706 */
{ 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, /* 144.000 30.857 24.686 */
{ 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, /* 150.857 33.000 24.000 */
{ 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, /* 152.000 32.571 24.000 */
{ 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, /* 156.000 31.200 24.960 */
{ 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, /* 160.000 32.000 24.000 */
{ 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, /* 163.200 32.640 24.727 */
{ 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, /* 168.000 32.000 24.889 */
{ 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, /* 176.000 33.000 24.000 */
};
typedef struct {
uint32 mipsclock;
uint32 sbclock;
uint16 n;
uint32 sb;
uint32 pci33;
uint32 m2;
uint32 m3;
uint32 ratio;
uint32 ratio_parm;
} n4m_table_t;
static n4m_table_t type2_table[] = {
{ 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
{ 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 },
{ 200000000, 100000000, 0x0303, 0x01000000, 0x01000600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 },
{ 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
{ 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
{ 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
{ 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
{ 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
{ 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 },
{ 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
{ 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
{ 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
{ 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 },
{ 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
{ 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 },
{ 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
{ 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 }
};
static n4m_table_t type4_table[] = {
{ 192000000, 96000000, 0x0702, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 0x21, 0x0aaa0555 },
{ 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 0x21, 0x0aaa0555 },
{ 216000000, 108000000, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 0x21, 0x0aaa0555 },
{ 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x11030305, 0x04000005, 0x94, 0x012a00a9 },
{ 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 0x21, 0x0aaa0555 },
{ 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 0x21, 0x0aaa0555 },
{ 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 0x21, 0x0aaa0555 },
{ 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 0x21, 0x0aaa0555 },
{ 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 0x73, 0x254a14a9 },
{ 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 0x73, 0x254a14a9 },
{ 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 0x73, 0x254a14a9 },
{ 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 0x52, 0x02520129 }
};
uint icache_size, ic_lsize;
ulong start, end, dst;
bool ret = FALSE;
/* get index of the current core */
idx = sb_coreidx(sbh);
/* switch to extif or chipc core */
if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
pll_type = PLL_TYPE1;
clockcontrol_n = &eir->clockcontrol_n;
clockcontrol_sb = &eir->clockcontrol_sb;
clockcontrol_pci = &eir->clockcontrol_pci;
} else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK;
clockcontrol_n = &cc->clockcontrol_n;
clockcontrol_sb = &cc->clockcontrol_sb;
clockcontrol_pci = &cc->clockcontrol_pci;
} else
goto done;
/* Store the current clock register values */
orig_n = R_REG(clockcontrol_n);
orig_sb = R_REG(clockcontrol_sb);
orig_pci = R_REG(clockcontrol_pci);
if (pll_type == PLL_TYPE1) {
/* Keep the current PCI clock if not specified */
if (pciclock == 0) {
pciclock = sb_clock_rate(pll_type, R_REG(clockcontrol_n), R_REG(clockcontrol_pci));
pciclock = (pciclock <= 25000000) ? 25000000 : 33000000;
}
/* Search for the closest MIPS clock less than or equal to a preferred value */
for (i = 0; i < ARRAYSIZE(type1_table); i++) {
ASSERT(type1_table[i].mipsclock ==
sb_clock_rate(pll_type, type1_table[i].n, type1_table[i].sb));
if (type1_table[i].mipsclock > mipsclock)
break;
}
if (i == 0) {
ret = FALSE;
goto done;
} else {
ret = TRUE;
i--;
}
ASSERT(type1_table[i].mipsclock <= mipsclock);
/* No PLL change */
if ((orig_n == type1_table[i].n) &&
(orig_sb == type1_table[i].sb) &&
(orig_pci == type1_table[i].pci33))
goto done;
/* Set the PLL controls */
W_REG(clockcontrol_n, type1_table[i].n);
W_REG(clockcontrol_sb, type1_table[i].sb);
if (pciclock == 25000000)
W_REG(clockcontrol_pci, type1_table[i].pci25);
else
W_REG(clockcontrol_pci, type1_table[i].pci33);
/* Reset */
sb_watchdog(sbh, 1);
while (1);
} else if ((pll_type == PLL_TYPE2) || (pll_type == PLL_TYPE4)) {
n4m_table_t *table = (pll_type == PLL_TYPE2) ? type2_table : type4_table;
uint tabsz = (pll_type == PLL_TYPE2) ? ARRAYSIZE(type2_table) : ARRAYSIZE(type4_table);
ASSERT(cc);
/* Store the current clock register values */
orig_m2 = R_REG(&cc->clockcontrol_m2);
orig_mips = R_REG(&cc->clockcontrol_mips);
orig_ratio_parm = 0;
/* Look up current ratio */
for (i = 0; i < tabsz; i++) {
if ((orig_n == table[i].n) &&
(orig_sb == table[i].sb) &&
(orig_pci == table[i].pci33) &&
(orig_m2 == table[i].m2) &&
(orig_mips == table[i].m3)) {
orig_ratio_parm = table[i].ratio_parm;
break;
}
}
/* Search for the closest MIPS clock greater or equal to a preferred value */
for (i = 0; i < tabsz; i++) {
ASSERT(table[i].mipsclock ==
sb_clock_rate(pll_type, table[i].n, table[i].m3));
if ((mipsclock <= table[i].mipsclock) &&
((sbclock == 0) || (sbclock <= table[i].sbclock)))
break;
}
if (i == tabsz) {
ret = FALSE;
goto done;
} else {
ret = TRUE;
}
/* No PLL change */
if ((orig_n == table[i].n) &&
(orig_sb == table[i].sb) &&
(orig_pci == table[i].pci33) &&
(orig_m2 == table[i].m2) &&
(orig_mips == table[i].m3))
goto done;
/* Set the PLL controls */
W_REG(clockcontrol_n, table[i].n);
W_REG(clockcontrol_sb, table[i].sb);
W_REG(clockcontrol_pci, table[i].pci33);
W_REG(&cc->clockcontrol_m2, table[i].m2);
W_REG(&cc->clockcontrol_mips, table[i].m3);
/* No ratio change */
if (orig_ratio_parm == table[i].ratio_parm)
goto end_fill;
new_ratio = table[i].ratio_parm;
icache_probe(&icache_size, &ic_lsize);
/* Preload the code into the cache */
start = ((ulong) &&start_fill) & ~(ic_lsize - 1);
end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1);
while (start < end) {
cache_unroll(start, Fill_I);
start += ic_lsize;
}
/* Copy the handler */
start = (ulong) &handler;
end = (ulong) &afterhandler;
dst = KSEG1ADDR(0x180);
for (i = 0; i < (end - start); i += 4)
*((ulong *)(dst + i)) = *((ulong *)(start + i));
/* Preload handler into the cache one line at a time */
for (i = 0; i < (end - start); i += 4)
cache_unroll(dst + i, Fill_I);
/* Clear BEV bit */
MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~ST0_BEV);
/* Enable interrupts */
MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) | (ALLINTS | ST0_IE));
/* Enable MIPS timer interrupt */
if (!(mipsr = sb_setcore(sbh, SB_MIPS, 0)) &&
!(mipsr = sb_setcore(sbh, SB_MIPS33, 0)))
ASSERT(mipsr);
W_REG(&mipsr->intmask, 1);
start_fill:
/* step 1, set clock ratios */
MTC0(C0_BROADCOM, 3, new_ratio);
MTC0(C0_BROADCOM, 1, 8);
/* step 2: program timer intr */
W_REG(&mipsr->timer, 100);
(void) R_REG(&mipsr->timer);
/* step 3, switch to async */
sync_mode = MFC0(C0_BROADCOM, 4);
MTC0(C0_BROADCOM, 4, 1 << 22);
/* step 4, set cfg active */
MTC0(C0_BROADCOM, 2, 0x9);
/* steps 5 & 6 */
__asm__ __volatile__ (
".set\tmips3\n\t"
"wait\n\t"
".set\tmips0"
);
/* step 7, clear cfg_active */
MTC0(C0_BROADCOM, 2, 0);
/* Additional Step: set back to orig sync mode */
MTC0(C0_BROADCOM, 4, sync_mode);
/* step 8, fake soft reset */
MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | 4);
end_fill:
/* step 9 set watchdog timer */
sb_watchdog(sbh, 20);
(void) R_REG(&cc->chipid);
/* step 11 */
__asm__ __volatile__ (
".set\tmips3\n\t"
"sync\n\t"
"wait\n\t"
".set\tmips0"
);
while (1);
}
done:
/* switch back to previous core */
sb_setcoreidx(sbh, idx);
return ret;
}
/* returns the ncdl value to be programmed into sdram_ncdl for calibration */
uint32
sb_memc_get_ncdl(void *sbh)
{
sbmemcregs_t *memc;
uint32 ret = 0;
uint32 config, rd, wr, misc, dqsg, cd, sm, sd;
uint idx, rev;
idx = sb_coreidx(sbh);
memc = (sbmemcregs_t *)sb_setcore(sbh, SB_MEMC, 0);
if (memc == 0)
goto out;
rev = sb_corerev(sbh);
config = R_REG(&memc->config);
wr = R_REG(&memc->wrncdlcor);
rd = R_REG(&memc->rdncdlcor);
misc = R_REG(&memc->miscdlyctl);
dqsg = R_REG(&memc->dqsgatencdl);
rd &= MEMC_RDNCDLCOR_RD_MASK;
wr &= MEMC_WRNCDLCOR_WR_MASK;
dqsg &= MEMC_DQSGATENCDL_G_MASK;
if (config & MEMC_CONFIG_DDR) {
ret = (wr << 16) | (rd << 8) | dqsg;
} else {
if (rev > 0)
cd = rd;
else
cd = (rd == MEMC_CD_THRESHOLD) ? rd : (wr + MEMC_CD_THRESHOLD);
sm = (misc & MEMC_MISC_SM_MASK) >> MEMC_MISC_SM_SHIFT;
sd = (misc & MEMC_MISC_SD_MASK) >> MEMC_MISC_SD_SHIFT;
ret = (sm << 16) | (sd << 8) | cd;
}
out:
/* switch back to previous core */
sb_setcoreidx(sbh, idx);
return ret;
}

View File

@ -1,557 +0,0 @@
/*
* Low-Level PCI and SB support for BCM47xx
*
* 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.
*
* $Id$
*/
#include <typedefs.h>
#include <pcicfg.h>
#include <bcmdevs.h>
#include <sbconfig.h>
#include <sbpci.h>
#include <osl.h>
#include <bcmendian.h>
#include <bcmutils.h>
#include <sbutils.h>
#include <bcmnvram.h>
#include <hndmips.h>
/* Can free sbpci_init() memory after boot */
#ifndef linux
#define __init
#endif
/* Emulated configuration space */
static pci_config_regs sb_config_regs[SB_MAXCORES];
/* Banned cores */
static uint16 pci_ban[32] = { 0 };
static uint pci_banned = 0;
/* CardBus mode */
static bool cardbus = FALSE;
/* Disable PCI host core */
static bool pci_disabled = FALSE;
/*
* Functions for accessing external PCI configuration space
*/
/* Assume one-hot slot wiring */
#define PCI_SLOT_MAX 16
static uint32
config_cmd(void *sbh, uint bus, uint dev, uint func, uint off)
{
uint coreidx;
sbpciregs_t *regs;
uint32 addr = 0;
/* CardBusMode supports only one device */
if (cardbus && dev > 1)
return 0;
coreidx = sb_coreidx(sbh);
regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0);
/* Type 0 transaction */
if (bus == 1) {
/* Skip unwired slots */
if (dev < PCI_SLOT_MAX) {
/* Slide the PCI window to the appropriate slot */
W_REG(&regs->sbtopci1, SBTOPCI_CFG0 | ((1 << (dev + 16)) & SBTOPCI1_MASK));
addr = SB_PCI_CFG | ((1 << (dev + 16)) & ~SBTOPCI1_MASK) |
(func << 8) | (off & ~3);
}
}
/* Type 1 transaction */
else {
W_REG(&regs->sbtopci1, SBTOPCI_CFG1);
addr = SB_PCI_CFG | (bus << 16) | (dev << 11) | (func << 8) | (off & ~3);
}
sb_setcoreidx(sbh, coreidx);
return addr;
}
static int
extpci_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
uint32 addr, *reg = NULL, val;
int ret = 0;
if (pci_disabled ||
!(addr = config_cmd(sbh, bus, dev, func, off)) ||
!(reg = (uint32 *) REG_MAP(addr, len)) ||
BUSPROBE(val, reg))
val = 0xffffffff;
val >>= 8 * (off & 3);
if (len == 4)
*((uint32 *) buf) = val;
else if (len == 2)
*((uint16 *) buf) = (uint16) val;
else if (len == 1)
*((uint8 *) buf) = (uint8) val;
else
ret = -1;
if (reg)
REG_UNMAP(reg);
return ret;
}
static int
extpci_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
uint32 addr, *reg = NULL, val;
int ret = 0;
if (pci_disabled ||
!(addr = config_cmd(sbh, bus, dev, func, off)) ||
!(reg = (uint32 *) REG_MAP(addr, len)) ||
BUSPROBE(val, reg))
goto done;
if (len == 4)
val = *((uint32 *) buf);
else if (len == 2) {
val &= ~(0xffff << (8 * (off & 3)));
val |= *((uint16 *) buf) << (8 * (off & 3));
} else if (len == 1) {
val &= ~(0xff << (8 * (off & 3)));
val |= *((uint8 *) buf) << (8 * (off & 3));
} else
ret = -1;
W_REG(reg, val);
done:
if (reg)
REG_UNMAP(reg);
return ret;
}
/*
* Functions for accessing translated SB configuration space
*/
static int
sb_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
pci_config_regs *cfg;
if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs))
return -1;
cfg = &sb_config_regs[dev];
ASSERT(ISALIGNED(off, len));
ASSERT(ISALIGNED(buf, len));
if (len == 4)
*((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off)));
else if (len == 2)
*((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off)));
else if (len == 1)
*((uint8 *) buf) = *((uint8 *)((ulong) cfg + off));
else
return -1;
return 0;
}
static int
sb_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
uint coreidx, n;
void *regs;
sbconfig_t *sb;
pci_config_regs *cfg;
if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs))
return -1;
cfg = &sb_config_regs[dev];
ASSERT(ISALIGNED(off, len));
ASSERT(ISALIGNED(buf, len));
/* Emulate BAR sizing */
if (off >= OFFSETOF(pci_config_regs, base[0]) && off <= OFFSETOF(pci_config_regs, base[3]) &&
len == 4 && *((uint32 *) buf) == ~0) {
coreidx = sb_coreidx(sbh);
if ((regs = sb_setcoreidx(sbh, dev))) {
sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
/* Highest numbered address match register */
n = (R_REG(&sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT;
if (off == OFFSETOF(pci_config_regs, base[0]))
cfg->base[0] = ~(sb_size(R_REG(&sb->sbadmatch0)) - 1);
else if (off == OFFSETOF(pci_config_regs, base[1]) && n >= 1)
cfg->base[1] = ~(sb_size(R_REG(&sb->sbadmatch1)) - 1);
else if (off == OFFSETOF(pci_config_regs, base[2]) && n >= 2)
cfg->base[2] = ~(sb_size(R_REG(&sb->sbadmatch2)) - 1);
else if (off == OFFSETOF(pci_config_regs, base[3]) && n >= 3)
cfg->base[3] = ~(sb_size(R_REG(&sb->sbadmatch3)) - 1);
}
sb_setcoreidx(sbh, coreidx);
return 0;
}
if (len == 4)
*((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf));
else if (len == 2)
*((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf));
else if (len == 1)
*((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf);
else
return -1;
return 0;
}
int
sbpci_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
if (bus == 0)
return sb_read_config(sbh, bus, dev, func, off, buf, len);
else
return extpci_read_config(sbh, bus, dev, func, off, buf, len);
}
int
sbpci_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
{
if (bus == 0)
return sb_write_config(sbh, bus, dev, func, off, buf, len);
else
return extpci_write_config(sbh, bus, dev, func, off, buf, len);
}
void
sbpci_ban(uint16 core)
{
if (pci_banned < ARRAYSIZE(pci_ban))
pci_ban[pci_banned++] = core;
}
int __init
sbpci_init(void *sbh)
{
uint chip, chiprev, chippkg, coreidx, host, i;
uint32 boardflags;
sbpciregs_t *pci;
sbconfig_t *sb;
pci_config_regs *cfg;
void *regs;
char varname[8];
uint wlidx = 0;
uint16 vendor, core;
uint8 class, subclass, progif;
uint32 val;
uint32 sbips_int_mask[] = { 0, SBIPS_INT1_MASK, SBIPS_INT2_MASK, SBIPS_INT3_MASK, SBIPS_INT4_MASK };
uint32 sbips_int_shift[] = { 0, 0, SBIPS_INT2_SHIFT, SBIPS_INT3_SHIFT, SBIPS_INT4_SHIFT };
chip = sb_chip(sbh);
chiprev = sb_chiprev(sbh);
chippkg = sb_chippkg(sbh);
coreidx = sb_coreidx(sbh);
if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0)))
return -1;
sb_core_reset(sbh, 0);
boardflags = (uint32) getintvar(NULL, "boardflags");
if ((chip == BCM4310_DEVICE_ID) && (chiprev == 0))
pci_disabled = TRUE;
/*
* The 200-pin BCM4712 package does not bond out PCI. Even when
* PCI is bonded out, some boards may leave the pins
* floating.
*/
if (((chip == BCM4712_DEVICE_ID) &&
((chippkg == BCM4712SMALL_PKG_ID) ||
(chippkg == BCM4712MID_PKG_ID))) ||
(boardflags & BFL_NOPCI))
pci_disabled = TRUE;
/*
* If the PCI core should not be touched (disabled, not bonded
* out, or pins floating), do not even attempt to access core
* registers. Otherwise, try to determine if it is in host
* mode.
*/
if (pci_disabled)
host = 0;
else
host = !BUSPROBE(val, &pci->control);
if (!host) {
/* Disable PCI interrupts in client mode */
sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF);
W_REG(&sb->sbintvec, 0);
/* Disable the PCI bridge in client mode */
sbpci_ban(SB_PCI);
printf("PCI: Disabled\n");
} else {
/* Reset the external PCI bus and enable the clock */
W_REG(&pci->control, 0x5); /* enable the tristate drivers */
W_REG(&pci->control, 0xd); /* enable the PCI clock */
OSL_DELAY(150); /* delay > 100 us */
W_REG(&pci->control, 0xf); /* deassert PCI reset */
W_REG(&pci->arbcontrol, PCI_INT_ARB); /* use internal arbiter */
OSL_DELAY(1); /* delay 1 us */
/* Enable CardBusMode */
cardbus = nvram_match("cardbus", "1");
if (cardbus) {
printf("PCI: Enabling CardBus\n");
/* GPIO 1 resets the CardBus device on bcm94710ap */
sb_gpioout(sbh, 1, 1);
sb_gpioouten(sbh, 1, 1);
W_REG(&pci->sprom[0], R_REG(&pci->sprom[0]) | 0x400);
}
/* 64 MB I/O access window */
W_REG(&pci->sbtopci0, SBTOPCI_IO);
/* 64 MB configuration access window */
W_REG(&pci->sbtopci1, SBTOPCI_CFG0);
/* 1 GB memory access window */
W_REG(&pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA);
/* Enable PCI bridge BAR0 prefetch and burst */
val = 6;
sbpci_write_config(sbh, 1, 0, 0, PCI_CFG_CMD, &val, sizeof(val));
/* Enable PCI interrupts */
W_REG(&pci->intmask, PCI_INTA);
}
/* Scan the SB bus */
bzero(sb_config_regs, sizeof(sb_config_regs));
for (cfg = sb_config_regs; cfg < &sb_config_regs[SB_MAXCORES]; cfg++) {
cfg->vendor = 0xffff;
if (!(regs = sb_setcoreidx(sbh, cfg - sb_config_regs)))
continue;
sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
/* Read ID register and parse vendor and core */
val = R_REG(&sb->sbidhigh);
vendor = (val & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT;
core = (val & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT;
progif = 0;
/* Check if this core is banned */
for (i = 0; i < pci_banned; i++)
if (core == pci_ban[i])
break;
if (i < pci_banned)
continue;
/* Known vendor translations */
switch (vendor) {
case SB_VEND_BCM:
vendor = VENDOR_BROADCOM;
break;
}
/* Determine class based on known core codes */
switch (core) {
case SB_ILINE20:
class = PCI_CLASS_NET;
subclass = PCI_NET_ETHER;
core = BCM47XX_ILINE_ID;
break;
case SB_ILINE100:
class = PCI_CLASS_NET;
subclass = PCI_NET_ETHER;
core = BCM4610_ILINE_ID;
break;
case SB_ENET:
class = PCI_CLASS_NET;
subclass = PCI_NET_ETHER;
core = BCM47XX_ENET_ID;
break;
case SB_SDRAM:
case SB_MEMC:
class = PCI_CLASS_MEMORY;
subclass = PCI_MEMORY_RAM;
break;
case SB_PCI:
class = PCI_CLASS_BRIDGE;
subclass = PCI_BRIDGE_PCI;
break;
case SB_MIPS:
case SB_MIPS33:
class = PCI_CLASS_CPU;
subclass = PCI_CPU_MIPS;
break;
case SB_CODEC:
class = PCI_CLASS_COMM;
subclass = PCI_COMM_MODEM;
core = BCM47XX_V90_ID;
break;
case SB_USB:
class = PCI_CLASS_SERIAL;
subclass = PCI_SERIAL_USB;
progif = 0x10; /* OHCI */
core = BCM47XX_USB_ID;
break;
case SB_USB11H:
class = PCI_CLASS_SERIAL;
subclass = PCI_SERIAL_USB;
progif = 0x10; /* OHCI */
core = BCM47XX_USBH_ID;
break;
case SB_USB11D:
class = PCI_CLASS_SERIAL;
subclass = PCI_SERIAL_USB;
core = BCM47XX_USBD_ID;
break;
case SB_IPSEC:
class = PCI_CLASS_CRYPT;
subclass = PCI_CRYPT_NETWORK;
core = BCM47XX_IPSEC_ID;
break;
case SB_EXTIF:
case SB_CC:
class = PCI_CLASS_MEMORY;
subclass = PCI_MEMORY_FLASH;
break;
case SB_D11:
class = PCI_CLASS_NET;
subclass = PCI_NET_OTHER;
/* Let an nvram variable override this */
sprintf(varname, "wl%did", wlidx);
wlidx++;
if ((core = getintvar(NULL, varname)) == 0) {
if (chip == BCM4712_DEVICE_ID) {
if (chippkg == BCM4712SMALL_PKG_ID)
core = BCM4306_D11G_ID;
else
core = BCM4306_D11DUAL_ID;
} else {
/* 4310 */
core = BCM4310_D11B_ID;
}
}
break;
default:
class = subclass = progif = 0xff;
break;
}
/* Supported translations */
cfg->vendor = htol16(vendor);
cfg->device = htol16(core);
cfg->rev_id = chiprev;
cfg->prog_if = progif;
cfg->sub_class = subclass;
cfg->base_class = class;
cfg->base[0] = htol32(sb_base(R_REG(&sb->sbadmatch0)));
cfg->base[1] = htol32(sb_base(R_REG(&sb->sbadmatch1)));
cfg->base[2] = htol32(sb_base(R_REG(&sb->sbadmatch2)));
cfg->base[3] = htol32(sb_base(R_REG(&sb->sbadmatch3)));
cfg->base[4] = 0;
cfg->base[5] = 0;
if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI)
cfg->header_type = PCI_HEADER_BRIDGE;
else
cfg->header_type = PCI_HEADER_NORMAL;
/* Save core interrupt flag */
cfg->int_pin = R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK;
/* Default to MIPS shared interrupt 0 */
cfg->int_line = 0;
/* MIPS sbipsflag maps core interrupt flags to interrupts 1 through 4 */
if ((regs = sb_setcore(sbh, SB_MIPS, 0)) ||
(regs = sb_setcore(sbh, SB_MIPS33, 0))) {
sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF);
val = R_REG(&sb->sbipsflag);
for (cfg->int_line = 1; cfg->int_line <= 4; cfg->int_line++) {
if (((val & sbips_int_mask[cfg->int_line]) >> sbips_int_shift[cfg->int_line]) == cfg->int_pin)
break;
}
if (cfg->int_line > 4)
cfg->int_line = 0;
}
/* Emulated core */
*((uint32 *) &cfg->sprom_control) = 0xffffffff;
}
sb_setcoreidx(sbh, coreidx);
return 0;
}
void
sbpci_check(void *sbh)
{
uint coreidx;
sbpciregs_t *pci;
uint32 sbtopci1;
uint32 buf[64], *ptr, i;
ulong pa;
volatile uint j;
coreidx = sb_coreidx(sbh);
pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0);
/* Clear the test array */
pa = (ulong) DMA_MAP(NULL, buf, sizeof(buf), DMA_RX, NULL);
ptr = (uint32 *) OSL_UNCACHED(&buf[0]);
memset(ptr, 0, sizeof(buf));
/* Point PCI window 1 to memory */
sbtopci1 = R_REG(&pci->sbtopci1);
W_REG(&pci->sbtopci1, SBTOPCI_MEM | (pa & SBTOPCI1_MASK));
/* Fill the test array via PCI window 1 */
ptr = (uint32 *) REG_MAP(SB_PCI_CFG + (pa & ~SBTOPCI1_MASK), sizeof(buf));
for (i = 0; i < ARRAYSIZE(buf); i++) {
for (j = 0; j < 2; j++);
W_REG(&ptr[i], i);
}
REG_UNMAP(ptr);
/* Restore PCI window 1 */
W_REG(&pci->sbtopci1, sbtopci1);
/* Check the test array */
DMA_UNMAP(NULL, pa, sizeof(buf), DMA_RX, NULL);
ptr = (uint32 *) OSL_UNCACHED(&buf[0]);
for (i = 0; i < ARRAYSIZE(buf); i++) {
if (ptr[i] != i)
break;
}
/* Change the clock if the test fails */
if (i < ARRAYSIZE(buf)) {
uint32 req, cur;
cur = sb_clock(sbh);
printf("PCI: Test failed at %d MHz\n", (cur + 500000) / 1000000);
for (req = 104000000; req < 176000000; req += 4000000) {
printf("PCI: Resetting to %d MHz\n", (req + 500000) / 1000000);
/* This will only reset if the clocks are valid and have changed */
sb_mips_setclock(sbh, req, 0, 0);
}
/* Should not reach here */
ASSERT(0);
}
sb_setcoreidx(sbh, coreidx);
}

View File

@ -1,252 +0,0 @@
/*
* Generic setup routines for Broadcom MIPS boards
*
* 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.
*
* $Id$
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/serialP.h>
#include <linux/ide.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <asm/reboot.h>
#ifdef CONFIG_MTD_PARTITIONS
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#endif
#include <typedefs.h>
#include <bcmutils.h>
#include <bcmnvram.h>
#include <sbmips.h>
#include <sbutils.h>
#include <trxhdr.h>
extern void bcm947xx_time_init(void);
extern void bcm947xx_timer_setup(struct irqaction *irq);
#ifdef CONFIG_REMOTE_DEBUG
extern void set_debug_traps(void);
extern void rs_kgdb_hook(struct serial_state *);
extern void breakpoint(void);
#endif
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
extern struct ide_ops std_ide_ops;
#endif
/* Global SB handle */
void *bcm947xx_sbh = NULL;
spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED;
EXPORT_SYMBOL(bcm947xx_sbh);
EXPORT_SYMBOL(bcm947xx_sbh_lock);
/* Convenience */
#define sbh bcm947xx_sbh
#define sbh_lock bcm947xx_sbh_lock
/* Kernel command line */
char arcs_cmdline[CL_SIZE] __initdata = CONFIG_CMDLINE;
void
bcm947xx_machine_restart(char *command)
{
printk("Please stand by while rebooting the system...\n");
/* Set the watchdog timer to reset immediately */
__cli();
sb_watchdog(sbh, 1);
while (1);
}
void
bcm947xx_machine_halt(void)
{
printk("System halted\n");
/* Disable interrupts and watchdog and spin forever */
__cli();
sb_watchdog(sbh, 0);
while (1);
}
#ifdef CONFIG_SERIAL
static struct serial_struct rs = {
line: 0,
flags: ASYNC_BOOT_AUTOCONF,
io_type: SERIAL_IO_MEM,
};
static void __init
serial_add(void *regs, uint irq, uint baud_base, uint reg_shift)
{
rs.iomem_base = regs;
rs.irq = irq + 2;
rs.baud_base = baud_base / 16;
rs.iomem_reg_shift = reg_shift;
early_serial_setup(&rs);
rs.line++;
}
static void __init
serial_setup(void *sbh)
{
sb_serial_init(sbh, serial_add);
#ifdef CONFIG_REMOTE_DEBUG
/* Use the last port for kernel debugging */
if (rs.iomem_base)
rs_kgdb_hook(&rs);
#endif
}
#endif /* CONFIG_SERIAL */
void __init
brcm_setup(void)
{
char *value;
/* Get global SB handle */
sbh = sb_kattach();
/* Initialize clocks and interrupts */
sb_mips_init(sbh);
#ifdef CONFIG_SERIAL
/* Initialize UARTs */
serial_setup(sbh);
#endif
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
ide_ops = &std_ide_ops;
#endif
/* Override default command line arguments */
value = nvram_get("kernel_args");
if (value && strlen(value) && strncmp(value, "empty", 5))
strncpy(arcs_cmdline, value, sizeof(arcs_cmdline));
/* Generic setup */
_machine_restart = bcm947xx_machine_restart;
_machine_halt = bcm947xx_machine_halt;
_machine_power_off = bcm947xx_machine_halt;
board_time_init = bcm947xx_time_init;
board_timer_setup = bcm947xx_timer_setup;
}
const char *
get_system_type(void)
{
return "Broadcom BCM947XX";
}
void __init
bus_error_init(void)
{
}
#ifdef CONFIG_MTD_PARTITIONS
static struct mtd_partition bcm947xx_parts[] = {
{ name: "pmon", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, },
{ name: "linux", offset: 0, size: 0, },
{ name: "rootfs", offset: 0, size: 0, },
{ name: "nvram", offset: 0, size: 0, },
{ name: "OpenWrt", offset: 0, size: 0, },
{ name: NULL, },
};
static int __init
find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
{
struct trx_header *trx;
unsigned char buf[512];
int off;
size_t len;
trx = (struct trx_header *) buf;
for (off = (256*1024); off < size; off += mtd->erasesize) {
memset(buf, 0xe5, sizeof(buf));
/*
* Read into buffer
*/
if (MTD_READ(mtd, off, sizeof(buf), &len, buf) ||
len != sizeof(buf))
continue;
/* found a TRX header */
if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
part->offset = le32_to_cpu(trx->offsets[2]) ? :
le32_to_cpu(trx->offsets[1]);
part->size = le32_to_cpu(trx->len);
part->size -= part->offset;
part->offset += off;
goto done;
}
}
printk(KERN_NOTICE
"%s: Couldn't find root filesystem\n",
mtd->name);
return -1;
done:
return part->size;
}
struct mtd_partition * __init
init_mtd_partitions(struct mtd_info *mtd, size_t size)
{
/* boot loader */
bcm947xx_parts[0].offset=0;
bcm947xx_parts[0].size=256*1024;
/* nvram */
bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
bcm947xx_parts[3].size = size - bcm947xx_parts[3].offset;
/* Size linux (kernel and rootfs) */
bcm947xx_parts[1].offset = bcm947xx_parts[0].size;
bcm947xx_parts[1].size = bcm947xx_parts[3].offset - bcm947xx_parts[1].offset;
/* Find and size rootfs */
if (find_root(mtd,size,&bcm947xx_parts[2])==0) {
/* entirely jffs2 */
bcm947xx_parts[2].size = bcm947xx_parts[3].offset - bcm947xx_parts[2].offset;
bcm947xx_parts[4].name = NULL;
} else {
/* legacy setup */
/* calculate leftover flash, and assign it to the jffs2 partition */
bcm947xx_parts[4].offset = bcm947xx_parts[2].offset + bcm947xx_parts[2].size;
bcm947xx_parts[4].offset = ROUNDUP(bcm947xx_parts[4].offset, mtd->erasesize);
bcm947xx_parts[4].size = bcm947xx_parts[3].offset - bcm947xx_parts[4].offset;
}
return bcm947xx_parts;
}
EXPORT_SYMBOL(init_mtd_partitions);
#endif

View File

@ -1,346 +0,0 @@
/*
* Broadcom SiliconBackplane chipcommon serial flash interface
*
* 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.
*
* $Id$
*/
#include <typedefs.h>
#include <bcmutils.h>
#include <osl.h>
#include <sbchipc.h>
#include <sflash.h>
/* Private global state */
static struct sflash sflash;
/* Issue a serial flash command */
static INLINE void
sflash_cmd(chipcregs_t *cc, uint opcode)
{
W_REG(&cc->flashcontrol, SFLASH_START | opcode);
while (R_REG(&cc->flashcontrol) & SFLASH_BUSY);
}
/* Initialize serial flash access */
struct sflash *
sflash_init(chipcregs_t *cc)
{
uint32 id, id2;
bzero(&sflash, sizeof(sflash));
sflash.type = R_REG(&cc->capabilities) & CAP_FLASH_MASK;
switch (sflash.type) {
case SFLASH_ST:
/* Probe for ST chips */
sflash_cmd(cc, SFLASH_ST_DP);
sflash_cmd(cc, SFLASH_ST_RES);
id = R_REG(&cc->flashdata);
switch (id) {
case 0x11:
/* ST M25P20 2 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 4;
break;
case 0x12:
/* ST M25P40 4 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 8;
break;
case 0x13:
/* ST M25P80 8 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 16;
break;
case 0x14:
/* ST M25P16 16 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 32;
break;
case 0xbf:
W_REG(&cc->flashaddress, 1);
sflash_cmd(cc, SFLASH_ST_RES);
id2 = R_REG(&cc->flashdata);
if (id2 == 0x44) {
/* SST M25VF80 4 Mbit Serial Flash */
sflash.blocksize = 64 * 1024;
sflash.numblocks = 8;
}
break;
}
break;
case SFLASH_AT:
/* Probe for Atmel chips */
sflash_cmd(cc, SFLASH_AT_STATUS);
id = R_REG(&cc->flashdata) & 0x3c;
switch (id) {
case 0x2c:
/* Atmel AT45DB161 16Mbit Serial Flash */
sflash.blocksize = 512;
sflash.numblocks = 4096;
break;
case 0x34:
/* Atmel AT45DB321 32Mbit Serial Flash */
sflash.blocksize = 512;
sflash.numblocks = 8192;
break;
case 0x3c:
/* Atmel AT45DB642 64Mbit Serial Flash */
sflash.blocksize = 1024;
sflash.numblocks = 8192;
break;
}
break;
}
sflash.size = sflash.blocksize * sflash.numblocks;
return sflash.size ? &sflash : NULL;
}
/* Read len bytes starting at offset into buf. Returns number of bytes read. */
int
sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf)
{
int cnt;
uint32 *from, *to;
if (!len)
return 0;
if ((offset + len) > sflash.size)
return -22;
if ((len >= 4) && (offset & 3))
cnt = 4 - (offset & 3);
else if ((len >= 4) && ((uint32)buf & 3))
cnt = 4 - ((uint32)buf & 3);
else
cnt = len;
from = (uint32 *)(CC_FLASH_BASE + offset);
to = (uint32 *)buf;
if (cnt < 4) {
bcopy(from, to, cnt);
return cnt;
}
while (cnt >= 4) {
*to++ = *from++;
cnt -= 4;
}
return (len - cnt);
}
/* Poll for command completion. Returns zero when complete. */
int
sflash_poll(chipcregs_t *cc, uint offset)
{
if (offset >= sflash.size)
return -22;
switch (sflash.type) {
case SFLASH_ST:
/* Check for ST Write In Progress bit */
sflash_cmd(cc, SFLASH_ST_RDSR);
return R_REG(&cc->flashdata) & SFLASH_ST_WIP;
case SFLASH_AT:
/* Check for Atmel Ready bit */
sflash_cmd(cc, SFLASH_AT_STATUS);
return !(R_REG(&cc->flashdata) & SFLASH_AT_READY);
}
return 0;
}
/* Write len bytes starting at offset into buf. Returns number of bytes
* written. Caller should poll for completion.
*/
int
sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf)
{
struct sflash *sfl;
int ret = 0;
uint32 page, byte, mask;
if (!len)
return 0;
if ((offset + len) > sflash.size)
return -22;
sfl = &sflash;
switch (sfl->type) {
case SFLASH_ST:
ret = 1;
/* Enable writes */
sflash_cmd(cc, SFLASH_ST_WREN);
W_REG(&cc->flashaddress, offset);
W_REG(&cc->flashdata, *buf);
/* Page program */
sflash_cmd(cc, SFLASH_ST_PP);
break;
case SFLASH_AT:
mask = sfl->blocksize - 1;
page = (offset & ~mask) << 1;
byte = offset & mask;
/* Read main memory page into buffer 1 */
if (byte || len < sfl->blocksize) {
W_REG(&cc->flashaddress, page);
sflash_cmd(cc, SFLASH_AT_BUF1_LOAD);
/* 250 us for AT45DB321B */
SPINWAIT(sflash_poll(cc, offset), 1000);
ASSERT(!sflash_poll(cc, offset));
}
/* Write into buffer 1 */
for (ret = 0; ret < len && byte < sfl->blocksize; ret++) {
W_REG(&cc->flashaddress, byte++);
W_REG(&cc->flashdata, *buf++);
sflash_cmd(cc, SFLASH_AT_BUF1_WRITE);
}
/* Write buffer 1 into main memory page */
W_REG(&cc->flashaddress, page);
sflash_cmd(cc, SFLASH_AT_BUF1_PROGRAM);
break;
}
return ret;
}
/* Erase a region. Returns number of bytes scheduled for erasure.
* Caller should poll for completion.
*/
int
sflash_erase(chipcregs_t *cc, uint offset)
{
struct sflash *sfl;
if (offset >= sflash.size)
return -22;
sfl = &sflash;
switch (sfl->type) {
case SFLASH_ST:
sflash_cmd(cc, SFLASH_ST_WREN);
W_REG(&cc->flashaddress, offset);
sflash_cmd(cc, SFLASH_ST_SE);
return sfl->blocksize;
case SFLASH_AT:
W_REG(&cc->flashaddress, offset << 1);
sflash_cmd(cc, SFLASH_AT_PAGE_ERASE);
return sfl->blocksize;
}
return 0;
}
/*
* writes the appropriate range of flash, a NULL buf simply erases
* the region of flash
*/
int
sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf)
{
struct sflash *sfl;
uchar *block = NULL, *cur_ptr, *blk_ptr;
uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder;
uint blk_offset, blk_len, copied;
int bytes, ret = 0;
/* Check address range */
if (len <= 0)
return 0;
sfl = &sflash;
if ((offset + len) > sfl->size)
return -1;
blocksize = sfl->blocksize;
mask = blocksize - 1;
/* Allocate a block of mem */
if (!(block = MALLOC(blocksize)))
return -1;
while (len) {
/* Align offset */
cur_offset = offset & ~mask;
cur_length = blocksize;
cur_ptr = block;
remainder = blocksize - (offset & mask);
if (len < remainder)
cur_retlen = len;
else
cur_retlen = remainder;
/* buf == NULL means erase only */
if (buf) {
/* Copy existing data into holding block if necessary */
if ((offset & mask) || (len < blocksize)) {
blk_offset = cur_offset;
blk_len = cur_length;
blk_ptr = cur_ptr;
/* Copy entire block */
while(blk_len) {
copied = sflash_read(cc, blk_offset, blk_len, blk_ptr);
blk_offset += copied;
blk_len -= copied;
blk_ptr += copied;
}
}
/* Copy input data into holding block */
memcpy(cur_ptr + (offset & mask), buf, cur_retlen);
}
/* Erase block */
if ((ret = sflash_erase(cc, (uint) cur_offset)) < 0)
goto done;
while (sflash_poll(cc, (uint) cur_offset));
/* buf == NULL means erase only */
if (!buf) {
offset += cur_retlen;
len -= cur_retlen;
continue;
}
/* Write holding block */
while (cur_length > 0) {
if ((bytes = sflash_write(cc,
(uint) cur_offset,
(uint) cur_length,
(uchar *) cur_ptr)) < 0) {
ret = bytes;
goto done;
}
while (sflash_poll(cc, (uint) cur_offset));
cur_offset += bytes;
cur_length -= bytes;
cur_ptr += bytes;
}
offset += cur_retlen;
len -= cur_retlen;
buf += cur_retlen;
}
done:
if (block)
MFREE(block, blocksize);
return ret;
}

View File

@ -1,117 +0,0 @@
/*
* 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.
*
* $Id$
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/serial_reg.h>
#include <linux/interrupt.h>
#include <asm/addrspace.h>
#include <asm/io.h>
#include <asm/time.h>
#include <typedefs.h>
#include <bcmnvram.h>
#include <sbconfig.h>
#include <sbextif.h>
#include <sbutils.h>
#include <sbmips.h>
/* Global SB handle */
extern void *bcm947xx_sbh;
extern spinlock_t bcm947xx_sbh_lock;
/* Convenience */
#define sbh bcm947xx_sbh
#define sbh_lock bcm947xx_sbh_lock
extern int panic_timeout;
static int watchdog = 0;
static u8 *mcr = NULL;
void __init
bcm947xx_time_init(void)
{
unsigned int hz;
extifregs_t *eir;
/*
* Use deterministic values for initial counter interrupt
* so that calibrate delay avoids encountering a counter wrap.
*/
write_c0_count(0);
write_c0_compare(0xffff);
if (!(hz = sb_mips_clock(sbh)))
hz = 100000000;
printk("CPU: BCM%04x rev %d at %d MHz\n", sb_chip(sbh), sb_chiprev(sbh),
(hz + 500000) / 1000000);
/* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
mips_hpt_frequency = hz / 2;
/* Set watchdog interval in ms */
watchdog = simple_strtoul(nvram_safe_get("watchdog"), NULL, 0);
/* Please set the watchdog to 3 sec if it is less than 3 but not equal to 0 */
if (watchdog > 0) {
if (watchdog < 3000)
watchdog = 3000;
}
/* Set panic timeout in seconds */
panic_timeout = watchdog / 1000;
/* Setup blink */
if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) {
sbconfig_t *sb = (sbconfig_t *)((unsigned int) eir + SBCONFIGOFF);
unsigned long base = EXTIF_CFGIF_BASE(sb_base(readl(&sb->sbadmatch1)));
mcr = (u8 *) ioremap_nocache(base + UART_MCR, 1);
}
}
static void
bcm947xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
/* Generic MIPS timer code */
timer_interrupt(irq, dev_id, regs);
/* Set the watchdog timer to reset after the specified number of ms */
if (watchdog > 0)
sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog);
#ifdef CONFIG_HWSIM
(*((int *)0xa0000f1c))++;
#else
/* Blink one of the LEDs in the external UART */
if (mcr && !(jiffies % (HZ/2)))
writeb(readb(mcr) ^ UART_MCR_OUT2, mcr);
#endif
}
static struct irqaction bcm947xx_timer_irqaction = {
bcm947xx_timer_interrupt,
SA_INTERRUPT,
0,
"timer",
NULL,
NULL
};
void __init
bcm947xx_timer_setup(struct irqaction *irq)
{
/* Enable the timer interrupt */
setup_irq(7, &bcm947xx_timer_irqaction);
}

View File

@ -1,26 +0,0 @@
#
# Makefile for generic Broadcom MIPS boards
#
# 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.
#
# $Id$
#
.S.s:
$(CPP) $(AFLAGS) $< -o $*.s
.S.o:
$(CC) $(AFLAGS) -c $< -o $*.o
O_TARGET := brcm.o
obj-y := int-handler.o irq.o
obj-$(CONFIG_REMOTE_DEBUG) += gdb_hook.o
include $(TOPDIR)/Rules.make

View File

@ -1,120 +0,0 @@
/*
* 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.
*
* Carsten Langgaard, carstenl@mips.com
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
*
* ########################################################################
*
* This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as
* published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
* ########################################################################
*
* This is the interface to the remote debugger stub.
*
*/
#include <linux/serialP.h>
#include <linux/serial_reg.h>
#include <asm/serial.h>
#include <asm/io.h>
static struct async_struct kdb_port_info = {0};
static __inline__ unsigned int serial_in(struct async_struct *info, int offset)
{
return readb((unsigned long) info->iomem_base +
(offset<<info->iomem_reg_shift));
}
static __inline__ void serial_out(struct async_struct *info, int offset,
int value)
{
writeb(value, (unsigned long) info->iomem_base +
(offset<<info->iomem_reg_shift));
}
void rs_kgdb_hook(struct serial_state *ser) {
int t;
kdb_port_info.state = ser;
kdb_port_info.magic = SERIAL_MAGIC;
kdb_port_info.port = ser->port;
kdb_port_info.flags = ser->flags;
kdb_port_info.iomem_base = ser->iomem_base;
kdb_port_info.iomem_reg_shift = ser->iomem_reg_shift;
kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS;
/*
* Clear all interrupts
*/
serial_in(&kdb_port_info, UART_LSR);
serial_in(&kdb_port_info, UART_RX);
serial_in(&kdb_port_info, UART_IIR);
serial_in(&kdb_port_info, UART_MSR);
/*
* Now, initialize the UART
*/
serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */
serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR);
/*
* and set the speed of the serial port
* (currently hardwired to 115200 8N1
*/
/* baud rate is fixed to 115200 (is this sufficient?)*/
t = kdb_port_info.state->baud_base / 115200;
/* set DLAB */
serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB);
serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */
serial_out(&kdb_port_info, UART_DLM, t >> 8); /* MS of divisor */
/* reset DLAB */
serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8);
}
int putDebugChar(char c)
{
if (!kdb_port_info.state) { /* need to init device first */
return 0;
}
while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0)
;
serial_out(&kdb_port_info, UART_TX, c);
return 1;
}
char getDebugChar(void)
{
if (!kdb_port_info.state) { /* need to init device first */
return 0;
}
while (!(serial_in(&kdb_port_info, UART_LSR) & 1))
;
return(serial_in(&kdb_port_info, UART_RX));
}

View File

@ -1,51 +0,0 @@
/*
* Generic interrupt handler for Broadcom MIPS boards
*
* 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.
*
* $Id$
*/
#include <linux/config.h>
#include <asm/asm.h>
#include <asm/mipsregs.h>
#include <asm/regdef.h>
#include <asm/stackframe.h>
/*
* MIPS IRQ Source
* -------- ------
* 0 Software (ignored)
* 1 Software (ignored)
* 2 Combined hardware interrupt (hw0)
* 3 Hardware
* 4 Hardware
* 5 Hardware
* 6 Hardware
* 7 R4k timer
*/
.text
.set noreorder
.set noat
.align 5
NESTED(brcmIRQ, PT_SIZE, sp)
SAVE_ALL
CLI
.set at
.set noreorder
jal brcm_irq_dispatch
move a0, sp
j ret_from_irq
nop
END(brcmIRQ)

View File

@ -1,130 +0,0 @@
/*
* Generic interrupt control functions for Broadcom MIPS boards
*
* 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.
*
* $Id$
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/gdb-stub.h>
#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
extern asmlinkage void brcmIRQ(void);
extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
void
brcm_irq_dispatch(struct pt_regs *regs)
{
u32 cause;
cause = read_c0_cause() &
read_c0_status() &
CAUSEF_IP;
#ifdef CONFIG_KERNPROF
change_c0_status(cause | 1, 1);
#else
clear_c0_status(cause);
#endif
if (cause & CAUSEF_IP7)
do_IRQ(7, regs);
if (cause & CAUSEF_IP2)
do_IRQ(2, regs);
if (cause & CAUSEF_IP3)
do_IRQ(3, regs);
if (cause & CAUSEF_IP4)
do_IRQ(4, regs);
if (cause & CAUSEF_IP5)
do_IRQ(5, regs);
if (cause & CAUSEF_IP6)
do_IRQ(6, regs);
}
static void
enable_brcm_irq(unsigned int irq)
{
if (irq < 8)
set_c0_status(1 << (irq + 8));
else
set_c0_status(IE_IRQ0);
}
static void
disable_brcm_irq(unsigned int irq)
{
if (irq < 8)
clear_c0_status(1 << (irq + 8));
else
clear_c0_status(IE_IRQ0);
}
static void
ack_brcm_irq(unsigned int irq)
{
/* Already done in brcm_irq_dispatch */
}
static unsigned int
startup_brcm_irq(unsigned int irq)
{
enable_brcm_irq(irq);
return 0; /* never anything pending */
}
static void
end_brcm_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_brcm_irq(irq);
}
static struct hw_interrupt_type brcm_irq_type = {
typename: "MIPS",
startup: startup_brcm_irq,
shutdown: disable_brcm_irq,
enable: enable_brcm_irq,
disable: disable_brcm_irq,
ack: ack_brcm_irq,
end: end_brcm_irq,
NULL
};
void __init
init_IRQ(void)
{
int i;
for (i = 0; i < NR_IRQS; i++) {
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = 0;
irq_desc[i].depth = 1;
irq_desc[i].handler = &brcm_irq_type;
}
set_except_vector(0, brcmIRQ);
change_c0_status(ST0_IM, ALLINTS);
#ifdef CONFIG_REMOTE_DEBUG
printk("Breaking into debugger...\n");
set_debug_traps();
breakpoint();
#endif
}

View File

@ -1,855 +0,0 @@
/*
* Common Flash Interface support:
* SST Standard Vendor Command Set (ID 0x0701)
*
* Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
*
* 2_by_8 routines added by Simon Munton
*
* This code is GPL
*
* $Id$
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/mtd/map.h>
#include <linux/mtd/cfi.h>
static int cfi_sststd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_sststd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
static int cfi_sststd_erase_onesize(struct mtd_info *, struct erase_info *);
static int cfi_sststd_erase_varsize(struct mtd_info *, struct erase_info *);
static void cfi_sststd_sync (struct mtd_info *);
static int cfi_sststd_suspend (struct mtd_info *);
static void cfi_sststd_resume (struct mtd_info *);
static void cfi_sststd_destroy(struct mtd_info *);
struct mtd_info *cfi_cmdset_0701(struct map_info *, int);
static struct mtd_info *cfi_sststd_setup (struct map_info *);
static struct mtd_chip_driver cfi_sststd_chipdrv = {
probe: NULL, /* Not usable directly */
destroy: cfi_sststd_destroy,
name: "cfi_cmdset_0701",
module: THIS_MODULE
};
struct mtd_info *cfi_cmdset_0701(struct map_info *map, int primary)
{
struct cfi_private *cfi = map->fldrv_priv;
int ofs_factor = cfi->interleave * cfi->device_type;
int i;
__u8 major, minor;
__u32 base = cfi->chips[0].start;
if (cfi->cfi_mode==1){
__u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
major = cfi_read_query(map, base + (adr+3)*ofs_factor);
minor = cfi_read_query(map, base + (adr+4)*ofs_factor);
printk(" SST Query Table v%c.%c at 0x%4.4X\n",
major, minor, adr);
cfi_send_gen_cmd(0xf0, 0x5555, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x90, 0x5555, base, map, cfi, cfi->device_type, NULL);
cfi->mfr = cfi_read_query(map, base);
cfi->id = cfi_read_query(map, base + ofs_factor);
cfi_send_gen_cmd(0xAA, 0x5555, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, 0x2AAA, base, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x98, 0x5555, base, map, cfi, cfi->device_type, NULL);
switch (cfi->device_type) {
case CFI_DEVICETYPE_X16:
cfi->addr_unlock1 = 0x5555;
cfi->addr_unlock2 = 0x2AAA;
break;
default:
printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0701 device type %d\n", cfi->device_type);
return NULL;
}
} /* CFI mode */
for (i=0; i< cfi->numchips; i++) {
cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
}
map->fldrv = &cfi_sststd_chipdrv;
MOD_INC_USE_COUNT;
cfi_send_gen_cmd(0xf0, 0x5555, base, map, cfi, cfi->device_type, NULL);
return cfi_sststd_setup(map);
}
static struct mtd_info *cfi_sststd_setup(struct map_info *map)
{
struct cfi_private *cfi = map->fldrv_priv;
struct mtd_info *mtd;
unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
printk("number of %s chips: %d\n", (cfi->cfi_mode)?"JEDEC":"CFI",cfi->numchips);
if (!mtd) {
printk("Failed to allocate memory for MTD device\n");
kfree(cfi->cmdset_priv);
return NULL;
}
memset(mtd, 0, sizeof(*mtd));
mtd->priv = map;
mtd->type = MTD_NORFLASH;
/* Also select the correct geometry setup too */
mtd->size = devsize * cfi->numchips;
if (cfi->cfiq->NumEraseRegions == 1) {
/* No need to muck about with multiple erase sizes */
mtd->erasesize = ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi->interleave;
} else {
unsigned long offset = 0;
int i,j;
mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL);
if (!mtd->eraseregions) {
printk("Failed to allocate memory for MTD erase region info\n");
kfree(cfi->cmdset_priv);
return NULL;
}
for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
unsigned long ernum, ersize;
ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
if (mtd->erasesize < ersize) {
mtd->erasesize = ersize;
}
for (j=0; j<cfi->numchips; j++) {
mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset = (j*devsize)+offset;
mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize;
mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum;
}
offset += (ersize * ernum);
}
// debug
for (i=0; i<mtd->numeraseregions;i++){
printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
i,mtd->eraseregions[i].offset,
mtd->eraseregions[i].erasesize,
mtd->eraseregions[i].numblocks);
}
}
switch (CFIDEV_BUSWIDTH)
{
case 1:
case 2:
case 4:
if (mtd->numeraseregions > 1)
mtd->erase = cfi_sststd_erase_varsize;
else
mtd->erase = cfi_sststd_erase_onesize;
mtd->read = cfi_sststd_read;
mtd->write = cfi_sststd_write;
break;
default:
printk("Unsupported buswidth\n");
kfree(mtd);
kfree(cfi->cmdset_priv);
return NULL;
break;
}
mtd->sync = cfi_sststd_sync;
mtd->suspend = cfi_sststd_suspend;
mtd->resume = cfi_sststd_resume;
mtd->flags = MTD_CAP_NORFLASH;
map->fldrv = &cfi_sststd_chipdrv;
mtd->name = map->name;
MOD_INC_USE_COUNT;
return mtd;
}
static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
{
DECLARE_WAITQUEUE(wait, current);
unsigned long timeo = jiffies + HZ;
retry:
cfi_spin_lock(chip->mutex);
if (chip->state != FL_READY){
printk("Waiting for chip to read, status = %d\n", chip->state);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
cfi_spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
timeo = jiffies + HZ;
goto retry;
}
adr += chip->start;
chip->state = FL_READY;
map->copy_from(map, buf, adr, len);
wake_up(&chip->wq);
cfi_spin_unlock(chip->mutex);
return 0;
}
static int cfi_sststd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
unsigned long ofs;
int chipnum;
int ret = 0;
/* ofs: offset within the first chip that the first read should start */
chipnum = (from >> cfi->chipshift);
ofs = from - (chipnum << cfi->chipshift);
*retlen = 0;
while (len) {
unsigned long thislen;
if (chipnum >= cfi->numchips)
break;
if ((len + ofs -1) >> cfi->chipshift)
thislen = (1<<cfi->chipshift) - ofs;
else
thislen = len;
ret = do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf);
if (ret)
break;
*retlen += thislen;
len -= thislen;
buf += thislen;
ofs = 0;
chipnum++;
}
return ret;
}
static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum, int fast)
{
unsigned long timeo = jiffies + HZ;
unsigned int Last[4];
unsigned long Count = 0;
struct cfi_private *cfi = map->fldrv_priv;
DECLARE_WAITQUEUE(wait, current);
int ret = 0;
retry:
cfi_spin_lock(chip->mutex);
if (chip->state != FL_READY){
printk("Waiting for chip to write, status = %d\n", chip->state);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
cfi_spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
printk("Wake up to write:\n");
timeo = jiffies + HZ;
goto retry;
}
chip->state = FL_WRITING;
adr += chip->start;
ENABLE_VPP(map);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
cfi_write(map, datum, adr);
cfi_spin_unlock(chip->mutex);
cfi_udelay(chip->word_write_time);
cfi_spin_lock(chip->mutex);
Last[0] = cfi_read(map, adr);
// printk("Last[0] is %x\n", Last[0]);
Last[1] = cfi_read(map, adr);
// printk("Last[1] is %x\n", Last[1]);
Last[2] = cfi_read(map, adr);
// printk("Last[2] is %x\n", Last[2]);
for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && Count < 10000; Count++){
cfi_spin_unlock(chip->mutex);
cfi_udelay(10);
cfi_spin_lock(chip->mutex);
Last[Count % 4] = cfi_read(map, adr);
// printk("Last[%d%%4] is %x\n", Count, Last[Count%4]);
}
if (Last[(Count - 1) % 4] != datum){
printk("Last[%ld] is %x, datum is %x\n",(Count - 1) % 4,Last[(Count - 1) % 4],datum);
cfi_send_gen_cmd(0xF0, 0, chip->start, map, cfi, cfi->device_type, NULL);
DISABLE_VPP(map);
ret = -EIO;
}
DISABLE_VPP(map);
chip->state = FL_READY;
wake_up(&chip->wq);
cfi_spin_unlock(chip->mutex);
return ret;
}
static int cfi_sststd_write (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
int ret = 0;
int chipnum;
unsigned long ofs, chipstart;
*retlen = 0;
if (!len)
return 0;
chipnum = to >> cfi->chipshift;
ofs = to - (chipnum << cfi->chipshift);
chipstart = cfi->chips[chipnum].start;
/* If it's not bus-aligned, do the first byte write */
if (ofs & (CFIDEV_BUSWIDTH-1)) {
unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
int i = ofs - bus_ofs;
int n = 0;
u_char tmp_buf[4];
__u32 datum;
map->copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
while (len && i < CFIDEV_BUSWIDTH)
tmp_buf[i++] = buf[n++], len--;
if (cfi_buswidth_is_2()) {
datum = *(__u16*)tmp_buf;
} else if (cfi_buswidth_is_4()) {
datum = *(__u32*)tmp_buf;
} else {
return -EINVAL; /* should never happen, but be safe */
}
ret = do_write_oneword(map, &cfi->chips[chipnum],
bus_ofs, datum, 0);
if (ret)
return ret;
ofs += n;
buf += n;
(*retlen) += n;
if (ofs >> cfi->chipshift) {
chipnum ++;
ofs = 0;
if (chipnum == cfi->numchips)
return 0;
}
}
/* We are now aligned, write as much as possible */
while(len >= CFIDEV_BUSWIDTH) {
__u32 datum;
if (cfi_buswidth_is_1()) {
datum = *(__u8*)buf;
} else if (cfi_buswidth_is_2()) {
datum = *(__u16*)buf;
} else if (cfi_buswidth_is_4()) {
datum = *(__u32*)buf;
} else {
return -EINVAL;
}
ret = do_write_oneword(map, &cfi->chips[chipnum],
ofs, datum, cfi->fast_prog);
if (ret) {
return ret;
}
ofs += CFIDEV_BUSWIDTH;
buf += CFIDEV_BUSWIDTH;
(*retlen) += CFIDEV_BUSWIDTH;
len -= CFIDEV_BUSWIDTH;
if (ofs >> cfi->chipshift) {
chipnum ++;
ofs = 0;
if (chipnum == cfi->numchips)
return 0;
chipstart = cfi->chips[chipnum].start;
}
}
if (len & (CFIDEV_BUSWIDTH-1)) {
int i = 0, n = 0;
u_char tmp_buf[4];
__u32 datum;
map->copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
while (len--)
tmp_buf[i++] = buf[n++];
if (cfi_buswidth_is_2()) {
datum = *(__u16*)tmp_buf;
} else if (cfi_buswidth_is_4()) {
datum = *(__u32*)tmp_buf;
} else {
return -EINVAL; /* should never happen, but be safe */
}
ret = do_write_oneword(map, &cfi->chips[chipnum],
ofs, datum, 0);
if (ret)
return ret;
(*retlen) += n;
}
return 0;
}
static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
{
unsigned int status;
unsigned long timeo = jiffies + HZ;
struct cfi_private *cfi = map->fldrv_priv;
unsigned int rdy_mask;
DECLARE_WAITQUEUE(wait, current);
retry:
cfi_spin_lock(chip->mutex);
if (chip->state != FL_READY){
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
cfi_spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
timeo = jiffies + HZ;
goto retry;
}
chip->state = FL_ERASING;
adr += chip->start;
ENABLE_VPP(map);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X16, NULL);
cfi_write(map, CMD(0x30), adr);
timeo = jiffies + (HZ*20);
cfi_spin_unlock(chip->mutex);
schedule_timeout(HZ);
cfi_spin_lock(chip->mutex);
rdy_mask = CMD(0x80);
/* Once the state machine's known to be working I'll do that */
while ( ( (status = cfi_read(map,adr)) & rdy_mask ) != rdy_mask ) {
static int z=0;
if (chip->state != FL_ERASING) {
/* Someone's suspended the erase. Sleep */
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&chip->wq, &wait);
cfi_spin_unlock(chip->mutex);
printk("erase suspended. Sleeping\n");
schedule();
remove_wait_queue(&chip->wq, &wait);
timeo = jiffies + (HZ*2);
cfi_spin_lock(chip->mutex);
continue;
}
/* OK Still waiting */
if (time_after(jiffies, timeo)) {
chip->state = FL_READY;
cfi_spin_unlock(chip->mutex);
printk("waiting for erase to complete timed out.");
DISABLE_VPP(map);
return -EIO;
}
/* Latency issues. Drop the lock, wait a while and retry */
cfi_spin_unlock(chip->mutex);
z++;
if ( 0 && !(z % 100 ))
printk("chip not ready yet after erase. looping\n");
cfi_udelay(1);
cfi_spin_lock(chip->mutex);
continue;
}
/* Done and happy. */
DISABLE_VPP(map);
chip->state = FL_READY;
wake_up(&chip->wq);
cfi_spin_unlock(chip->mutex);
return 0;
}
static int cfi_sststd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
unsigned long adr, len;
int chipnum, ret = 0;
int i, first;
struct mtd_erase_region_info *regions = mtd->eraseregions;
if (instr->addr > mtd->size)
return -EINVAL;
if ((instr->len + instr->addr) > mtd->size)
return -EINVAL;
/* Check that both start and end of the requested erase are
* aligned with the erasesize at the appropriate addresses.
*/
i = 0;
/* Skip all erase regions which are ended before the start of
the requested erase. Actually, to save on the calculations,
we skip to the first erase region which starts after the
start of the requested erase, and then go back one.
*/
while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
i++;
i--;
/* OK, now i is pointing at the erase region in which this
erase request starts. Check the start of the requested
erase range is aligned with the erase size which is in
effect here.
*/
if (instr->addr & (regions[i].erasesize-1))
return -EINVAL;
/* Remember the erase region we start on */
first = i;
/* Next, check that the end of the requested erase is aligned
* with the erase region at that address.
*/
while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset)
i++;
/* As before, drop back one to point at the region in which
the address actually falls
*/
i--;
if ((instr->addr + instr->len) & (regions[i].erasesize-1))
return -EINVAL;
chipnum = instr->addr >> cfi->chipshift;
adr = instr->addr - (chipnum << cfi->chipshift);
len = instr->len;
i=first;
while(len) {
ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
if (ret)
return ret;
adr += regions[i].erasesize;
len -= regions[i].erasesize;
if (adr % (1<< cfi->chipshift) == ((regions[i].offset + (regions[i].erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift)))
i++;
if (adr >> cfi->chipshift) {
adr = 0;
chipnum++;
if (chipnum >= cfi->numchips)
break;
}
}
instr->state = MTD_ERASE_DONE;
if (instr->callback)
instr->callback(instr);
return 0;
}
static int cfi_sststd_erase_onesize(struct mtd_info *mtd, struct erase_info *instr)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
unsigned long adr, len;
int chipnum, ret = 0;
if (instr->addr & (mtd->erasesize - 1))
return -EINVAL;
if (instr->len & (mtd->erasesize -1))
return -EINVAL;
if ((instr->len + instr->addr) > mtd->size)
return -EINVAL;
chipnum = instr->addr >> cfi->chipshift;
adr = instr->addr - (chipnum << cfi->chipshift);
len = instr->len;
while(len) {
ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
if (ret)
return ret;
adr += mtd->erasesize;
len -= mtd->erasesize;
if (adr >> cfi->chipshift) {
adr = 0;
chipnum++;
if (chipnum >= cfi->numchips)
break;
}
}
instr->state = MTD_ERASE_DONE;
if (instr->callback)
instr->callback(instr);
return 0;
}
static void cfi_sststd_sync (struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
int i;
struct flchip *chip;
int ret = 0;
DECLARE_WAITQUEUE(wait, current);
for (i=0; !ret && i<cfi->numchips; i++) {
chip = &cfi->chips[i];
retry:
cfi_spin_lock(chip->mutex);
switch(chip->state) {
case FL_READY:
case FL_STATUS:
case FL_CFI_QUERY:
case FL_JEDEC_QUERY:
chip->oldstate = chip->state;
chip->state = FL_SYNCING;
/* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything
* with the chip now anyway.
*/
case FL_SYNCING:
cfi_spin_unlock(chip->mutex);
break;
default:
/* Not an idle state */
add_wait_queue(&chip->wq, &wait);
cfi_spin_unlock(chip->mutex);
schedule();
remove_wait_queue(&chip->wq, &wait);
goto retry;
}
}
/* Unlock the chips again */
for (i--; i >=0; i--) {
chip = &cfi->chips[i];
cfi_spin_lock(chip->mutex);
if (chip->state == FL_SYNCING) {
chip->state = chip->oldstate;
wake_up(&chip->wq);
}
cfi_spin_unlock(chip->mutex);
}
}
static int cfi_sststd_suspend(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
int i;
struct flchip *chip;
int ret = 0;
//printk("suspend\n");
for (i=0; !ret && i<cfi->numchips; i++) {
chip = &cfi->chips[i];
cfi_spin_lock(chip->mutex);
switch(chip->state) {
case FL_READY:
case FL_STATUS:
case FL_CFI_QUERY:
case FL_JEDEC_QUERY:
chip->oldstate = chip->state;
chip->state = FL_PM_SUSPENDED;
/* No need to wake_up() on this state change -
* as the whole point is that nobody can do anything
* with the chip now anyway.
*/
case FL_PM_SUSPENDED:
break;
default:
ret = -EAGAIN;
break;
}
cfi_spin_unlock(chip->mutex);
}
/* Unlock the chips again */
if (ret) {
for (i--; i >=0; i--) {
chip = &cfi->chips[i];
cfi_spin_lock(chip->mutex);
if (chip->state == FL_PM_SUSPENDED) {
chip->state = chip->oldstate;
wake_up(&chip->wq);
}
cfi_spin_unlock(chip->mutex);
}
}
return ret;
}
static void cfi_sststd_resume(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
int i;
struct flchip *chip;
//printk("resume\n");
for (i=0; i<cfi->numchips; i++) {
chip = &cfi->chips[i];
cfi_spin_lock(chip->mutex);
if (chip->state == FL_PM_SUSPENDED) {
chip->state = FL_READY;
cfi_write(map, CMD(0xF0), chip->start);
wake_up(&chip->wq);
}
else
printk("Argh. Chip not in PM_SUSPENDED state upon resume()\n");
cfi_spin_unlock(chip->mutex);
}
}
static void cfi_sststd_destroy(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
kfree(cfi->cmdset_priv);
kfree(cfi);
}
#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
#define cfi_sststd_init init_module
#define cfi_sststd_exit cleanup_module
#endif
static char im_name[]="cfi_cmdset_0701";
mod_init_t cfi_sststd_init(void)
{
inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0701);
return 0;
}
mod_exit_t cfi_sststd_exit(void)
{
inter_module_unregister(im_name);
}
module_init(cfi_sststd_init);
module_exit(cfi_sststd_exit);

View File

@ -1,236 +0,0 @@
/*
* Flash mapping for BCM947XX boards
*
* 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.
*
* $Id$
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/config.h>
#include <typedefs.h>
#include <bcmnvram.h>
#include <bcmutils.h>
#include <sbconfig.h>
#include <sbchipc.h>
#include <sbutils.h>
#include <trxhdr.h>
/* Global SB handle */
extern void *bcm947xx_sbh;
extern spinlock_t bcm947xx_sbh_lock;
/* Convenience */
#define sbh bcm947xx_sbh
#define sbh_lock bcm947xx_sbh_lock
#ifdef CONFIG_MTD_PARTITIONS
extern struct mtd_partition * init_mtd_partitions(struct mtd_info *mtd, size_t size);
#endif
#define WINDOW_ADDR 0x1fc00000
#define WINDOW_SIZE 0x400000
#define BUSWIDTH 2
/* e.g., flash=2M or flash=4M */
static int flash = 0;
MODULE_PARM(flash, "i");
static int __init
bcm947xx_setup(char *str)
{
flash = memparse(str, &str);
return 1;
}
__setup("flash=", bcm947xx_setup);
static struct mtd_info *bcm947xx_mtd;
__u8 bcm947xx_map_read8(struct map_info *map, unsigned long ofs)
{
if (map->map_priv_2 == 1)
return __raw_readb(map->map_priv_1 + ofs);
u16 val = __raw_readw(map->map_priv_1 + (ofs & ~1));
if (ofs & 1)
return ((val >> 8) & 0xff);
else
return (val & 0xff);
}
__u16 bcm947xx_map_read16(struct map_info *map, unsigned long ofs)
{
return __raw_readw(map->map_priv_1 + ofs);
}
__u32 bcm947xx_map_read32(struct map_info *map, unsigned long ofs)
{
return __raw_readl(map->map_priv_1 + ofs);
}
void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
{
if (len==1) {
memcpy_fromio(to, map->map_priv_1 + from, len);
} else {
int i;
u16 *dest = (u16 *) to;
u16 *src = (u16 *) (map->map_priv_1 + from);
for (i = 0; i < (len / 2); i++) {
dest[i] = src[i];
}
if (len & 1)
*((u8 *)dest+len-1) = src[i] & 0xff;
}
}
void bcm947xx_map_write8(struct map_info *map, __u8 d, unsigned long adr)
{
__raw_writeb(d, map->map_priv_1 + adr);
mb();
}
void bcm947xx_map_write16(struct map_info *map, __u16 d, unsigned long adr)
{
__raw_writew(d, map->map_priv_1 + adr);
mb();
}
void bcm947xx_map_write32(struct map_info *map, __u32 d, unsigned long adr)
{
__raw_writel(d, map->map_priv_1 + adr);
mb();
}
void bcm947xx_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
{
memcpy_toio(map->map_priv_1 + to, from, len);
}
struct map_info bcm947xx_map = {
name: "Physically mapped flash",
size: WINDOW_SIZE,
buswidth: BUSWIDTH,
read8: bcm947xx_map_read8,
read16: bcm947xx_map_read16,
read32: bcm947xx_map_read32,
copy_from: bcm947xx_map_copy_from,
write8: bcm947xx_map_write8,
write16: bcm947xx_map_write16,
write32: bcm947xx_map_write32,
copy_to: bcm947xx_map_copy_to
};
#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
#define init_bcm947xx_map init_module
#define cleanup_bcm947xx_map cleanup_module
#endif
mod_init_t init_bcm947xx_map(void)
{
ulong flags;
uint coreidx;
chipcregs_t *cc;
uint32 fltype;
uint window_addr = 0, window_size = 0;
size_t size;
int ret = 0;
#ifdef CONFIG_MTD_PARTITIONS
struct mtd_partition *parts;
int i;
#endif
spin_lock_irqsave(&sbh_lock, flags);
coreidx = sb_coreidx(sbh);
/* Check strapping option if chipcommon exists */
if ((cc = sb_setcore(sbh, SB_CC, 0))) {
fltype = readl(&cc->capabilities) & CAP_FLASH_MASK;
if (fltype == PFLASH) {
bcm947xx_map.map_priv_2 = 1;
window_addr = 0x1c000000;
bcm947xx_map.size = window_size = 32 * 1024 * 1024;
if ((readl(&cc->flash_config) & CC_CFG_DS) == 0)
bcm947xx_map.buswidth = 1;
}
} else {
fltype = PFLASH;
bcm947xx_map.map_priv_2 = 0;
window_addr = WINDOW_ADDR;
window_size = WINDOW_SIZE;
}
sb_setcoreidx(sbh, coreidx);
spin_unlock_irqrestore(&sbh_lock, flags);
if (fltype != PFLASH) {
printk(KERN_ERR "pflash: found no supported devices\n");
ret = -ENODEV;
goto fail;
}
bcm947xx_map.map_priv_1 = (unsigned long) ioremap(window_addr, window_size);
if (!bcm947xx_map.map_priv_1) {
printk(KERN_ERR "pflash: ioremap failed\n");
ret = -EIO;
goto fail;
}
if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) {
printk(KERN_ERR "pflash: cfi_probe failed\n");
ret = -ENXIO;
goto fail;
}
bcm947xx_mtd->module = THIS_MODULE;
/* Allow size override for testing */
size = flash ? : bcm947xx_mtd->size;
printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, window_addr);
#ifdef CONFIG_MTD_PARTITIONS
parts = init_mtd_partitions(bcm947xx_mtd, size);
for (i = 0; parts[i].name; i++);
ret = add_mtd_partitions(bcm947xx_mtd, parts, i);
if (ret) {
printk(KERN_ERR "pflash: add_mtd_partitions failed\n");
goto fail;
}
#endif
return 0;
fail:
if (bcm947xx_mtd)
map_destroy(bcm947xx_mtd);
if (bcm947xx_map.map_priv_1)
iounmap((void *) bcm947xx_map.map_priv_1);
bcm947xx_map.map_priv_1 = 0;
return ret;
}
mod_exit_t cleanup_bcm947xx_map(void)
{
#ifdef CONFIG_MTD_PARTITIONS
del_mtd_partitions(bcm947xx_mtd);
#endif
map_destroy(bcm947xx_mtd);
iounmap((void *) bcm947xx_map.map_priv_1);
bcm947xx_map.map_priv_1 = 0;
}
module_init(init_bcm947xx_map);
module_exit(cleanup_bcm947xx_map);

View File

@ -1,9 +0,0 @@
O_TARGET := diag.o
MAC_OBJS := diag_led.o
export-objs :=
obj-y := $(MAC_OBJS)
obj-m := $(O_TARGET)
include $(TOPDIR)/Rules.make

View File

@ -1,244 +0,0 @@
/*
* diag_led.c - replacement diag module
*
* Copyright (C) 2004 Mike Baker,
* Imre Kaloz <kaloz@dune.hu>
*
* 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.
*
* $Id$
*/
/*
* ChangeLog:
* 2004/03/28 initial release
* 2004/08/26 asus & buffalo support added
* 2005/03/14 asus wl-500g deluxe and buffalo v2 support added
* 2005/04/13 added licensing informations
* 2005/04/18 base reset polarity off initial readings
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sysctl.h>
#include <asm/io.h>
#include <typedefs.h>
#include <bcm4710.h>
#include <sbutils.h>
extern char * nvram_get(const char *name);
static void *sbh;
// v2.x - - - - -
#define DIAG_GPIO (1<<1)
#define DMZ_GPIO (1<<7)
static void set_gpio(uint32 mask, uint32 value) {
sb_gpiocontrol(sbh,mask,0);
sb_gpioouten(sbh,mask,mask);
sb_gpioout(sbh,mask,value);
}
static void v2_set_diag(u8 state) {
set_gpio(DIAG_GPIO,state);
}
static void v2_set_dmz(u8 state) {
set_gpio(DMZ_GPIO,state);
}
// v1.x - - - - -
#define LED_DIAG 0x13
#define LED_DMZ 0x12
static void v1_set_diag(u8 state) {
if (!state) {
*(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DIAG)=0xFF;
} else {
*(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DIAG);
}
}
static void v1_set_dmz(u8 state) {
if (!state) {
*(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DMZ)=0xFF;
} else {
*(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DMZ);
}
}
// - - - - -
static void ignore(u8 ignored) {};
// - - - - -
#define BIT_DMZ 0x01
#define BIT_DIAG 0x04
void (*set_diag)(u8 state);
void (*set_dmz)(u8 state);
static unsigned int diag = 0;
static void diag_change()
{
set_diag(0xFF); // off
set_dmz(0xFF); // off
if(diag & BIT_DIAG)
set_diag(0x00); // on
if(diag & BIT_DMZ)
set_dmz(0x00); // on
}
static int proc_diag(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
{
int r;
r = proc_dointvec(table, write, filp, buffer, lenp);
if (write && !r) {
diag_change();
}
return r;
}
// - - - - -
static unsigned char reset_gpio = 0;
static unsigned char reset_polarity = 0;
static unsigned int reset = 0;
static int proc_reset(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
{
if (reset_gpio) {
sb_gpiocontrol(sbh,reset_gpio,reset_gpio);
sb_gpioouten(sbh,reset_gpio,0);
reset=!(sb_gpioin(sbh)&reset_gpio);
if (reset_polarity) reset=!reset;
} else {
reset=0;
}
return proc_dointvec(table, write, filp, buffer, lenp);
}
// - - - - -
static struct ctl_table_header *diag_sysctl_header;
static ctl_table sys_diag[] = {
{
ctl_name: 2000,
procname: "diag",
data: &diag,
maxlen: sizeof(diag),
mode: 0644,
proc_handler: proc_diag
},
{
ctl_name: 2001,
procname: "reset",
data: &reset,
maxlen: sizeof(reset),
mode: 0444,
proc_handler: proc_reset
},
{ 0 }
};
static int __init diag_init()
{
char *buf;
u32 board_type;
sbh = sb_kattach();
sb_gpiosetcore(sbh);
board_type = sb_boardtype(sbh);
printk(KERN_INFO "diag boardtype: %08x\n",board_type);
set_diag=ignore;
set_dmz=ignore;
if ((board_type & 0xf00) == 0x400) {
buf=nvram_get("boardtype")?:"";
if (!strcmp(buf,"bcm94710dev")) {
buf=nvram_get("boardnum")?:"";
if (!strcmp(buf,"42")) {
// wrt54g v1.x
set_diag=v1_set_diag;
set_dmz=v1_set_dmz;
reset_gpio=(1<<6);
}
if (!strcmp(buf,"asusX")) {
//asus wl-500g
reset_gpio=(1<<6);
}
}
if (!strcmp(buf,"bcm94710ap")) {
buf=nvram_get("boardnum")?:"";
if (!strcmp(buf,"42")) {
// buffalo
set_dmz=v2_set_dmz;
reset_gpio=(1<<4);
}
if (!strcmp(buf,"44")) {
//dell truemobile
set_dmz=v2_set_dmz;
reset_gpio=(1<<0);
}
}
} else {
buf=nvram_get("boardnum")?:"";
if (!strcmp(buf,"42")) {
//linksys
set_diag=v2_set_diag;
set_dmz=v2_set_dmz;
reset_gpio=(1<<6);
}
if (!strcmp(buf,"44")) {
//motorola
reset_gpio=(1<<5);
}
if (!strcmp(buf,"00")) {
//buffalo
reset_gpio=(1<<7);
}
if (!strcmp(buf,"45")) {
//wl-500g deluxe
reset_gpio=(1<<6);
}
}
sb_gpiocontrol(sbh,reset_gpio,reset_gpio);
sb_gpioouten(sbh,reset_gpio,0);
reset_polarity=!(sb_gpioin(sbh)&reset_gpio);
diag_sysctl_header = register_sysctl_table(sys_diag, 0);
diag_change();
return 0;
}
static void __exit diag_exit()
{
unregister_sysctl_table(diag_sysctl_header);
}
EXPORT_NO_SYMBOLS;
MODULE_AUTHOR("openwrt.org");
MODULE_LICENSE("GPL");
module_init(diag_init);
module_exit(diag_exit);

View File

@ -1,34 +0,0 @@
#
# Makefile for the Broadcom et driver
#
# 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.
#
# $Id$
#
O_TARGET := et.o
ET_OBJS := et_linux.o etc.o
ifeq ($(CONFIG_ET_47XX),y)
ET_OBJS += etc47xx.o etc_robo.o etc_adm.o
EXTRA_CFLAGS += -DBCM47XX_CHOPS
endif
ifeq ($(CONFIG_ET_4413),y)
ET_OBJS += etc4413.o
EXTRA_CFLAGS += -DBCM4413_CHOPS
endif
export-objs :=
obj-y := $(ET_OBJS)
obj-m := $(O_TARGET)
EXTRA_CFLAGS += -DDMA
include $(TOPDIR)/Rules.make

View File

@ -1,35 +0,0 @@
#
# Broadcom Home Networking Division (HND) driver configuration
#
# 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.
#
mainmenu_option next_comment
comment 'Broadcom HND network devices'
tristate 'Broadcom HND network device support' CONFIG_HND $CONFIG_PCI
if [ "$CONFIG_HND" != "n" ]; then
dep_tristate ' Broadcom InsideLine HPNA support' CONFIG_IL $CONFIG_HND
if [ "$CONFIG_IL" != "n" ]; then
bool ' Broadcom BCM42xx support' CONFIG_IL_42XX
bool ' Broadcom BCM47xx support' CONFIG_IL_47XX
int ' LARQ buffer allocation (0 = tiny, 2 = huge)' CONFIG_LARQ_BUF 0
fi
dep_tristate ' Broadcom 10/100 Ethernet support' CONFIG_ET $CONFIG_HND
if [ "$CONFIG_ET" != "n" ]; then
bool ' Broadcom BCM4413 support' CONFIG_ET_4413
bool ' Broadcom BCM47xx support' CONFIG_ET_47XX
fi
dep_tristate ' Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL $CONFIG_HND
if [ "$CONFIG_WL" != "n" ]; then
bool ' Access Point Mode Supported' CONFIG_WL_AP
bool ' STA Mode Supported' CONFIG_WL_STA
bool ' OID Interface Supported' CONFIG_WL_OID
fi
fi
endmenu

View File

@ -1,30 +0,0 @@
#
# Makefile for Broadcom Home Networking Division (HND) shared driver code
#
# 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.
#
# $Id$
#
O_TARGET := hnd.o
HND_OBJS := bcmutils.o hnddma.o linux_osl.o sbutils.o bcmsrom.o
ifneq ($(CONFIG_BCM947XX),y)
HND_OBJS += nvramstubs.o
endif
export-objs := shared_ksyms.o
obj-y := shared_ksyms.o $(HND_OBJS)
obj-m := $(O_TARGET)
include $(TOPDIR)/Rules.make
shared_ksyms.c: shared_ksyms.sh $(HND_OBJS)
sh -e $< $(HND_OBJS) > $@

View File

@ -1,711 +0,0 @@
/*
* Misc useful routines to access NIC SROM
*
* 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.
* $Id$
*/
#include <typedefs.h>
#include <osl.h>
#include <bcmutils.h>
#include <bcmsrom.h>
#include <bcmdevs.h>
#include <bcmendian.h>
#include <sbpcmcia.h>
#include <pcicfg.h>
#include <sbutils.h>
#include <proto/ethernet.h> /* for sprom content groking */
#define VARS_MAX 4096 /* should be reduced */
static int initvars_srom_pci(void *curmap, char **vars, int *count);
static int initvars_cis_pcmcia(void *sbh, void *curmap, void *osh, char **vars, int *count);
static int sprom_cmd_pcmcia(void *osh, uint8 cmd);
static int sprom_read_pcmcia(void *osh, uint16 addr, uint16 *data);
static int sprom_write_pcmcia(void *osh, uint16 addr, uint16 data);
static int sprom_read_pci(uint16 *sprom, uint byteoff, uint16 *buf, uint nbytes, bool check_crc);
/*
* Initialize the vars from the right source for this platform.
* Return 0 on success, nonzero on error.
*/
int
srom_var_init(void *sbh, uint bus, void *curmap, void *osh, char **vars, int *count)
{
if (vars == NULL)
return (0);
switch (bus) {
case SB_BUS:
/* These two could be asserts ... */
*vars = NULL;
*count = 0;
return(0);
case PCI_BUS:
ASSERT(curmap); /* can not be NULL */
return(initvars_srom_pci(curmap, vars, count));
case PCMCIA_BUS:
return(initvars_cis_pcmcia(sbh, curmap, osh, vars, count));
default:
ASSERT(0);
}
return (-1);
}
/* support only 16-bit word read from srom */
int
srom_read(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf)
{
void *srom;
uint i, off, nw;
/* check input - 16-bit access only */
if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
return 1;
if (bus == PCI_BUS) {
if (!curmap)
return 1;
srom = (void *)((uint)curmap + PCI_BAR0_SPROM_OFFSET);
if (sprom_read_pci(srom, byteoff, buf, nbytes, FALSE))
return 1;
} else if (bus == PCMCIA_BUS) {
off = byteoff / 2;
nw = nbytes / 2;
for (i = 0; i < nw; i++) {
if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i)))
return 1;
}
} else {
return 1;
}
return 0;
}
/* support only 16-bit word write into srom */
int
srom_write(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf)
{
uint16 *srom;
uint i, off, nw, crc_range;
uint16 image[SPROM_SIZE], *p;
uint8 crc;
volatile uint32 val32;
/* check input - 16-bit access only */
if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
return 1;
crc_range = ((bus == PCMCIA_BUS) ? SPROM_SIZE : SPROM_CRC_RANGE) * 2;
/* if changes made inside crc cover range */
if (byteoff < crc_range) {
nw = (((byteoff + nbytes) > crc_range) ? byteoff + nbytes : crc_range) / 2;
/* read data including entire first 64 words from srom */
if (srom_read(bus, curmap, osh, 0, nw * 2, image))
return 1;
/* make changes */
bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes);
/* calculate crc */
htol16_buf(image, crc_range);
crc = ~crc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE);
ltoh16_buf(image, crc_range);
image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff);
p = image;
off = 0;
} else {
p = buf;
off = byteoff / 2;
nw = nbytes / 2;
}
if (bus == PCI_BUS) {
srom = (uint16*)((uint)curmap + PCI_BAR0_SPROM_OFFSET);
/* enable writes to the SPROM */
val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
val32 |= SPROM_WRITEEN;
OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32);
bcm_mdelay(500);
/* write srom */
for (i = 0; i < nw; i++) {
W_REG(&srom[off + i], p[i]);
bcm_mdelay(20);
}
/* disable writes to the SPROM */
OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ~SPROM_WRITEEN);
} else if (bus == PCMCIA_BUS) {
/* enable writes to the SPROM */
if (sprom_cmd_pcmcia(osh, SROM_WEN))
return 1;
bcm_mdelay(500);
/* write srom */
for (i = 0; i < nw; i++) {
sprom_write_pcmcia(osh, (uint16)(off + i), p[i]);
bcm_mdelay(20);
}
/* disable writes to the SPROM */
if (sprom_cmd_pcmcia(osh, SROM_WDS))
return 1;
} else {
return 1;
}
bcm_mdelay(500);
return 0;
}
int
srom_parsecis(uint8 *cis, char **vars, int *count)
{
char eabuf[32];
char *vp, *base;
uint8 tup, tlen, sromrev = 1;
int i, j;
uint varsize;
bool ag_init = FALSE;
uint16 w;
ASSERT(vars);
ASSERT(count);
base = vp = MALLOC(VARS_MAX);
ASSERT(vp);
i = 0;
do {
tup = cis[i++];
tlen = cis[i++];
if ((i + tlen) >= CIS_SIZE)
break;
switch (tup) {
case CISTPL_MANFID:
vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]);
vp++;
vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]);
vp++;
break;
case CISTPL_FUNCE:
if (cis[i] == LAN_NID) {
ASSERT(cis[i + 1] == ETHER_ADDR_LEN);
bcm_ether_ntoa((uchar*)&cis[i + 2], eabuf);
vp += sprintf(vp, "il0macaddr=%s", eabuf);
vp++;
}
break;
case CISTPL_CFTABLE:
vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]);
vp++;
break;
case CISTPL_BRCM_HNBU:
switch (cis[i]) {
case HNBU_CHIPID:
vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) + cis[i + 1]);
vp++;
vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) + cis[i + 3]);
vp++;
if (tlen == 7) {
vp += sprintf(vp, "chiprev=%d", (cis[i + 6] << 8) + cis[i + 5]);
vp++;
}
break;
case HNBU_BOARDREV:
vp += sprintf(vp, "boardrev=%d", cis[i + 1]);
vp++;
break;
case HNBU_AA:
vp += sprintf(vp, "aa0=%d", cis[i + 1]);
vp++;
break;
case HNBU_AG:
vp += sprintf(vp, "ag0=%d", cis[i + 1]);
vp++;
ag_init = TRUE;
break;
case HNBU_CC:
vp += sprintf(vp, "cc=%d", cis[i + 1]);
vp++;
break;
case HNBU_PAPARMS:
vp += sprintf(vp, "pa0maxpwr=%d", cis[i + tlen - 1]);
vp++;
if (tlen == 9) {
/* New version */
for (j = 0; j < 3; j++) {
vp += sprintf(vp, "pa0b%d=%d", j,
(cis[i + (j * 2) + 2] << 8) + cis[i + (j * 2) + 1]);
vp++;
}
vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]);
vp++;
}
break;
case HNBU_OEM:
vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
cis[i + 1], cis[i + 2], cis[i + 3], cis[i + 4],
cis[i + 5], cis[i + 6], cis[i + 7], cis[i + 8]);
vp++;
break;
case HNBU_BOARDFLAGS:
w = (cis[i + 2] << 8) + cis[i + 1];
if (w == 0xffff) w = 0;
vp += sprintf(vp, "boardflags=%d", w);
vp++;
break;
case HNBU_LED:
if (cis[i + 1] != 0xff) {
vp += sprintf(vp, "wl0gpio0=%d", cis[i + 1]);
vp++;
}
if (cis[i + 2] != 0xff) {
vp += sprintf(vp, "wl0gpio1=%d", cis[i + 2]);
vp++;
}
if (cis[i + 3] != 0xff) {
vp += sprintf(vp, "wl0gpio2=%d", cis[i + 3]);
vp++;
}
if (cis[i + 4] != 0xff) {
vp += sprintf(vp, "wl0gpio3=%d", cis[i + 4]);
vp++;
}
break;
}
break;
}
i += tlen;
} while (tup != 0xff);
/* Set the srom version */
vp += sprintf(vp, "sromrev=%d", sromrev);
vp++;
/* For now just set boardflags2 to zero */
vp += sprintf(vp, "boardflags2=0");
vp++;
/* if there is no antenna gain field, set default */
if (ag_init == FALSE) {
vp += sprintf(vp, "ag0=%d", 0xff);
vp++;
}
/* final nullbyte terminator */
*vp++ = '\0';
varsize = (uint)vp - (uint)base;
ASSERT(varsize < VARS_MAX);
if (varsize == VARS_MAX) {
*vars = base;
} else {
vp = MALLOC(varsize);
ASSERT(vp);
bcopy(base, vp, varsize);
MFREE(base, VARS_MAX);
*vars = vp;
}
*count = varsize;
return (0);
}
/* set PCMCIA sprom command register */
static int
sprom_cmd_pcmcia(void *osh, uint8 cmd)
{
uint8 status;
uint wait_cnt = 1000;
/* write sprom command register */
OSL_PCMCIA_WRITE_ATTR(osh, SROM_CS, &cmd, 1);
/* wait status */
while (wait_cnt--) {
OSL_PCMCIA_READ_ATTR(osh, SROM_CS, &status, 1);
if (status & SROM_DONE)
return 0;
}
return 1;
}
/* read a word from the PCMCIA srom */
static int
sprom_read_pcmcia(void *osh, uint16 addr, uint16 *data)
{
uint8 addr_l, addr_h, data_l, data_h;
addr_l = (uint8)((addr * 2) & 0xff);
addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
/* set address */
OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
/* do read */
if (sprom_cmd_pcmcia(osh, SROM_READ))
return 1;
/* read data */
OSL_PCMCIA_READ_ATTR(osh, SROM_DATAH, &data_h, 1);
OSL_PCMCIA_READ_ATTR(osh, SROM_DATAL, &data_l, 1);
*data = (data_h << 8) | data_l;
return 0;
}
/* write a word to the PCMCIA srom */
static int
sprom_write_pcmcia(void *osh, uint16 addr, uint16 data)
{
uint8 addr_l, addr_h, data_l, data_h;
addr_l = (uint8)((addr * 2) & 0xff);
addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
data_l = (uint8)(data & 0xff);
data_h = (uint8)((data >> 8) & 0xff);
/* set address */
OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
/* write data */
OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAH, &data_h, 1);
OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAL, &data_l, 1);
/* do write */
return sprom_cmd_pcmcia(osh, SROM_WRITE);
}
/*
* Read in and validate sprom.
* Return 0 on success, nonzero on error.
*/
static int
sprom_read_pci(uint16 *sprom, uint byteoff, uint16 *buf, uint nbytes, bool check_crc)
{
int off, nw;
uint8 chk8;
int i;
off = byteoff / 2;
nw = ROUNDUP(nbytes, 2) / 2;
/* read the sprom */
for (i = 0; i < nw; i++)
buf[i] = R_REG(&sprom[off + i]);
if (check_crc) {
/* fixup the endianness so crc8 will pass */
htol16_buf(buf, nw * 2);
if ((chk8 = crc8((uchar*)buf, nbytes, CRC8_INIT_VALUE)) != CRC8_GOOD_VALUE)
return (1);
/* now correct the endianness of the byte array */
ltoh16_buf(buf, nw * 2);
}
return (0);
}
/*
* Initialize nonvolatile variable table from sprom.
* Return 0 on success, nonzero on error.
*/
static int
initvars_srom_pci(void *curmap, char **vars, int *count)
{
uint16 w, b[64];
uint8 sromrev;
struct ether_addr ea;
char eabuf[32];
uint32 bfl;
int c, woff, i;
char *vp, *base;
if (sprom_read_pci((void *)((uint)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof (b), TRUE))
return (-1);
/* top word of sprom contains version and crc8 */
sromrev = b[63] & 0xff;
if ((sromrev != 1) && (sromrev != 2)) {
return (-2);
}
ASSERT(vars);
ASSERT(count);
base = vp = MALLOC(VARS_MAX);
ASSERT(vp);
vp += sprintf(vp, "sromrev=%d", sromrev);
vp++;
if (sromrev >= 2) {
/* New section takes over the 4th hardware function space */
/* Word 29 is max power 11a high/low */
w = b[29];
vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff);
vp++;
vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff);
vp++;
/* Words 30-32 set the 11alow pa settings,
* 33-35 are the 11ahigh ones.
*/
for (i = 0; i < 3; i++) {
vp += sprintf(vp, "pa1lob%d=%d", i, b[30 + i]);
vp++;
vp += sprintf(vp, "pa1hib%d=%d", i, b[33 + i]);
vp++;
}
w = b[59];
if (w == 0)
vp += sprintf(vp, "ccode=");
else
vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff));
vp++;
}
/* parameter section of sprom starts at byte offset 72 */
woff = 72/2;
/* first 6 bytes are il0macaddr */
ea.octet[0] = (b[woff] >> 8) & 0xff;
ea.octet[1] = b[woff] & 0xff;
ea.octet[2] = (b[woff+1] >> 8) & 0xff;
ea.octet[3] = b[woff+1] & 0xff;
ea.octet[4] = (b[woff+2] >> 8) & 0xff;
ea.octet[5] = b[woff+2] & 0xff;
woff += ETHER_ADDR_LEN/2 ;
bcm_ether_ntoa((uchar*)&ea, eabuf);
vp += sprintf(vp, "il0macaddr=%s", eabuf);
vp++;
/* next 6 bytes are et0macaddr */
ea.octet[0] = (b[woff] >> 8) & 0xff;
ea.octet[1] = b[woff] & 0xff;
ea.octet[2] = (b[woff+1] >> 8) & 0xff;
ea.octet[3] = b[woff+1] & 0xff;
ea.octet[4] = (b[woff+2] >> 8) & 0xff;
ea.octet[5] = b[woff+2] & 0xff;
woff += ETHER_ADDR_LEN/2 ;
bcm_ether_ntoa((uchar*)&ea, eabuf);
vp += sprintf(vp, "et0macaddr=%s", eabuf);
vp++;
/* next 6 bytes are et1macaddr */
ea.octet[0] = (b[woff] >> 8) & 0xff;
ea.octet[1] = b[woff] & 0xff;
ea.octet[2] = (b[woff+1] >> 8) & 0xff;
ea.octet[3] = b[woff+1] & 0xff;
ea.octet[4] = (b[woff+2] >> 8) & 0xff;
ea.octet[5] = b[woff+2] & 0xff;
woff += ETHER_ADDR_LEN/2 ;
bcm_ether_ntoa((uchar*)&ea, eabuf);
vp += sprintf(vp, "et1macaddr=%s", eabuf);
vp++;
/*
* Enet phy settings one or two singles or a dual
* Bits 4-0 : MII address for enet0 (0x1f for not there)
* Bits 9-5 : MII address for enet1 (0x1f for not there)
* Bit 14 : Mdio for enet0
* Bit 15 : Mdio for enet1
*/
w = b[woff];
vp += sprintf(vp, "et0phyaddr=%d", (w & 0x1f));
vp++;
vp += sprintf(vp, "et1phyaddr=%d", ((w >> 5) & 0x1f));
vp++;
vp += sprintf(vp, "et0mdcport=%d", ((w >> 14) & 0x1));
vp++;
vp += sprintf(vp, "et1mdcport=%d", ((w >> 15) & 0x1));
vp++;
/* Word 46 has board rev, antennas 0/1 & Country code/control */
w = b[46];
vp += sprintf(vp, "boardrev=%d", w & 0xff);
vp++;
if (sromrev > 1)
vp += sprintf(vp, "cctl=%d", (w >> 8) & 0xf);
else
vp += sprintf(vp, "cc=%d", (w >> 8) & 0xf);
vp++;
vp += sprintf(vp, "aa0=%d", (w >> 12) & 0x3);
vp++;
vp += sprintf(vp, "aa1=%d", (w >> 14) & 0x3);
vp++;
/* Words 47-49 set the (wl) pa settings */
woff = 47;
for (i = 0; i < 3; i++) {
vp += sprintf(vp, "pa0b%d=%d", i, b[woff+i]);
vp++;
vp += sprintf(vp, "pa1b%d=%d", i, b[woff+i+6]);
vp++;
}
/*
* Words 50-51 set the customer-configured wl led behavior.
* 8 bits/gpio pin. High bit: activehi=0, activelo=1;
* LED behavior values defined in wlioctl.h .
*/
w = b[50];
if ((w != 0) && (w != 0xffff)) {
/* gpio0 */
vp += sprintf(vp, "wl0gpio0=%d", (w & 0xff));
vp++;
/* gpio1 */
vp += sprintf(vp, "wl0gpio1=%d", (w >> 8) & 0xff);
vp++;
}
w = b[51];
if ((w != 0) && (w != 0xffff)) {
/* gpio2 */
vp += sprintf(vp, "wl0gpio2=%d", w & 0xff);
vp++;
/* gpio3 */
vp += sprintf(vp, "wl0gpio3=%d", (w >> 8) & 0xff);
vp++;
}
/* Word 52 is max power 0/1 */
w = b[52];
vp += sprintf(vp, "pa0maxpwr=%d", w & 0xff);
vp++;
vp += sprintf(vp, "pa1maxpwr=%d", (w >> 8) & 0xff);
vp++;
/* Word 56 is idle tssi target 0/1 */
w = b[56];
vp += sprintf(vp, "pa0itssit=%d", w & 0xff);
vp++;
vp += sprintf(vp, "pa1itssit=%d", (w >> 8) & 0xff);
vp++;
/* Word 57 is boardflags, if not programmed make it zero */
bfl = (uint32)b[57];
if (bfl == 0xffff) bfl = 0;
if (sromrev > 1) {
/* Word 28 is boardflags2 */
bfl |= (uint32)b[28] << 16;
}
vp += sprintf(vp, "boardflags=%d", bfl);
vp++;
/* Word 58 is antenna gain 0/1 */
w = b[58];
vp += sprintf(vp, "ag0=%d", w & 0xff);
vp++;
vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff);
vp++;
if (sromrev == 1) {
/* set the oem string */
vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
((b[59] >> 8) & 0xff), (b[59] & 0xff),
((b[60] >> 8) & 0xff), (b[60] & 0xff),
((b[61] >> 8) & 0xff), (b[61] & 0xff),
((b[62] >> 8) & 0xff), (b[62] & 0xff));
vp++;
} else {
if (sromrev >= 1){
/* Word 60 OFDM tx power offset from CCK level */
/* OFDM Power Offset - opo */
w = b[60] & 0xff;
if (w == 0xff)
w = 16;
vp += sprintf(vp, "opo=%d", w);
vp++;
}
}
/* final nullbyte terminator */
*vp++ = '\0';
c = vp - base;
ASSERT(c <= VARS_MAX);
if (c == VARS_MAX) {
*vars = base;
} else {
vp = MALLOC(c);
ASSERT(vp);
bcopy(base, vp, c);
MFREE(base, VARS_MAX);
*vars = vp;
}
*count = c;
return (0);
}
/*
* Read the cis and call parsecis to initialize the vars.
* Return 0 on success, nonzero on error.
*/
static int
initvars_cis_pcmcia(void *sbh, void *curmap, void *osh, char **vars, int *count)
{
uint8 *cis = NULL;
int rc;
uint data_sz;
data_sz = (sb_pcmciarev(sbh) == 1) ? (SPROM_SIZE * 2) : CIS_SIZE;
if ((cis = MALLOC(data_sz)) == NULL)
return (-1);
if (sb_pcmciarev(sbh) == 1) {
if (srom_read(PCMCIA_BUS, (void *)NULL, osh, 0, data_sz, (uint16 *)cis)) {
MFREE(cis, data_sz);
return (-1);
}
/* fix up endianess for 16-bit data vs 8-bit parsing */
ltoh16_buf((uint16 *)cis, data_sz);
} else
OSL_PCMCIA_READ_ATTR(osh, 0, cis, data_sz);
rc = srom_parsecis(cis, vars, count);
MFREE(cis, data_sz);
return (rc);
}

View File

@ -1,803 +0,0 @@
/*
* Misc useful OS-independent routines.
*
* 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.
* $Id$
*/
#include <typedefs.h>
#include <osl.h>
#include <bcmutils.h>
#include <bcmendian.h>
#include <bcmnvram.h>
unsigned char bcm_ctype[] = {
_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */
_BCM_C,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C,_BCM_C, /* 8-15 */
_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */
_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */
_BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */
_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */
_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */
_BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */
_BCM_P,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U, /* 64-71 */
_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */
_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */
_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */
_BCM_P,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L, /* 96-103 */
_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */
_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */
_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
_BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 160-175 */
_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 176-191 */
_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 192-207 */
_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_L, /* 208-223 */
_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 224-239 */
_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L /* 240-255 */
};
uchar
bcm_toupper(uchar c)
{
if (bcm_islower(c))
c -= 'a'-'A';
return (c);
}
ulong
bcm_strtoul(char *cp, char **endp, uint base)
{
ulong result, value;
bool minus;
minus = FALSE;
while (bcm_isspace(*cp))
cp++;
if (cp[0] == '+')
cp++;
else if (cp[0] == '-') {
minus = TRUE;
cp++;
}
if (base == 0) {
if (cp[0] == '0') {
if ((cp[1] == 'x') || (cp[1] == 'X')) {
base = 16;
cp = &cp[2];
} else {
base = 8;
cp = &cp[1];
}
} else
base = 10;
} else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) {
cp = &cp[2];
}
result = 0;
while (bcm_isxdigit(*cp) &&
(value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) {
result = result*base + value;
cp++;
}
if (minus)
result = (ulong)(result * -1);
if (endp)
*endp = (char *)cp;
return (result);
}
uint
bcm_atoi(char *s)
{
uint n;
n = 0;
while (bcm_isdigit(*s))
n = (n * 10) + *s++ - '0';
return (n);
}
void
deadbeef(char *p, uint len)
{
static uchar meat[] = { 0xde, 0xad, 0xbe, 0xef };
while (len-- > 0) {
*p = meat[((uint)p) & 3];
p++;
}
}
/* pretty hex print a contiguous buffer */
void
prhex(char *msg, uchar *buf, uint nbytes)
{
char line[256];
char* p;
uint i;
if (msg && (msg[0] != '\0'))
printf("%s: ", msg);
p = line;
for (i = 0; i < nbytes; i++) {
if (i % 16 == 0) {
p += sprintf(p, "%04d: ", i); /* line prefix */
}
p += sprintf(p, "%02x ", buf[i]);
if (i % 16 == 15) {
printf("%s\n", line); /* flush line */
p = line;
}
}
/* flush last partial line */
if (p != line)
printf("%s\n", line);
}
/* pretty hex print a pkt buffer chain */
void
prpkt(char *msg, void *drv, void *p0)
{
void *p;
if (msg && (msg[0] != '\0'))
printf("%s: ", msg);
for (p = p0; p; p = PKTNEXT(drv, p))
prhex(NULL, PKTDATA(drv, p), PKTLEN(drv, p));
}
/* copy a pkt buffer chain into a buffer */
uint
pktcopy(void *drv, void *p, uint offset, int len, uchar *buf)
{
uint n, ret = 0;
if (len < 0)
len = 4096; /* "infinite" */
/* skip 'offset' bytes */
for (; p && offset; p = PKTNEXT(drv, p)) {
if (offset < (uint)PKTLEN(drv, p))
break;
offset -= PKTLEN(drv, p);
}
if (!p)
return 0;
/* copy the data */
for (; p && len; p = PKTNEXT(drv, p)) {
n = MIN((uint)PKTLEN(drv, p) - offset, (uint)len);
bcopy(PKTDATA(drv, p) + offset, buf, n);
buf += n;
len -= n;
ret += n;
offset = 0;
}
return ret;
}
/* return total length of buffer chain */
uint
pkttotlen(void *drv, void *p)
{
uint total;
total = 0;
for (; p; p = PKTNEXT(drv, p))
total += PKTLEN(drv, p);
return (total);
}
uchar*
bcm_ether_ntoa(char *ea, char *buf)
{
sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x",
(uchar)ea[0]&0xff, (uchar)ea[1]&0xff, (uchar)ea[2]&0xff,
(uchar)ea[3]&0xff, (uchar)ea[4]&0xff, (uchar)ea[5]&0xff);
return (buf);
}
/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
int
bcm_ether_atoe(char *p, char *ea)
{
int i = 0;
for (;;) {
ea[i++] = (char) bcm_strtoul(p, &p, 16);
if (!*p++ || i == 6)
break;
}
return (i == 6);
}
/*
* Advance from the current 1-byte tag/1-byte length/variable-length value
* triple, to the next, returning a pointer to the next.
*/
bcm_tlv_t *
bcm_next_tlv(bcm_tlv_t *elt, int *buflen)
{
int len;
/* validate current elt */
if (*buflen < 2) {
return NULL;
}
len = elt->len;
/* validate remaining buflen */
if (*buflen >= (2 + len + 2)) {
elt = (bcm_tlv_t*)(elt->data + len);
*buflen -= (2 + len);
} else {
elt = NULL;
}
return elt;
}
/*
* Traverse a string of 1-byte tag/1-byte length/variable-length value
* triples, returning a pointer to the substring whose first element
* matches tag. Stop parsing when we see an element whose ID is greater
* than the target key.
*/
bcm_tlv_t *
bcm_parse_ordered_tlvs(void *buf, int buflen, uint key)
{
bcm_tlv_t *elt;
int totlen;
elt = (bcm_tlv_t*)buf;
totlen = buflen;
/* find tagged parameter */
while (totlen >= 2) {
uint id = elt->id;
int len = elt->len;
/* Punt if we start seeing IDs > than target key */
if (id > key)
return(NULL);
/* validate remaining totlen */
if ((id == key) && (totlen >= (len + 2)))
return (elt);
elt = (bcm_tlv_t*)((uint8*)elt + (len + 2));
totlen -= (len + 2);
}
return NULL;
}
/*
* Traverse a string of 1-byte tag/1-byte length/variable-length value
* triples, returning a pointer to the substring whose first element
* matches tag
*/
bcm_tlv_t *
bcm_parse_tlvs(void *buf, int buflen, uint key)
{
bcm_tlv_t *elt;
int totlen;
elt = (bcm_tlv_t*)buf;
totlen = buflen;
/* find tagged parameter */
while (totlen >= 2) {
int len = elt->len;
/* validate remaining totlen */
if ((elt->id == key) && (totlen >= (len + 2)))
return (elt);
elt = (bcm_tlv_t*)((uint8*)elt + (len + 2));
totlen -= (len + 2);
}
return NULL;
}
void
pktq_init(struct pktq *q, uint maxlen, bool priority)
{
q->head = q->tail = NULL;
q->priority = priority;
q->maxlen = maxlen;
q->len = 0;
}
bool
pktenq(struct pktq *q, void *p, bool lifo)
{
void *next, *prev;
/* Queue is full */
if (q->len >= q->maxlen)
return FALSE;
/* Queueing chains not allowed */
ASSERT(PKTLINK(p) == NULL);
/* Queue is empty */
if (q->tail == NULL) {
ASSERT(q->head == NULL);
q->head = q->tail = p;
}
/* Insert at head or tail */
else if (q->priority == FALSE) {
/* Insert at head (LIFO) */
if (lifo) {
PKTSETLINK(p, q->head);
q->head = p;
}
/* Insert at tail (FIFO) */
else {
ASSERT(PKTLINK(q->tail) == NULL);
PKTSETLINK(q->tail, p);
PKTSETLINK(p, NULL);
q->tail = p;
}
}
/* Insert by priority */
else {
ASSERT(q->head);
ASSERT(q->tail);
/* Shortcut to insertion at tail */
if (PKTPRIO(p) < PKTPRIO(q->tail) ||
(!lifo && PKTPRIO(p) <= PKTPRIO(q->tail))) {
prev = q->tail;
next = NULL;
}
/* Insert at head or in the middle */
else {
prev = NULL;
next = q->head;
}
/* Walk the queue */
for (; next; prev = next, next = PKTLINK(next)) {
/* Priority queue invariant */
ASSERT(!prev || PKTPRIO(prev) >= PKTPRIO(next));
/* Insert at head of string of packets of same priority (LIFO) */
if (lifo) {
if (PKTPRIO(p) >= PKTPRIO(next))
break;
}
/* Insert at tail of string of packets of same priority (FIFO) */
else {
if (PKTPRIO(p) > PKTPRIO(next))
break;
}
}
/* Insert at tail */
if (next == NULL) {
ASSERT(PKTLINK(q->tail) == NULL);
PKTSETLINK(q->tail, p);
PKTSETLINK(p, NULL);
q->tail = p;
}
/* Insert in the middle */
else if (prev) {
PKTSETLINK(prev, p);
PKTSETLINK(p, next);
}
/* Insert at head */
else {
PKTSETLINK(p, q->head);
q->head = p;
}
}
/* List invariants after insertion */
ASSERT(q->head);
ASSERT(PKTLINK(q->tail) == NULL);
q->len++;
return TRUE;
}
void*
pktdeq(struct pktq *q)
{
void *p;
if ((p = q->head)) {
ASSERT(q->tail);
q->head = PKTLINK(p);
PKTSETLINK(p, NULL);
q->len--;
if (q->head == NULL)
q->tail = NULL;
}
else {
ASSERT(q->tail == NULL);
}
return (p);
}
/*******************************************************************************
* 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 uint8 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
};
/*
* Search the name=value vars for a specific one and return its value.
* Returns NULL if not found.
*/
char*
getvar(char *vars, char *name)
{
char *s;
int len;
len = strlen(name);
/* first look in vars[] */
for (s = vars; s && *s; ) {
if ((bcmp(s, name, len) == 0) && (s[len] == '='))
return (&s[len+1]);
while (*s++)
;
}
/* then query nvram */
return (nvram_get(name));
}
/*
* Search the vars for a specific one and return its value as
* an integer. Returns 0 if not found.
*/
int
getintvar(char *vars, char *name)
{
char *val;
if ((val = getvar(vars, name)) == NULL)
return (0);
return (bcm_strtoul(val, NULL, 0));
}
/* return pointer to location of substring 'needle' in 'haystack' */
char*
bcmstrstr(char *haystack, char *needle)
{
int len, nlen;
int i;
if ((haystack == NULL) || (needle == NULL))
return (haystack);
nlen = strlen(needle);
len = strlen(haystack) - nlen + 1;
for (i = 0; i < len; i++)
if (bcmp(needle, &haystack[i], nlen) == 0)
return (&haystack[i]);
return (NULL);
}
void
bcm_mdelay(uint ms)
{
uint i;
for (i = 0; i < ms; i++) {
OSL_DELAY(1000);
}
}
#define CRC_INNER_LOOP(n, c, x) \
(c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
uint8
crc8(
uint8 *pdata, /* pointer to array of data to process */
uint nbytes, /* number of input data bytes to process */
uint8 crc /* either CRC8_INIT_VALUE or previous return value */
)
{
/* hard code the crc loop instead of using CRC_INNER_LOOP macro
* to avoid the undefined and unnecessary (uint8 >> 8) operation. */
while (nbytes-- > 0)
crc = crc8_table[(crc ^ *pdata++) & 0xff];
return crc;
}
/*******************************************************************************
* crc16
*
* Computes a crc16 over the input data using the polynomial:
*
* x^16 + x^12 +x^5 + 1
*
* The caller provides the initial value (either CRC16_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 CRC16_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 uint16 crc16_table[256] = {
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
};
uint16
crc16(
uint8 *pdata, /* pointer to array of data to process */
uint nbytes, /* number of input data bytes to process */
uint16 crc /* either CRC16_INIT_VALUE or previous return value */
)
{
while (nbytes-- > 0)
CRC_INNER_LOOP(16, crc, *pdata++);
return crc;
}
static uint32 crc32_table[256] = {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
uint32
crc32(
uint8 *pdata, /* pointer to array of data to process */
uint nbytes, /* number of input data bytes to process */
uint32 crc /* either CRC32_INIT_VALUE or previous return value */
)
{
uint8 *pend;
#ifdef __mips__
uint8 tmp[4];
ulong *tptr = (ulong *)tmp;
/* in case the beginning of the buffer isn't aligned */
pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc);
nbytes -= (pend - pdata);
while (pdata < pend)
CRC_INNER_LOOP(32, crc, *pdata++);
/* handle bulk of data as 32-bit words */
pend = pdata + (nbytes & 0xfffffffc);
while (pdata < pend) {
*tptr = (*((ulong *)pdata))++;
CRC_INNER_LOOP(32, crc, tmp[0]);
CRC_INNER_LOOP(32, crc, tmp[1]);
CRC_INNER_LOOP(32, crc, tmp[2]);
CRC_INNER_LOOP(32, crc, tmp[3]);
}
/* 1-3 bytes at end of buffer */
pend = pdata + (nbytes & 0x03);
while (pdata < pend)
CRC_INNER_LOOP(32, crc, *pdata++);
#else
pend = pdata + nbytes;
while (pdata < pend)
CRC_INNER_LOOP(32, crc, *pdata++);
#endif
return crc;
}
#ifdef notdef
#define CLEN 1499
#define CBUFSIZ (CLEN+4)
#define CNBUFS 5
void testcrc32(void)
{
uint j,k,l;
uint8 *buf;
uint len[CNBUFS];
uint32 crcr;
uint32 crc32tv[CNBUFS] =
{0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110};
ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL);
/* step through all possible alignments */
for (l=0;l<=4;l++) {
for (j=0; j<CNBUFS; j++) {
len[j] = CLEN;
for (k=0; k<len[j]; k++)
*(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff;
}
for (j=0; j<CNBUFS; j++) {
crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE);
ASSERT(crcr == crc32tv[j]);
}
}
MFREE(buf, CBUFSIZ*CNBUFS);
return;
}
#endif

View File

@ -1,841 +0,0 @@
/*
* Generic Broadcom Home Networking Division (HND) DMA module.
* This supports the following chips: BCM42xx, 44xx, 47xx .
*
* 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.
*
* $Id$
*/
#include <typedefs.h>
#include <osl.h>
#include <bcmendian.h>
#include <bcmutils.h>
struct dma_info; /* forward declaration */
#define di_t struct dma_info
#include <hnddma.h>
/* debug/trace */
#define DMA_ERROR(args)
#define DMA_TRACE(args)
/* default dma message level(if input msg_level pointer is null in dma_attach()) */
static uint dma_msg_level = 0;
#define MAXNAMEL 8
#define MAXDD (DMAMAXRINGSZ / sizeof (dmadd_t))
/* dma engine software state */
typedef struct dma_info {
hnddma_t hnddma; /* exported structure */
uint *msg_level; /* message level pointer */
char name[MAXNAMEL]; /* callers name for diag msgs */
void *drv; /* driver handle */
void *dev; /* device handle */
dmaregs_t *regs; /* dma engine registers */
dmadd_t *txd; /* pointer to chip-specific tx descriptor ring */
uint txin; /* index of next descriptor to reclaim */
uint txout; /* index of next descriptor to post */
uint txavail; /* # free tx descriptors */
void *txp[MAXDD]; /* parallel array of pointers to packets */
ulong txdpa; /* physical address of descriptor ring */
uint txdalign; /* #bytes added to alloc'd mem to align txd */
dmadd_t *rxd; /* pointer to chip-specific rx descriptor ring */
uint rxin; /* index of next descriptor to reclaim */
uint rxout; /* index of next descriptor to post */
void *rxp[MAXDD]; /* parallel array of pointers to packets */
ulong rxdpa; /* physical address of descriptor ring */
uint rxdalign; /* #bytes added to alloc'd mem to align rxd */
/* tunables */
uint ntxd; /* # tx descriptors */
uint nrxd; /* # rx descriptors */
uint rxbufsize; /* rx buffer size in bytes */
uint nrxpost; /* # rx buffers to keep posted */
uint rxoffset; /* rxcontrol offset */
uint ddoffset; /* add to get dma address of descriptor ring */
uint dataoffset; /* add to get dma address of data buffer */
} dma_info_t;
/* descriptor bumping macros */
#define TXD(x) ((x) & (di->ntxd - 1))
#define RXD(x) ((x) & (di->nrxd - 1))
#define NEXTTXD(i) TXD(i + 1)
#define PREVTXD(i) TXD(i - 1)
#define NEXTRXD(i) RXD(i + 1)
#define NTXDACTIVE(h, t) TXD(t - h)
#define NRXDACTIVE(h, t) RXD(t - h)
/* macros to convert between byte offsets and indexes */
#define B2I(bytes) ((bytes) / sizeof (dmadd_t))
#define I2B(index) ((index) * sizeof (dmadd_t))
void*
dma_attach(void *drv, void *dev, char *name, dmaregs_t *regs, uint ntxd, uint nrxd,
uint rxbufsize, uint nrxpost, uint rxoffset, uint ddoffset, uint dataoffset, uint *msg_level)
{
dma_info_t *di;
void *va;
ASSERT(ntxd <= MAXDD);
ASSERT(nrxd <= MAXDD);
/* allocate private info structure */
if ((di = MALLOC(sizeof (dma_info_t))) == NULL)
return (NULL);
bzero((char*)di, sizeof (dma_info_t));
/* set message level */
di->msg_level = msg_level ? msg_level : &dma_msg_level;
DMA_TRACE(("%s: dma_attach: drv 0x%x dev 0x%x regs 0x%x ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", name, (uint)drv, (uint)dev, (uint)regs, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, ddoffset, dataoffset));
/* make a private copy of our callers name */
strncpy(di->name, name, MAXNAMEL);
di->name[MAXNAMEL-1] = '\0';
di->drv = drv;
di->dev = dev;
di->regs = regs;
/* allocate transmit descriptor ring */
if (ntxd) {
if ((va = DMA_ALLOC_CONSISTENT(dev, (DMAMAXRINGSZ + DMARINGALIGN), &di->txdpa)) == NULL)
goto fail;
di->txd = (dmadd_t*) ROUNDUP(va, DMARINGALIGN);
di->txdalign = ((uint)di->txd - (uint)va);
di->txdpa = di->txdpa + di->txdalign;
ASSERT(ISALIGNED(di->txd, DMARINGALIGN));
}
/* allocate receive descriptor ring */
if (nrxd) {
if ((va = DMA_ALLOC_CONSISTENT(dev, (DMAMAXRINGSZ + DMARINGALIGN), &di->rxdpa)) == NULL)
goto fail;
di->rxd = (dmadd_t*) ROUNDUP(va, DMARINGALIGN);
di->rxdalign = ((uint)di->rxd - (uint)va);
di->rxdpa = di->rxdpa + di->rxdalign;
ASSERT(ISALIGNED(di->rxd, DMARINGALIGN));
}
/* save tunables */
di->ntxd = ntxd;
di->nrxd = nrxd;
di->rxbufsize = rxbufsize;
di->nrxpost = nrxpost;
di->rxoffset = rxoffset;
di->ddoffset = ddoffset;
di->dataoffset = dataoffset;
return ((void*)di);
fail:
dma_detach((void*)di);
return (NULL);
}
/* may be called with core in reset */
void
dma_detach(dma_info_t *di)
{
if (di == NULL)
return;
DMA_TRACE(("%s: dma_detach\n", di->name));
/* shouldn't be here if descriptors are unreclaimed */
ASSERT(di->txin == di->txout);
ASSERT(di->rxin == di->rxout);
/* free dma descriptor rings */
if (di->txd)
DMA_FREE_CONSISTENT(di->dev, (void *)((uint)di->txd - di->txdalign), (DMAMAXRINGSZ + DMARINGALIGN), di->txdpa);
if (di->rxd)
DMA_FREE_CONSISTENT(di->dev, (void *)((uint)di->rxd - di->rxdalign), (DMAMAXRINGSZ + DMARINGALIGN), di->rxdpa);
/* free our private info structure */
MFREE((void*)di, sizeof (dma_info_t));
}
void
dma_txreset(dma_info_t *di)
{
uint32 status;
DMA_TRACE(("%s: dma_txreset\n", di->name));
/* suspend tx DMA first */
W_REG(&di->regs->xmtcontrol, XC_SE);
SPINWAIT((status = (R_REG(&di->regs->xmtstatus) & XS_XS_MASK)) != XS_XS_DISABLED &&
status != XS_XS_IDLE &&
status != XS_XS_STOPPED,
10000);
W_REG(&di->regs->xmtcontrol, 0);
SPINWAIT((status = (R_REG(&di->regs->xmtstatus) & XS_XS_MASK)) != XS_XS_DISABLED,
10000);
if (status != XS_XS_DISABLED) {
DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name));
}
/* wait for the last transaction to complete */
OSL_DELAY(300);
}
void
dma_rxreset(dma_info_t *di)
{
uint32 status;
DMA_TRACE(("%s: dma_rxreset\n", di->name));
W_REG(&di->regs->rcvcontrol, 0);
SPINWAIT((status = (R_REG(&di->regs->rcvstatus) & RS_RS_MASK)) != RS_RS_DISABLED,
10000);
if (status != RS_RS_DISABLED) {
DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name));
}
}
void
dma_txinit(dma_info_t *di)
{
DMA_TRACE(("%s: dma_txinit\n", di->name));
di->txin = di->txout = 0;
di->txavail = di->ntxd - 1;
/* clear tx descriptor ring */
BZERO_SM((void*)di->txd, (di->ntxd * sizeof (dmadd_t)));
W_REG(&di->regs->xmtcontrol, XC_XE);
W_REG(&di->regs->xmtaddr, (di->txdpa + di->ddoffset));
}
bool
dma_txenabled(dma_info_t *di)
{
uint32 xc;
/* If the chip is dead, it is not enabled :-) */
xc = R_REG(&di->regs->xmtcontrol);
return ((xc != 0xffffffff) && (xc & XC_XE));
}
void
dma_txsuspend(dma_info_t *di)
{
DMA_TRACE(("%s: dma_txsuspend\n", di->name));
OR_REG(&di->regs->xmtcontrol, XC_SE);
}
void
dma_txresume(dma_info_t *di)
{
DMA_TRACE(("%s: dma_txresume\n", di->name));
AND_REG(&di->regs->xmtcontrol, ~XC_SE);
}
bool
dma_txsuspended(dma_info_t *di)
{
if (!(R_REG(&di->regs->xmtcontrol) & XC_SE))
return 0;
if ((R_REG(&di->regs->xmtstatus) & XS_XS_MASK) != XS_XS_IDLE)
return 0;
OSL_DELAY(2);
return ((R_REG(&di->regs->xmtstatus) & XS_XS_MASK) == XS_XS_IDLE);
}
bool
dma_txstopped(dma_info_t *di)
{
return ((R_REG(&di->regs->xmtstatus) & XS_XS_MASK) == XS_XS_STOPPED);
}
bool
dma_rxstopped(dma_info_t *di)
{
return ((R_REG(&di->regs->rcvstatus) & RS_RS_MASK) == RS_RS_STOPPED);
}
void
dma_fifoloopbackenable(dma_info_t *di)
{
DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
OR_REG(&di->regs->xmtcontrol, XC_LE);
}
void
dma_rxinit(dma_info_t *di)
{
DMA_TRACE(("%s: dma_rxinit\n", di->name));
di->rxin = di->rxout = 0;
/* clear rx descriptor ring */
BZERO_SM((void*)di->rxd, (di->nrxd * sizeof (dmadd_t)));
dma_rxenable(di);
W_REG(&di->regs->rcvaddr, (di->rxdpa + di->ddoffset));
}
void
dma_rxenable(dma_info_t *di)
{
DMA_TRACE(("%s: dma_rxenable\n", di->name));
W_REG(&di->regs->rcvcontrol, ((di->rxoffset << RC_RO_SHIFT) | RC_RE));
}
bool
dma_rxenabled(dma_info_t *di)
{
uint32 rc;
rc = R_REG(&di->regs->rcvcontrol);
return ((rc != 0xffffffff) && (rc & RC_RE));
}
/*
* The BCM47XX family supports full 32bit dma engine buffer addressing so
* dma buffers can cross 4 Kbyte page boundaries.
*/
int
dma_txfast(dma_info_t *di, void *p0, uint32 coreflags)
{
void *p, *next;
uchar *data;
uint len;
uint txout;
uint32 ctrl;
uint32 pa;
DMA_TRACE(("%s: dma_txfast\n", di->name));
txout = di->txout;
ctrl = 0;
/*
* Walk the chain of packet buffers
* allocating and initializing transmit descriptor entries.
*/
for (p = p0; p; p = next) {
data = PKTDATA(di->drv, p);
len = PKTLEN(di->drv, p);
next = PKTNEXT(di->drv, p);
/* return nonzero if out of tx descriptors */
if (NEXTTXD(txout) == di->txin)
goto outoftxd;
if (len == 0)
continue;
/* get physical address of buffer start */
pa = (uint32) DMA_MAP(di->dev, data, len, DMA_TX, p);
/* build the descriptor control value */
ctrl = len & CTRL_BC_MASK;
ctrl |= coreflags;
if (p == p0)
ctrl |= CTRL_SOF;
if (next == NULL)
ctrl |= (CTRL_IOC | CTRL_EOF);
if (txout == (di->ntxd - 1))
ctrl |= CTRL_EOT;
/* init the tx descriptor */
W_SM(&di->txd[txout].ctrl, BUS_SWAP32(ctrl));
W_SM(&di->txd[txout].addr, BUS_SWAP32(pa + di->dataoffset));
ASSERT(di->txp[txout] == NULL);
txout = NEXTTXD(txout);
}
/* if last txd eof not set, fix it */
if (!(ctrl & CTRL_EOF))
W_SM(&di->txd[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF));
/* save the packet */
di->txp[PREVTXD(txout)] = p0;
/* bump the tx descriptor index */
di->txout = txout;
/* kick the chip */
W_REG(&di->regs->xmtptr, I2B(txout));
/* tx flow control */
di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
return (0);
outoftxd:
DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name));
PKTFREE(di->drv, p0, TRUE);
di->txavail = 0;
di->hnddma.txnobuf++;
return (-1);
}
#define PAGESZ 4096
#define PAGEBASE(x) ((uint)(x) & ~4095)
/*
* Just like above except go through the extra effort of splitting
* buffers that cross 4Kbyte boundaries into multiple tx descriptors.
*/
int
dma_tx(dma_info_t *di, void *p0, uint32 coreflags)
{
void *p, *next;
uchar *data;
uint plen, len;
uchar *page, *start, *end;
uint txout;
uint32 ctrl;
uint32 pa;
DMA_TRACE(("%s: dma_tx\n", di->name));
txout = di->txout;
ctrl = 0;
/*
* Walk the chain of packet buffers
* splitting those that cross 4 Kbyte boundaries
* allocating and initializing transmit descriptor entries.
*/
for (p = p0; p; p = next) {
data = PKTDATA(di->drv, p);
plen = PKTLEN(di->drv, p);
next = PKTNEXT(di->drv, p);
if (plen == 0)
continue;
for (page = (uchar*)PAGEBASE(data);
page <= (uchar*)PAGEBASE(data + plen - 1);
page += PAGESZ) {
/* return nonzero if out of tx descriptors */
if (NEXTTXD(txout) == di->txin)
goto outoftxd;
start = (page == (uchar*)PAGEBASE(data))? data: page;
end = (page == (uchar*)PAGEBASE(data + plen))?
(data + plen): (page + PAGESZ);
len = end - start;
/* build the descriptor control value */
ctrl = len & CTRL_BC_MASK;
ctrl |= coreflags;
if ((p == p0) && (start == data))
ctrl |= CTRL_SOF;
if ((next == NULL) && (end == (data + plen)))
ctrl |= (CTRL_IOC | CTRL_EOF);
if (txout == (di->ntxd - 1))
ctrl |= CTRL_EOT;
/* get physical address of buffer start */
pa = (uint32) DMA_MAP(di->dev, start, len, DMA_TX, p);
/* init the tx descriptor */
W_SM(&di->txd[txout].ctrl, BUS_SWAP32(ctrl));
W_SM(&di->txd[txout].addr, BUS_SWAP32(pa + di->dataoffset));
ASSERT(di->txp[txout] == NULL);
txout = NEXTTXD(txout);
}
}
/* if last txd eof not set, fix it */
if (!(ctrl & CTRL_EOF))
W_SM(&di->txd[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF));
/* save the packet */
di->txp[PREVTXD(txout)] = p0;
/* bump the tx descriptor index */
di->txout = txout;
/* kick the chip */
W_REG(&di->regs->xmtptr, I2B(txout));
/* tx flow control */
di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
return (0);
outoftxd:
DMA_ERROR(("%s: dma_tx: out of txds\n", di->name));
PKTFREE(di->drv, p0, TRUE);
di->txavail = 0;
di->hnddma.txnobuf++;
return (-1);
}
/* returns a pointer to the next frame received, or NULL if there are no more */
void*
dma_rx(dma_info_t *di)
{
void *p;
uint len;
int skiplen = 0;
while ((p = dma_getnextrxp(di, FALSE))) {
/* skip giant packets which span multiple rx descriptors */
if (skiplen > 0) {
skiplen -= di->rxbufsize;
if (skiplen < 0)
skiplen = 0;
PKTFREE(di->drv, p, FALSE);
continue;
}
len = ltoh16(*(uint16*)(PKTDATA(di->drv, p)));
DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
/* bad frame length check */
if (len > (di->rxbufsize - di->rxoffset)) {
DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len));
if (len > 0)
skiplen = len - (di->rxbufsize - di->rxoffset);
PKTFREE(di->drv, p, FALSE);
di->hnddma.rxgiants++;
continue;
}
/* set actual length */
PKTSETLEN(di->drv, p, (di->rxoffset + len));
break;
}
return (p);
}
/* post receive buffers */
void
dma_rxfill(dma_info_t *di)
{
void *p;
uint rxin, rxout;
uint ctrl;
uint n;
uint i;
uint32 pa;
uint rxbufsize;
/*
* Determine how many receive buffers we're lacking
* from the full complement, allocate, initialize,
* and post them, then update the chip rx lastdscr.
*/
rxin = di->rxin;
rxout = di->rxout;
rxbufsize = di->rxbufsize;
n = di->nrxpost - NRXDACTIVE(rxin, rxout);
DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
for (i = 0; i < n; i++) {
if ((p = PKTGET(di->drv, rxbufsize, FALSE)) == NULL) {
DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name));
di->hnddma.rxnobuf++;
break;
}
*(uint32*)(OSL_UNCACHED(PKTDATA(di->drv, p))) = 0;
pa = (uint32) DMA_MAP(di->dev, PKTDATA(di->drv, p), rxbufsize, DMA_RX, p);
ASSERT(ISALIGNED(pa, 4));
/* save the free packet pointer */
ASSERT(di->rxp[rxout] == NULL);
di->rxp[rxout] = p;
/* prep the descriptor control value */
ctrl = rxbufsize;
if (rxout == (di->nrxd - 1))
ctrl |= CTRL_EOT;
/* init the rx descriptor */
W_SM(&di->rxd[rxout].ctrl, BUS_SWAP32(ctrl));
W_SM(&di->rxd[rxout].addr, BUS_SWAP32(pa + di->dataoffset));
rxout = NEXTRXD(rxout);
}
di->rxout = rxout;
/* update the chip lastdscr pointer */
W_REG(&di->regs->rcvptr, I2B(rxout));
}
void
dma_txreclaim(dma_info_t *di, bool forceall)
{
void *p;
DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
while ((p = dma_getnexttxp(di, forceall)))
PKTFREE(di->drv, p, TRUE);
}
/*
* Reclaim next completed txd (txds if using chained buffers) and
* return associated packet.
* If 'force' is true, reclaim txd(s) and return associated packet
* regardless of the value of the hardware "curr" pointer.
*/
void*
dma_getnexttxp(dma_info_t *di, bool forceall)
{
uint start, end, i;
void *txp;
DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
txp = NULL;
start = di->txin;
if (forceall)
end = di->txout;
else
end = B2I(R_REG(&di->regs->xmtstatus) & XS_CD_MASK);
if ((start == 0) && (end > di->txout))
goto bogus;
for (i = start; i != end && !txp; i = NEXTTXD(i)) {
DMA_UNMAP(di->dev, (BUS_SWAP32(R_SM(&di->txd[i].addr)) - di->dataoffset),
(BUS_SWAP32(R_SM(&di->txd[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]);
W_SM(&di->txd[i].addr, 0xdeadbeef);
txp = di->txp[i];
di->txp[i] = NULL;
}
di->txin = i;
/* tx flow control */
di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
return (txp);
bogus:
/*
DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n",
start, end, di->txout, forceall));
*/
return (NULL);
}
/* like getnexttxp but no reclaim */
void*
dma_peeknexttxp(dma_info_t *di)
{
uint end, i;
end = B2I(R_REG(&di->regs->xmtstatus) & XS_CD_MASK);
for (i = di->txin; i != end; i = NEXTTXD(i))
if (di->txp[i])
return (di->txp[i]);
return (NULL);
}
void
dma_rxreclaim(dma_info_t *di)
{
void *p;
DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
while ((p = dma_getnextrxp(di, TRUE)))
PKTFREE(di->drv, p, FALSE);
}
void *
dma_getnextrxp(dma_info_t *di, bool forceall)
{
uint i;
void *rxp;
/* if forcing, dma engine must be disabled */
ASSERT(!forceall || !dma_rxenabled(di));
i = di->rxin;
/* return if no packets posted */
if (i == di->rxout)
return (NULL);
/* ignore curr if forceall */
if (!forceall && (i == B2I(R_REG(&di->regs->rcvstatus) & RS_CD_MASK)))
return (NULL);
/* get the packet pointer that corresponds to the rx descriptor */
rxp = di->rxp[i];
ASSERT(rxp);
di->rxp[i] = NULL;
/* clear this packet from the descriptor ring */
DMA_UNMAP(di->dev, (BUS_SWAP32(R_SM(&di->rxd[i].addr)) - di->dataoffset),
di->rxbufsize, DMA_RX, rxp);
W_SM(&di->rxd[i].addr, 0xdeadbeef);
di->rxin = NEXTRXD(i);
return (rxp);
}
char*
dma_dumptx(dma_info_t *di, char *buf)
{
buf += sprintf(buf, "txd 0x%lx txdpa 0x%lx txp 0x%lx txin %d txout %d txavail %d\n",
(ulong)di->txd, di->txdpa, (ulong)di->txp, di->txin, di->txout, di->txavail);
buf += sprintf(buf, "xmtcontrol 0x%x xmtaddr 0x%x xmtptr 0x%x xmtstatus 0x%x\n",
R_REG(&di->regs->xmtcontrol),
R_REG(&di->regs->xmtaddr),
R_REG(&di->regs->xmtptr),
R_REG(&di->regs->xmtstatus));
return (buf);
}
char*
dma_dumprx(dma_info_t *di, char *buf)
{
buf += sprintf(buf, "rxd 0x%lx rxdpa 0x%lx rxp 0x%lx rxin %d rxout %d\n",
(ulong)di->rxd, di->rxdpa, (ulong)di->rxp, di->rxin, di->rxout);
buf += sprintf(buf, "rcvcontrol 0x%x rcvaddr 0x%x rcvptr 0x%x rcvstatus 0x%x\n",
R_REG(&di->regs->rcvcontrol),
R_REG(&di->regs->rcvaddr),
R_REG(&di->regs->rcvptr),
R_REG(&di->regs->rcvstatus));
return (buf);
}
char*
dma_dump(dma_info_t *di, char *buf)
{
buf = dma_dumptx(di, buf);
buf = dma_dumprx(di, buf);
return (buf);
}
uint
dma_getvar(dma_info_t *di, char *name)
{
if (!strcmp(name, "&txavail"))
return ((uint) &di->txavail);
else {
ASSERT(0);
}
return (0);
}
void
dma_txblock(dma_info_t *di)
{
di->txavail = 0;
}
void
dma_txunblock(dma_info_t *di)
{
di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
}
uint
dma_txactive(dma_info_t *di)
{
return (NTXDACTIVE(di->txin, di->txout));
}
/*
* Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
*/
void
dma_txrotate(di_t *di)
{
uint ad;
uint nactive;
uint rot;
uint old, new;
uint32 w;
uint first, last;
ASSERT(dma_txsuspended(di));
nactive = dma_txactive(di);
ad = B2I((R_REG(&di->regs->xmtstatus) & XS_AD_MASK) >> XS_AD_SHIFT);
rot = TXD(ad - di->txin);
ASSERT(rot < di->ntxd);
/* full-ring case is a lot harder - don't worry about this */
if (rot >= (di->ntxd - nactive)) {
DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
return;
}
first = di->txin;
last = PREVTXD(di->txout);
/* move entries starting at last and moving backwards to first */
for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
new = TXD(old + rot);
/*
* Move the tx dma descriptor.
* EOT is set only in the last entry in the ring.
*/
w = R_SM(&di->txd[old].ctrl) & ~CTRL_EOT;
if (new == (di->ntxd - 1))
w |= CTRL_EOT;
W_SM(&di->txd[new].ctrl, w);
W_SM(&di->txd[new].addr, R_SM(&di->txd[old].addr));
/* zap the old tx dma descriptor address field */
W_SM(&di->txd[old].addr, 0xdeadbeef);
/* move the corresponding txp[] entry */
ASSERT(di->txp[new] == NULL);
di->txp[new] = di->txp[old];
di->txp[old] = NULL;
}
/* update txin and txout */
di->txin = ad;
di->txout = TXD(di->txout + rot);
di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
/* kick the chip */
W_REG(&di->regs->xmtptr, I2B(di->txout));
}

View File

@ -1,465 +0,0 @@
/*
* Linux OS Independent Layer
*
* 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.
*
* $Id$
*/
#define LINUX_OSL
#include <typedefs.h>
#include <bcmendian.h>
#include <linuxver.h>
#include <linux_osl.h>
#include <bcmutils.h>
#include <linux/delay.h>
#ifdef mips
#include <asm/paccess.h>
#endif
#include <pcicfg.h>
#define PCI_CFG_RETRY 10
void*
osl_pktget(void *drv, uint len, bool send)
{
struct sk_buff *skb;
if ((skb = dev_alloc_skb(len)) == NULL)
return (NULL);
skb_put(skb, len);
/* ensure the cookie field is cleared */
PKTSETCOOKIE(skb, NULL);
return ((void*) skb);
}
void
osl_pktfree(void *p)
{
struct sk_buff *skb, *nskb;
skb = (struct sk_buff*) p;
/* perversion: we use skb->next to chain multi-skb packets */
while (skb) {
nskb = skb->next;
skb->next = NULL;
if (skb->destructor) {
/* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */
dev_kfree_skb_any(skb);
} else {
/* can free immediately (even in_irq()) if destructor does not exist */
dev_kfree_skb(skb);
}
skb = nskb;
}
}
uint32
osl_pci_read_config(void *loc, uint offset, uint size)
{
struct pci_dev *pdev;
uint val;
uint retry=PCI_CFG_RETRY;
/* only 4byte access supported */
ASSERT(size == 4);
pdev = (struct pci_dev*)loc;
do {
pci_read_config_dword(pdev, offset, &val);
if (val != 0xffffffff)
break;
} while (retry--);
return (val);
}
void
osl_pci_write_config(void *loc, uint offset, uint size, uint val)
{
struct pci_dev *pdev;
uint retry=PCI_CFG_RETRY;
/* only 4byte access supported */
ASSERT(size == 4);
pdev = (struct pci_dev*)loc;
do {
pci_write_config_dword(pdev, offset, val);
if (offset!=PCI_BAR0_WIN)
break;
if (osl_pci_read_config(loc,offset,size) == val)
break;
} while (retry--);
}
static void
osl_pcmcia_attr(void *osh, uint offset, char *buf, int size, bool write)
{
}
void
osl_pcmcia_read_attr(void *osh, uint offset, void *buf, int size)
{
osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE);
}
void
osl_pcmcia_write_attr(void *osh, uint offset, void *buf, int size)
{
osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE);
}
#if defined(BINOSL)
void
osl_assert(char *exp, char *file, int line)
{
char tempbuf[255];
sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line);
panic(tempbuf);
}
void*
osl_malloc(uint size)
{
return (kmalloc(size, GFP_ATOMIC));
}
void
osl_mfree(void *addr, uint size)
{
kfree(addr);
}
uint
osl_malloced(void)
{
#ifdef MODULE
return malloced;
#else
return 0;
#endif
}
#endif /* defined(BCMDBG) || defined(BINOSL) */
/*
* BINOSL selects the slightly slower function-call-based binary compatible osl.
*/
#ifdef BINOSL
int
osl_printf(const char *format, ...)
{
va_list args;
char buf[1024];
int len;
/* sprintf into a local buffer because there *is* no "vprintk()".. */
va_start(args, format);
len = vsprintf(buf, format, args);
va_end(args);
if (len > sizeof (buf)) {
printk("osl_printf: buffer overrun\n");
return (0);
}
return (printk(buf));
}
int
osl_sprintf(char *buf, const char *format, ...)
{
va_list args;
int rc;
va_start(args, format);
rc = vsprintf(buf, format, args);
va_end(args);
return (rc);
}
int
osl_strcmp(const char *s1, const char *s2)
{
return (strcmp(s1, s2));
}
int
osl_strncmp(const char *s1, const char *s2, uint n)
{
return (strncmp(s1, s2, n));
}
int
osl_strlen(char *s)
{
return (strlen(s));
}
char*
osl_strcpy(char *d, const char *s)
{
return (strcpy(d, s));
}
char*
osl_strncpy(char *d, const char *s, uint n)
{
return (strncpy(d, s, n));
}
void
bcopy(const void *src, void *dst, int len)
{
memcpy(dst, src, len);
}
int
bcmp(const void *b1, const void *b2, int len)
{
return (memcmp(b1, b2, len));
}
void
bzero(void *b, int len)
{
memset(b, '\0', len);
}
uint32
osl_readl(volatile uint32 *r)
{
return (readl(r));
}
uint16
osl_readw(volatile uint16 *r)
{
return (readw(r));
}
uint8
osl_readb(volatile uint8 *r)
{
return (readb(r));
}
void
osl_writel(uint32 v, volatile uint32 *r)
{
writel(v, r);
}
void
osl_writew(uint16 v, volatile uint16 *r)
{
writew(v, r);
}
void
osl_writeb(uint8 v, volatile uint8 *r)
{
writeb(v, r);
}
void *
osl_uncached(void *va)
{
#ifdef mips
return ((void*)KSEG1ADDR(va));
#else
return ((void*)va);
#endif
}
uint
osl_getcycles(void)
{
uint cycles;
#if defined(mips)
cycles = read_c0_count() * 2;
#elif defined(__i386__)
rdtscl(cycles);
#else
cycles = 0;
#endif
return cycles;
}
void *
osl_reg_map(uint32 pa, uint size)
{
return (ioremap_nocache((unsigned long)pa, (unsigned long)size));
}
void
osl_reg_unmap(void *va)
{
iounmap(va);
}
int
osl_busprobe(uint32 *val, uint32 addr)
{
#ifdef mips
return get_dbe(*val, (uint32*)addr);
#else
*val = readl(addr);
return 0;
#endif
}
void*
osl_dma_alloc_consistent(void *dev, uint size, ulong *pap)
{
return (pci_alloc_consistent((struct pci_dev*)dev, size, (dma_addr_t*)pap));
}
void
osl_dma_free_consistent(void *dev, void *va, uint size, ulong pa)
{
pci_free_consistent((struct pci_dev*)dev, size, va, (dma_addr_t)pa);
}
uint
osl_dma_map(void *dev, void *va, uint size, int direction)
{
int dir;
dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
return (pci_map_single(dev, va, size, dir));
}
void
osl_dma_unmap(void *dev, uint pa, uint size, int direction)
{
int dir;
dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
pci_unmap_single(dev, (uint32)pa, size, dir);
}
void
osl_delay(uint usec)
{
udelay(usec);
}
uchar*
osl_pktdata(void *drv, void *skb)
{
return (((struct sk_buff*)skb)->data);
}
uint
osl_pktlen(void *drv, void *skb)
{
return (((struct sk_buff*)skb)->len);
}
uint
osl_pktheadroom(void *drv, void *skb)
{
return (uint) skb_headroom((struct sk_buff *) skb);
}
uint
osl_pkttailroom(void *drv, void *skb)
{
return (uint) skb_tailroom((struct sk_buff *) skb);
}
void*
osl_pktnext(void *drv, void *skb)
{
return (((struct sk_buff*)skb)->next);
}
void
osl_pktsetnext(void *skb, void *x)
{
((struct sk_buff*)skb)->next = (struct sk_buff*)x;
}
void
osl_pktsetlen(void *drv, void *skb, uint len)
{
__skb_trim((struct sk_buff*)skb, len);
}
uchar*
osl_pktpush(void *drv, void *skb, int bytes)
{
return (skb_push((struct sk_buff*)skb, bytes));
}
uchar*
osl_pktpull(void *drv, void *skb, int bytes)
{
return (skb_pull((struct sk_buff*)skb, bytes));
}
void*
osl_pktdup(void *drv, void *skb)
{
return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC));
}
void*
osl_pktcookie(void *skb)
{
return ((void*)((struct sk_buff*)skb)->csum);
}
void
osl_pktsetcookie(void *skb, void *x)
{
((struct sk_buff*)skb)->csum = (uint)x;
}
void*
osl_pktlink(void *skb)
{
return (((struct sk_buff*)skb)->prev);
}
void
osl_pktsetlink(void *skb, void *x)
{
((struct sk_buff*)skb)->prev = (struct sk_buff*)x;
}
uint
osl_pktprio(void *skb)
{
return (((struct sk_buff*)skb)->priority);
}
void
osl_pktsetprio(void *skb, uint x)
{
((struct sk_buff*)skb)->priority = x;
}
#endif /* BINOSL */

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +0,0 @@
#!/bin/sh
#
# 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.
#
# $Id$
#
cat <<EOF
#include <linux/config.h>
#include <linux/module.h>
EOF
for file in $* ; do
${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p'
done

View File

@ -1,59 +0,0 @@
#
# Makefile for the Broadcom wl driver
#
# 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.
#
# $Id$
#
O_TARGET := wl.o
WL_OBJS := wl_linux.o wlc.o d11ucode.o wlc_phy.o wlc_rate.o wlc_led.o wlc_security.o rc4.o tkhash.o bcmwpa.o
INSUP_OBJS := aes.o aeskeywrap.o hmac.o md5.o passhash.o prf.o rijndael-alg-fst.o sha1.o
# Alternate ioctl interfaces
#ifeq ($(CONFIG_NET_WIRELESS),y)
#WL_OBJS += wlc_cmn_ioctl.o
#endif
ifeq ($(CONFIG_WL_OID),y)
WL_OBJS += wl_oid.o
endif
ifeq ($(CONFIG_WL_STA),y)
WL_OBJS += $(INSUP_OBJS)
endif
# Prefix driver variants
WL_APOBJS := $(foreach obj,$(WL_OBJS),ap_$(obj))
WL_STAOBJS := $(foreach obj,$(WL_OBJS) wlc_sup.o,sta_$(obj))
WL_APSTAOBJS := $(foreach obj,$(WL_OBJS) wlc_sup.o,apsta_$(obj))
ifneq ($(CONFIG_WL_STA),y)
WL_APSTAOBJS += $(foreach obj,$(INSUP_OBJS), apsta_$(obj))
endif
# Either or both
ifeq ($(CONFIG_WL_AP),y)
AP := AP
endif
ifeq ($(CONFIG_WL_STA),y)
STA := STA
endif
# Build all variants as modules but link only one of them
export-objs :=
obj-y := $(WL_$(AP)$(STA)OBJS)
obj-m := $(O_TARGET)
variant-objs := $(WL_APOBJS) $(WL_STAOBJS) $(WL_APSTAOBJS)
EXTRA_CFLAGS += -DDMA
include $(TOPDIR)/Rules.make

View File

@ -1,345 +0,0 @@
/* Low-level parallel port routines for the ASUS WL-500g built-in port
*
* Author: Nuno Grilo <nuno.grilo@netcabo.pt>
* Based on parport_pc source
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/parport.h>
#include <linux/parport_pc.h>
#define SPLINK_ADDRESS 0xBF800010
#undef DEBUG
#ifdef DEBUG
#define DPRINTK printk
#else
#define DPRINTK(stuff...)
#endif
/* __parport_splink_frob_control differs from parport_splink_frob_control in that
* it doesn't do any extra masking. */
static __inline__ unsigned char __parport_splink_frob_control (struct parport *p,
unsigned char mask,
unsigned char val)
{
struct parport_pc_private *priv = p->physport->private_data;
unsigned char *io = (unsigned char *) p->base;
unsigned char ctr = priv->ctr;
#ifdef DEBUG_PARPORT
printk (KERN_DEBUG
"__parport_splink_frob_control(%02x,%02x): %02x -> %02x\n",
mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable);
#endif
ctr = (ctr & ~mask) ^ val;
ctr &= priv->ctr_writable; /* only write writable bits. */
*(io+2) = ctr;
priv->ctr = ctr; /* Update soft copy */
return ctr;
}
static void parport_splink_data_forward (struct parport *p)
{
DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n");
__parport_splink_frob_control (p, 0x20, 0);
}
static void parport_splink_data_reverse (struct parport *p)
{
DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n");
__parport_splink_frob_control (p, 0x20, 0x20);
}
/*
static void parport_splink_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
DPRINTK(KERN_DEBUG "parport_splink: IRQ handler called\n");
parport_generic_irq(irq, (struct parport *) dev_id, regs);
}
*/
static void parport_splink_enable_irq(struct parport *p)
{
DPRINTK(KERN_DEBUG "parport_splink: parport_splink_enable_irq called\n");
__parport_splink_frob_control (p, 0x10, 0x10);
}
static void parport_splink_disable_irq(struct parport *p)
{
DPRINTK(KERN_DEBUG "parport_splink: parport_splink_disable_irq called\n");
__parport_splink_frob_control (p, 0x10, 0);
}
static void parport_splink_init_state(struct pardevice *dev, struct parport_state *s)
{
DPRINTK(KERN_DEBUG "parport_splink: parport_splink_init_state called\n");
s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
if (dev->irq_func &&
dev->port->irq != PARPORT_IRQ_NONE)
/* Set ackIntEn */
s->u.pc.ctr |= 0x10;
}
static void parport_splink_save_state(struct parport *p, struct parport_state *s)
{
const struct parport_pc_private *priv = p->physport->private_data;
DPRINTK(KERN_DEBUG "parport_splink: parport_splink_save_state called\n");
s->u.pc.ctr = priv->ctr;
}
static void parport_splink_restore_state(struct parport *p, struct parport_state *s)
{
struct parport_pc_private *priv = p->physport->private_data;
unsigned char *io = (unsigned char *) p->base;
unsigned char ctr = s->u.pc.ctr;
DPRINTK(KERN_DEBUG "parport_splink: parport_splink_restore_state called\n");
*(io+2) = ctr;
priv->ctr = ctr;
}
static void parport_splink_setup_interrupt(void) {
return;
}
static void parport_splink_write_data(struct parport *p, unsigned char d) {
DPRINTK(KERN_DEBUG "parport_splink: write data called\n");
unsigned char *io = (unsigned char *) p->base;
*io = d;
}
static unsigned char parport_splink_read_data(struct parport *p) {
DPRINTK(KERN_DEBUG "parport_splink: read data called\n");
unsigned char *io = (unsigned char *) p->base;
return *io;
}
static void parport_splink_write_control(struct parport *p, unsigned char d)
{
const unsigned char wm = (PARPORT_CONTROL_STROBE |
PARPORT_CONTROL_AUTOFD |
PARPORT_CONTROL_INIT |
PARPORT_CONTROL_SELECT);
DPRINTK(KERN_DEBUG "parport_splink: write control called\n");
/* Take this out when drivers have adapted to the newer interface. */
if (d & 0x20) {
printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n",
p->name, p->cad->name);
parport_splink_data_reverse (p);
}
__parport_splink_frob_control (p, wm, d & wm);
}
static unsigned char parport_splink_read_control(struct parport *p)
{
const unsigned char wm = (PARPORT_CONTROL_STROBE |
PARPORT_CONTROL_AUTOFD |
PARPORT_CONTROL_INIT |
PARPORT_CONTROL_SELECT);
DPRINTK(KERN_DEBUG "parport_splink: read control called\n");
const struct parport_pc_private *priv = p->physport->private_data;
return priv->ctr & wm; /* Use soft copy */
}
static unsigned char parport_splink_frob_control (struct parport *p, unsigned char mask,
unsigned char val)
{
const unsigned char wm = (PARPORT_CONTROL_STROBE |
PARPORT_CONTROL_AUTOFD |
PARPORT_CONTROL_INIT |
PARPORT_CONTROL_SELECT);
DPRINTK(KERN_DEBUG "parport_splink: frob control called\n");
/* Take this out when drivers have adapted to the newer interface. */
if (mask & 0x20) {
printk (KERN_DEBUG "%s (%s): use data_%s for this!\n",
p->name, p->cad->name,
(val & 0x20) ? "reverse" : "forward");
if (val & 0x20)
parport_splink_data_reverse (p);
else
parport_splink_data_forward (p);
}
/* Restrict mask and val to control lines. */
mask &= wm;
val &= wm;
return __parport_splink_frob_control (p, mask, val);
}
static unsigned char parport_splink_read_status(struct parport *p)
{
DPRINTK(KERN_DEBUG "parport_splink: read status called\n");
unsigned char *io = (unsigned char *) p->base;
return *(io+1);
}
static void parport_splink_inc_use_count(void)
{
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
}
static void parport_splink_dec_use_count(void)
{
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
}
static struct parport_operations parport_splink_ops =
{
parport_splink_write_data,
parport_splink_read_data,
parport_splink_write_control,
parport_splink_read_control,
parport_splink_frob_control,
parport_splink_read_status,
parport_splink_enable_irq,
parport_splink_disable_irq,
parport_splink_data_forward,
parport_splink_data_reverse,
parport_splink_init_state,
parport_splink_save_state,
parport_splink_restore_state,
parport_splink_inc_use_count,
parport_splink_dec_use_count,
parport_ieee1284_epp_write_data,
parport_ieee1284_epp_read_data,
parport_ieee1284_epp_write_addr,
parport_ieee1284_epp_read_addr,
parport_ieee1284_ecp_write_data,
parport_ieee1284_ecp_read_data,
parport_ieee1284_ecp_write_addr,
parport_ieee1284_write_compat,
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte,
};
/* --- Initialisation code -------------------------------- */
static struct parport *parport_splink_probe_port (unsigned long int base)
{
struct parport_pc_private *priv;
struct parport_operations *ops;
struct parport *p;
if (check_mem_region(base, 3)) {
printk (KERN_DEBUG "parport (0x%lx): iomem region not available\n", base);
return NULL;
}
priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL);
if (!priv) {
printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base);
return NULL;
}
ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
if (!ops) {
printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n",
base);
kfree (priv);
return NULL;
}
memcpy (ops, &parport_splink_ops, sizeof (struct parport_operations));
priv->ctr = 0xc;
priv->ctr_writable = 0xff;
if (!(p = parport_register_port(base, PARPORT_IRQ_NONE,
PARPORT_DMA_NONE, ops))) {
printk (KERN_DEBUG "parport (0x%lx): registration failed!\n",
base);
kfree (priv);
kfree (ops);
return NULL;
}
p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
p->size = (p->modes & PARPORT_MODE_EPP)?8:3;
p->private_data = priv;
parport_proc_register(p);
request_mem_region (p->base, 3, p->name);
/* Done probing. Now put the port into a sensible start-up state. */
parport_splink_write_data(p, 0);
parport_splink_data_forward (p);
/* Now that we've told the sharing engine about the port, and
found out its characteristics, let the high-level drivers
know about it. */
parport_announce_port (p);
DPRINTK(KERN_DEBUG "parport (0x%lx): init ok!\n",
base);
return p;
}
static void parport_splink_unregister_port(struct parport *p) {
struct parport_pc_private *priv = p->private_data;
struct parport_operations *ops = p->ops;
if (p->irq != PARPORT_IRQ_NONE)
free_irq(p->irq, p);
release_mem_region(p->base, 3);
parport_proc_unregister(p);
kfree (priv);
parport_unregister_port(p);
kfree (ops);
}
int parport_splink_init(void)
{
int ret;
DPRINTK(KERN_DEBUG "parport_splink init called\n");
parport_splink_setup_interrupt();
ret = !parport_splink_probe_port(SPLINK_ADDRESS);
return ret;
}
void parport_splink_cleanup(void) {
struct parport *p = parport_enumerate(), *tmp;
DPRINTK(KERN_DEBUG "parport_splink cleanup called\n");
if (p->size) {
if (p->modes & PARPORT_MODE_PCSPP) {
while(p) {
tmp = p->next;
parport_splink_unregister_port(p);
p = tmp;
}
}
}
}
MODULE_AUTHOR("Nuno Grilo <nuno.grilo@netcabo.pt>");
MODULE_DESCRIPTION("Parport Driver for ASUS WL-500g router builtin Port");
MODULE_SUPPORTED_DEVICE("ASUS WL-500g builtin Parallel Port");
MODULE_LICENSE("GPL");
module_init(parport_splink_init)
module_exit(parport_splink_cleanup)

View File

@ -1,912 +0,0 @@
/*
*
* bcm47xx pcmcia driver
*
* 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.
*
* Based on sa1100_generic.c from www.handhelds.org,
* and au1000_generic.c from oss.sgi.com.
*
* $Id$
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/config.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/tqueue.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/bus_ops.h>
#include "cs_internal.h"
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <typedefs.h>
#include <bcm4710.h>
#include <sbextif.h>
#include "bcm4710pcmcia.h"
#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
#endif
MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm47xx Socket Controller");
/* This structure maintains housekeeping state for each socket, such
* as the last known values of the card detect pins, or the Card Services
* callback value associated with the socket:
*/
static struct bcm47xx_pcmcia_socket *pcmcia_socket;
static int socket_count;
/* Returned by the low-level PCMCIA interface: */
static struct pcmcia_low_level *pcmcia_low_level;
/* Event poll timer structure */
static struct timer_list poll_timer;
/* Prototypes for routines which are used internally: */
static int bcm47xx_pcmcia_driver_init(void);
static void bcm47xx_pcmcia_driver_shutdown(void);
static void bcm47xx_pcmcia_task_handler(void *data);
static void bcm47xx_pcmcia_poll_event(unsigned long data);
static void bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
static struct tq_struct bcm47xx_pcmcia_task;
#ifdef CONFIG_PROC_FS
static int bcm47xx_pcmcia_proc_status(char *buf, char **start,
off_t pos, int count, int *eof, void *data);
#endif
/* Prototypes for operations which are exported to the
* in-kernel PCMCIA core:
*/
static int bcm47xx_pcmcia_init(unsigned int sock);
static int bcm47xx_pcmcia_suspend(unsigned int sock);
static int bcm47xx_pcmcia_register_callback(unsigned int sock,
void (*handler)(void *, unsigned int), void *info);
static int bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap);
static int bcm47xx_pcmcia_get_status(unsigned int sock, u_int *value);
static int bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state);
static int bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state);
static int bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *io);
static int bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *io);
static int bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *mem);
static int bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *mem);
#ifdef CONFIG_PROC_FS
static void bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base);
#endif
static struct pccard_operations bcm47xx_pcmcia_operations = {
bcm47xx_pcmcia_init,
bcm47xx_pcmcia_suspend,
bcm47xx_pcmcia_register_callback,
bcm47xx_pcmcia_inquire_socket,
bcm47xx_pcmcia_get_status,
bcm47xx_pcmcia_get_socket,
bcm47xx_pcmcia_set_socket,
bcm47xx_pcmcia_get_io_map,
bcm47xx_pcmcia_set_io_map,
bcm47xx_pcmcia_get_mem_map,
bcm47xx_pcmcia_set_mem_map,
#ifdef CONFIG_PROC_FS
bcm47xx_pcmcia_proc_setup
#endif
};
/*
* bcm47xx_pcmcia_driver_init()
*
* This routine performs a basic sanity check to ensure that this
* kernel has been built with the appropriate board-specific low-level
* PCMCIA support, performs low-level PCMCIA initialization, registers
* this socket driver with Card Services, and then spawns the daemon
* thread which is the real workhorse of the socket driver.
*
* Please see linux/Documentation/arm/SA1100/PCMCIA for more information
* on the low-level kernel interface.
*
* Returns: 0 on success, -1 on error
*/
static int __init bcm47xx_pcmcia_driver_init(void)
{
servinfo_t info;
struct pcmcia_init pcmcia_init;
struct pcmcia_state state;
unsigned int i;
unsigned long tmp;
printk("\nBCM47XX PCMCIA (CS release %s)\n", CS_RELEASE);
CardServices(GetCardServicesInfo, &info);
if (info.Revision != CS_RELEASE_CODE) {
printk(KERN_ERR "Card Services release codes do not match\n");
return -1;
}
#ifdef CONFIG_BCM4710
pcmcia_low_level=&bcm4710_pcmcia_ops;
#else
#error Unsupported Broadcom BCM47XX board.
#endif
pcmcia_init.handler=bcm47xx_pcmcia_interrupt;
if ((socket_count = pcmcia_low_level->init(&pcmcia_init)) < 0) {
printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
return -EIO;
} else {
printk("\t%d PCMCIA sockets initialized.\n", socket_count);
}
pcmcia_socket =
kmalloc(sizeof(struct bcm47xx_pcmcia_socket) * socket_count,
GFP_KERNEL);
memset(pcmcia_socket, 0,
sizeof(struct bcm47xx_pcmcia_socket) * socket_count);
if (!pcmcia_socket) {
printk(KERN_ERR "Card Services can't get memory \n");
return -1;
}
for (i = 0; i < socket_count; i++) {
if (pcmcia_low_level->socket_state(i, &state) < 0) {
printk(KERN_ERR "Unable to get PCMCIA status\n");
return -EIO;
}
pcmcia_socket[i].k_state = state;
pcmcia_socket[i].cs_state.csc_mask = SS_DETECT;
if (i == 0) {
pcmcia_socket[i].virt_io =
(unsigned long)ioremap_nocache(EXTIF_PCMCIA_IOBASE(BCM4710_EXTIF), 0x1000);
/* Substract ioport base which gets added by in/out */
pcmcia_socket[i].virt_io -= mips_io_port_base;
pcmcia_socket[i].phys_attr =
(unsigned long)EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF);
pcmcia_socket[i].phys_mem =
(unsigned long)EXTIF_PCMCIA_MEMBASE(BCM4710_EXTIF);
} else {
printk(KERN_ERR "bcm4710: socket 1 not supported\n");
return 1;
}
}
/* Only advertise as many sockets as we can detect: */
if (register_ss_entry(socket_count, &bcm47xx_pcmcia_operations) < 0) {
printk(KERN_ERR "Unable to register socket service routine\n");
return -ENXIO;
}
/* Start the event poll timer.
* It will reschedule by itself afterwards.
*/
bcm47xx_pcmcia_poll_event(0);
DEBUG(1, "bcm4710: initialization complete\n");
return 0;
}
module_init(bcm47xx_pcmcia_driver_init);
/*
* bcm47xx_pcmcia_driver_shutdown()
*
* Invokes the low-level kernel service to free IRQs associated with this
* socket controller and reset GPIO edge detection.
*/
static void __exit bcm47xx_pcmcia_driver_shutdown(void)
{
int i;
del_timer_sync(&poll_timer);
unregister_ss_entry(&bcm47xx_pcmcia_operations);
pcmcia_low_level->shutdown();
flush_scheduled_tasks();
for (i = 0; i < socket_count; i++) {
if (pcmcia_socket[i].virt_io)
iounmap((void *)pcmcia_socket[i].virt_io);
if (pcmcia_socket[i].phys_attr)
iounmap((void *)pcmcia_socket[i].phys_attr);
if (pcmcia_socket[i].phys_mem)
iounmap((void *)pcmcia_socket[i].phys_mem);
}
DEBUG(1, "bcm4710: shutdown complete\n");
}
module_exit(bcm47xx_pcmcia_driver_shutdown);
/*
* bcm47xx_pcmcia_init()
* We perform all of the interesting initialization tasks in
* bcm47xx_pcmcia_driver_init().
*
* Returns: 0
*/
static int bcm47xx_pcmcia_init(unsigned int sock)
{
DEBUG(1, "%s(): initializing socket %u\n", __FUNCTION__, sock);
return 0;
}
/*
* bcm47xx_pcmcia_suspend()
*
* We don't currently perform any actions on a suspend.
*
* Returns: 0
*/
static int bcm47xx_pcmcia_suspend(unsigned int sock)
{
DEBUG(1, "%s(): suspending socket %u\n", __FUNCTION__, sock);
return 0;
}
/*
* bcm47xx_pcmcia_events()
*
* Helper routine to generate a Card Services event mask based on
* state information obtained from the kernel low-level PCMCIA layer
* in a recent (and previous) sampling. Updates `prev_state'.
*
* Returns: an event mask for the given socket state.
*/
static inline unsigned
bcm47xx_pcmcia_events(struct pcmcia_state *state,
struct pcmcia_state *prev_state,
unsigned int mask, unsigned int flags)
{
unsigned int events=0;
if (state->bvd1 != prev_state->bvd1) {
DEBUG(3, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);
events |= mask & (flags & SS_IOCARD) ? SS_STSCHG : SS_BATDEAD;
}
if (state->bvd2 != prev_state->bvd2) {
DEBUG(3, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);
events |= mask & (flags & SS_IOCARD) ? 0 : SS_BATWARN;
}
if (state->detect != prev_state->detect) {
DEBUG(3, "%s(): card detect value %u\n", __FUNCTION__, state->detect);
events |= mask & SS_DETECT;
}
if (state->ready != prev_state->ready) {
DEBUG(3, "%s(): card ready value %u\n", __FUNCTION__, state->ready);
events |= mask & ((flags & SS_IOCARD) ? 0 : SS_READY);
}
if (events != 0) {
DEBUG(2, "events: %s%s%s%s%s\n",
(events & SS_DETECT) ? "DETECT " : "",
(events & SS_READY) ? "READY " : "",
(events & SS_BATDEAD) ? "BATDEAD " : "",
(events & SS_BATWARN) ? "BATWARN " : "",
(events & SS_STSCHG) ? "STSCHG " : "");
}
*prev_state=*state;
return events;
}
/*
* bcm47xx_pcmcia_task_handler()
*
* Processes serviceable socket events using the "eventd" thread context.
*
* Event processing (specifically, the invocation of the Card Services event
* callback) occurs in this thread rather than in the actual interrupt
* handler due to the use of scheduling operations in the PCMCIA core.
*/
static void bcm47xx_pcmcia_task_handler(void *data)
{
struct pcmcia_state state;
int i, events, irq_status;
DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
for (i = 0; i < socket_count; i++) {
if ((irq_status = pcmcia_low_level->socket_state(i, &state)) < 0)
printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n");
events = bcm47xx_pcmcia_events(&state,
&pcmcia_socket[i].k_state,
pcmcia_socket[i].cs_state.csc_mask,
pcmcia_socket[i].cs_state.flags);
if (pcmcia_socket[i].handler != NULL) {
pcmcia_socket[i].handler(pcmcia_socket[i].handler_info,
events);
}
}
}
static struct tq_struct bcm47xx_pcmcia_task = {
routine: bcm47xx_pcmcia_task_handler
};
/*
* bcm47xx_pcmcia_poll_event()
*
* Let's poll for events in addition to IRQs since IRQ only is unreliable...
*/
static void bcm47xx_pcmcia_poll_event(unsigned long dummy)
{
DEBUG(4, "%s(): polling for events\n", __FUNCTION__);
poll_timer.function = bcm47xx_pcmcia_poll_event;
poll_timer.expires = jiffies + BCM47XX_PCMCIA_POLL_PERIOD;
add_timer(&poll_timer);
schedule_task(&bcm47xx_pcmcia_task);
}
/*
* bcm47xx_pcmcia_interrupt()
*
* Service routine for socket driver interrupts (requested by the
* low-level PCMCIA init() operation via bcm47xx_pcmcia_thread()).
*
* The actual interrupt-servicing work is performed by
* bcm47xx_pcmcia_task(), largely because the Card Services event-
* handling code performs scheduling operations which cannot be
* executed from within an interrupt context.
*/
static void
bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
{
DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
schedule_task(&bcm47xx_pcmcia_task);
}
/*
* bcm47xx_pcmcia_register_callback()
*
* Implements the register_callback() operation for the in-kernel
* PCMCIA service (formerly SS_RegisterCallback in Card Services). If
* the function pointer `handler' is not NULL, remember the callback
* location in the state for `sock', and increment the usage counter
* for the driver module. (The callback is invoked from the interrupt
* service routine, bcm47xx_pcmcia_interrupt(), to notify Card Services
* of interesting events.) Otherwise, clear the callback pointer in the
* socket state and decrement the module usage count.
*
* Returns: 0
*/
static int
bcm47xx_pcmcia_register_callback(unsigned int sock,
void (*handler)(void *, unsigned int), void *info)
{
if (handler == NULL) {
pcmcia_socket[sock].handler = NULL;
MOD_DEC_USE_COUNT;
} else {
MOD_INC_USE_COUNT;
pcmcia_socket[sock].handler = handler;
pcmcia_socket[sock].handler_info = info;
}
return 0;
}
/*
* bcm47xx_pcmcia_inquire_socket()
*
* Implements the inquire_socket() operation for the in-kernel PCMCIA
* service (formerly SS_InquireSocket in Card Services). Of note is
* the setting of the SS_CAP_PAGE_REGS bit in the `features' field of
* `cap' to "trick" Card Services into tolerating large "I/O memory"
* addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory
* resource database check. (Mapped memory is set up within the socket
* driver itself.)
*
* In conjunction with the STATIC_MAP capability is a new field,
* `io_offset', recommended by David Hinds. Rather than go through
* the SetIOMap interface (which is not quite suited for communicating
* window locations up from the socket driver), we just pass up
* an offset which is applied to client-requested base I/O addresses
* in alloc_io_space().
*
* Returns: 0 on success, -1 if no pin has been configured for `sock'
*/
static int
bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
{
struct pcmcia_irq_info irq_info;
if (sock >= socket_count) {
printk(KERN_ERR "bcm47xx: socket %u not configured\n", sock);
return -1;
}
/* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
* force_low argument to validate_mem() in rsrc_mgr.c -- since in
* general, the mapped * addresses of the PCMCIA memory regions
* will not be within 0xffff, setting force_low would be
* undesirable.
*
* SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
* resource database; we instead pass up physical address ranges
* and allow other parts of Card Services to deal with remapping.
*
* SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
* not 32-bit CardBus devices.
*/
cap->features = (SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
irq_info.sock = sock;
irq_info.irq = -1;
if (pcmcia_low_level->get_irq_info(&irq_info) < 0) {
printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock);
return -1;
}
cap->irq_mask = 0;
cap->map_size = PAGE_SIZE;
cap->pci_irq = irq_info.irq;
cap->io_offset = pcmcia_socket[sock].virt_io;
return 0;
}
/*
* bcm47xx_pcmcia_get_status()
*
* Implements the get_status() operation for the in-kernel PCMCIA
* service (formerly SS_GetStatus in Card Services). Essentially just
* fills in bits in `status' according to internal driver state or
* the value of the voltage detect chipselect register.
*
* As a debugging note, during card startup, the PCMCIA core issues
* three set_socket() commands in a row the first with RESET deasserted,
* the second with RESET asserted, and the last with RESET deasserted
* again. Following the third set_socket(), a get_status() command will
* be issued. The kernel is looking for the SS_READY flag (see
* setup_socket(), reset_socket(), and unreset_socket() in cs.c).
*
* Returns: 0
*/
static int
bcm47xx_pcmcia_get_status(unsigned int sock, unsigned int *status)
{
struct pcmcia_state state;
if ((pcmcia_low_level->socket_state(sock, &state)) < 0) {
printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
return -1;
}
pcmcia_socket[sock].k_state = state;
*status = state.detect ? SS_DETECT : 0;
*status |= state.ready ? SS_READY : 0;
/* The power status of individual sockets is not available
* explicitly from the hardware, so we just remember the state
* and regurgitate it upon request:
*/
*status |= pcmcia_socket[sock].cs_state.Vcc ? SS_POWERON : 0;
if (pcmcia_socket[sock].cs_state.flags & SS_IOCARD)
*status |= state.bvd1 ? SS_STSCHG : 0;
else {
if (state.bvd1 == 0)
*status |= SS_BATDEAD;
else if (state.bvd2 == 0)
*status |= SS_BATWARN;
}
*status |= state.vs_3v ? SS_3VCARD : 0;
*status |= state.vs_Xv ? SS_XVCARD : 0;
DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n",
(*status&SS_DETECT)?"DETECT ":"",
(*status&SS_READY)?"READY ":"",
(*status&SS_BATDEAD)?"BATDEAD ":"",
(*status&SS_BATWARN)?"BATWARN ":"",
(*status&SS_POWERON)?"POWERON ":"",
(*status&SS_STSCHG)?"STSCHG ":"",
(*status&SS_3VCARD)?"3VCARD ":"",
(*status&SS_XVCARD)?"XVCARD ":"");
return 0;
}
/*
* bcm47xx_pcmcia_get_socket()
*
* Implements the get_socket() operation for the in-kernel PCMCIA
* service (formerly SS_GetSocket in Card Services). Not a very
* exciting routine.
*
* Returns: 0
*/
static int
bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
{
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
/* This information was given to us in an earlier call to set_socket(),
* so we're just regurgitating it here:
*/
*state = pcmcia_socket[sock].cs_state;
return 0;
}
/*
* bcm47xx_pcmcia_set_socket()
*
* Implements the set_socket() operation for the in-kernel PCMCIA
* service (formerly SS_SetSocket in Card Services). We more or
* less punt all of this work and let the kernel handle the details
* of power configuration, reset, &c. We also record the value of
* `state' in order to regurgitate it to the PCMCIA core later.
*
* Returns: 0
*/
static int
bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
{
struct pcmcia_configure configure;
DEBUG(2, "\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
"\tVcc %d Vpp %d irq %d\n",
(state->csc_mask == 0) ? "<NONE>" : "",
(state->csc_mask & SS_DETECT) ? "DETECT " : "",
(state->csc_mask & SS_READY) ? "READY " : "",
(state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "",
(state->csc_mask & SS_BATWARN) ? "BATWARN " : "",
(state->csc_mask & SS_STSCHG) ? "STSCHG " : "",
(state->flags == 0) ? "<NONE>" : "",
(state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "",
(state->flags & SS_IOCARD) ? "IOCARD " : "",
(state->flags & SS_RESET) ? "RESET " : "",
(state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "",
(state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "",
state->Vcc, state->Vpp, state->io_irq);
configure.sock = sock;
configure.vcc = state->Vcc;
configure.vpp = state->Vpp;
configure.output = (state->flags & SS_OUTPUT_ENA) ? 1 : 0;
configure.speaker = (state->flags & SS_SPKR_ENA) ? 1 : 0;
configure.reset = (state->flags & SS_RESET) ? 1 : 0;
if (pcmcia_low_level->configure_socket(&configure) < 0) {
printk(KERN_ERR "Unable to configure socket %u\n", sock);
return -1;
}
pcmcia_socket[sock].cs_state = *state;
return 0;
}
/*
* bcm47xx_pcmcia_get_io_map()
*
* Implements the get_io_map() operation for the in-kernel PCMCIA
* service (formerly SS_GetIOMap in Card Services). Just returns an
* I/O map descriptor which was assigned earlier by a set_io_map().
*
* Returns: 0 on success, -1 if the map index was out of range
*/
static int
bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
{
DEBUG(2, "bcm47xx_pcmcia_get_io_map: sock %d\n", sock);
if (map->map >= MAX_IO_WIN) {
printk(KERN_ERR "%s(): map (%d) out of range\n",
__FUNCTION__, map->map);
return -1;
}
*map = pcmcia_socket[sock].io_map[map->map];
return 0;
}
/*
* bcm47xx_pcmcia_set_io_map()
*
* Implements the set_io_map() operation for the in-kernel PCMCIA
* service (formerly SS_SetIOMap in Card Services). We configure
* the map speed as requested, but override the address ranges
* supplied by Card Services.
*
* Returns: 0 on success, -1 on error
*/
int
bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
{
unsigned int speed;
unsigned long start;
DEBUG(2, "\tmap %u speed %u\n\tstart 0x%08lx stop 0x%08lx\n"
"\tflags: %s%s%s%s%s%s%s%s\n",
map->map, map->speed, map->start, map->stop,
(map->flags == 0) ? "<NONE>" : "",
(map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
(map->flags & MAP_16BIT) ? "16BIT " : "",
(map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
(map->flags & MAP_0WS) ? "0WS " : "",
(map->flags & MAP_WRPROT) ? "WRPROT " : "",
(map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "",
(map->flags & MAP_PREFETCH) ? "PREFETCH " : "");
if (map->map >= MAX_IO_WIN) {
printk(KERN_ERR "%s(): map (%d) out of range\n",
__FUNCTION__, map->map);
return -1;
}
if (map->flags & MAP_ACTIVE) {
speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_IO_SPEED;
pcmcia_socket[sock].speed_io = speed;
}
start = map->start;
if (map->stop == 1) {
map->stop = PAGE_SIZE - 1;
}
map->start = pcmcia_socket[sock].virt_io;
map->stop = map->start + (map->stop - start);
pcmcia_socket[sock].io_map[map->map] = *map;
DEBUG(2, "set_io_map %d start %x stop %x\n",
map->map, map->start, map->stop);
return 0;
}
/*
* bcm47xx_pcmcia_get_mem_map()
*
* Implements the get_mem_map() operation for the in-kernel PCMCIA
* service (formerly SS_GetMemMap in Card Services). Just returns a
* memory map descriptor which was assigned earlier by a
* set_mem_map() request.
*
* Returns: 0 on success, -1 if the map index was out of range
*/
static int
bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
{
DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
if (map->map >= MAX_WIN) {
printk(KERN_ERR "%s(): map (%d) out of range\n",
__FUNCTION__, map->map);
return -1;
}
*map = pcmcia_socket[sock].mem_map[map->map];
return 0;
}
/*
* bcm47xx_pcmcia_set_mem_map()
*
* Implements the set_mem_map() operation for the in-kernel PCMCIA
* service (formerly SS_SetMemMap in Card Services). We configure
* the map speed as requested, but override the address ranges
* supplied by Card Services.
*
* Returns: 0 on success, -1 on error
*/
static int
bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
{
unsigned int speed;
unsigned long start;
u_long flags;
if (map->map >= MAX_WIN) {
printk(KERN_ERR "%s(): map (%d) out of range\n",
__FUNCTION__, map->map);
return -1;
}
DEBUG(2, "\tmap %u speed %u\n\tsys_start %#lx\n"
"\tsys_stop %#lx\n\tcard_start %#x\n"
"\tflags: %s%s%s%s%s%s%s%s\n",
map->map, map->speed, map->sys_start, map->sys_stop,
map->card_start, (map->flags == 0) ? "<NONE>" : "",
(map->flags & MAP_ACTIVE) ? "ACTIVE " : "",
(map->flags & MAP_16BIT) ? "16BIT " : "",
(map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "",
(map->flags & MAP_0WS) ? "0WS " : "",
(map->flags & MAP_WRPROT) ? "WRPROT " : "",
(map->flags & MAP_ATTRIB) ? "ATTRIB " : "",
(map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "");
if (map->flags & MAP_ACTIVE) {
/* When clients issue RequestMap, the access speed is not always
* properly configured:
*/
speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_MEM_SPEED;
/* TBD */
if (map->flags & MAP_ATTRIB) {
pcmcia_socket[sock].speed_attr = speed;
} else {
pcmcia_socket[sock].speed_mem = speed;
}
}
save_flags(flags);
cli();
start = map->sys_start;
if (map->sys_stop == 0)
map->sys_stop = PAGE_SIZE - 1;
if (map->flags & MAP_ATTRIB) {
map->sys_start = pcmcia_socket[sock].phys_attr +
map->card_start;
} else {
map->sys_start = pcmcia_socket[sock].phys_mem +
map->card_start;
}
map->sys_stop = map->sys_start + (map->sys_stop - start);
pcmcia_socket[sock].mem_map[map->map] = *map;
restore_flags(flags);
DEBUG(2, "set_mem_map %d start %x stop %x card_start %x\n",
map->map, map->sys_start, map->sys_stop,
map->card_start);
return 0;
}
#if defined(CONFIG_PROC_FS)
/*
* bcm47xx_pcmcia_proc_setup()
*
* Implements the proc_setup() operation for the in-kernel PCMCIA
* service (formerly SS_ProcSetup in Card Services).
*
* Returns: 0 on success, -1 on error
*/
static void
bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
{
struct proc_dir_entry *entry;
if ((entry = create_proc_entry("status", 0, base)) == NULL) {
printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
return;
}
entry->read_proc = bcm47xx_pcmcia_proc_status;
entry->data = (void *)sock;
}
/*
* bcm47xx_pcmcia_proc_status()
*
* Implements the /proc/bus/pccard/??/status file.
*
* Returns: the number of characters added to the buffer
*/
static int
bcm47xx_pcmcia_proc_status(char *buf, char **start, off_t pos,
int count, int *eof, void *data)
{
char *p = buf;
unsigned int sock = (unsigned int)data;
p += sprintf(p, "k_flags : %s%s%s%s%s%s%s\n",
pcmcia_socket[sock].k_state.detect ? "detect " : "",
pcmcia_socket[sock].k_state.ready ? "ready " : "",
pcmcia_socket[sock].k_state.bvd1 ? "bvd1 " : "",
pcmcia_socket[sock].k_state.bvd2 ? "bvd2 " : "",
pcmcia_socket[sock].k_state.wrprot ? "wrprot " : "",
pcmcia_socket[sock].k_state.vs_3v ? "vs_3v " : "",
pcmcia_socket[sock].k_state.vs_Xv ? "vs_Xv " : "");
p += sprintf(p, "status : %s%s%s%s%s%s%s%s%s\n",
pcmcia_socket[sock].k_state.detect ? "SS_DETECT " : "",
pcmcia_socket[sock].k_state.ready ? "SS_READY " : "",
pcmcia_socket[sock].cs_state.Vcc ? "SS_POWERON " : "",
pcmcia_socket[sock].cs_state.flags & SS_IOCARD ? "SS_IOCARD " : "",
(pcmcia_socket[sock].cs_state.flags & SS_IOCARD &&
pcmcia_socket[sock].k_state.bvd1) ? "SS_STSCHG " : "",
((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 &&
(pcmcia_socket[sock].k_state.bvd1 == 0)) ? "SS_BATDEAD " : "",
((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 &&
(pcmcia_socket[sock].k_state.bvd2 == 0)) ? "SS_BATWARN " : "",
pcmcia_socket[sock].k_state.vs_3v ? "SS_3VCARD " : "",
pcmcia_socket[sock].k_state.vs_Xv ? "SS_XVCARD " : "");
p += sprintf(p, "mask : %s%s%s%s%s\n",
pcmcia_socket[sock].cs_state.csc_mask & SS_DETECT ? "SS_DETECT " : "",
pcmcia_socket[sock].cs_state.csc_mask & SS_READY ? "SS_READY " : "",
pcmcia_socket[sock].cs_state.csc_mask & SS_BATDEAD ? "SS_BATDEAD " : "",
pcmcia_socket[sock].cs_state.csc_mask & SS_BATWARN ? "SS_BATWARN " : "",
pcmcia_socket[sock].cs_state.csc_mask & SS_STSCHG ? "SS_STSCHG " : "");
p += sprintf(p, "cs_flags : %s%s%s%s%s\n",
pcmcia_socket[sock].cs_state.flags & SS_PWR_AUTO ?
"SS_PWR_AUTO " : "",
pcmcia_socket[sock].cs_state.flags & SS_IOCARD ?
"SS_IOCARD " : "",
pcmcia_socket[sock].cs_state.flags & SS_RESET ?
"SS_RESET " : "",
pcmcia_socket[sock].cs_state.flags & SS_SPKR_ENA ?
"SS_SPKR_ENA " : "",
pcmcia_socket[sock].cs_state.flags & SS_OUTPUT_ENA ?
"SS_OUTPUT_ENA " : "");
p += sprintf(p, "Vcc : %d\n", pcmcia_socket[sock].cs_state.Vcc);
p += sprintf(p, "Vpp : %d\n", pcmcia_socket[sock].cs_state.Vpp);
p += sprintf(p, "irq : %d\n", pcmcia_socket[sock].cs_state.io_irq);
p += sprintf(p, "I/O : %u\n", pcmcia_socket[sock].speed_io);
p += sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr);
p += sprintf(p, "common : %u\n", pcmcia_socket[sock].speed_mem);
return p-buf;
}
#endif /* defined(CONFIG_PROC_FS) */

View File

@ -1,266 +0,0 @@
/*
* BCM4710 specific pcmcia routines.
*
* 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.
*
* $Id$
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/config.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/tqueue.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/bus_ops.h>
#include "cs_internal.h"
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <typedefs.h>
#include <bcmdevs.h>
#include <bcm4710.h>
#include <sbconfig.h>
#include <sbextif.h>
#include "bcm4710pcmcia.h"
/* Use a static var for irq dev_id */
static int bcm47xx_pcmcia_dev_id;
/* Do we think we have a card or not? */
static int bcm47xx_pcmcia_present = 0;
static void bcm4710_pcmcia_reset(void)
{
extifregs_t *eir;
unsigned long s;
uint32 out0, out1, outen;
eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t));
save_and_cli(s);
/* Use gpio7 to reset the pcmcia slot */
outen = readl(&eir->gpio[0].outen);
outen |= BCM47XX_PCMCIA_RESET;
out0 = readl(&eir->gpio[0].out);
out0 &= ~(BCM47XX_PCMCIA_RESET);
out1 = out0 | BCM47XX_PCMCIA_RESET;
writel(out0, &eir->gpio[0].out);
writel(outen, &eir->gpio[0].outen);
mdelay(1);
writel(out1, &eir->gpio[0].out);
mdelay(1);
writel(out0, &eir->gpio[0].out);
restore_flags(s);
}
static int bcm4710_pcmcia_init(struct pcmcia_init *init)
{
struct pci_dev *pdev;
extifregs_t *eir;
uint32 outen, intp, intm, tmp;
uint16 *attrsp;
int rc = 0, i;
extern unsigned long bcm4710_cpu_cycle;
if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_EXTIF, NULL))) {
printk(KERN_ERR "bcm4710_pcmcia: extif not found\n");
return -ENODEV;
}
eir = (extifregs_t *) ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
/* Initialize the pcmcia i/f: 16bit no swap */
writel(CF_EM_PCMCIA | CF_DS | CF_EN, &eir->pcmcia_config);
#ifdef notYet
/* Set the timing for memory accesses */
tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */
tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */
tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */
tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */
writel(tmp, &eir->pcmcia_memwait); /* 0x01020a0c for a 100Mhz clock */
/* Set the timing for I/O accesses */
tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */
tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */
tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */
tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */
writel(tmp, &eir->pcmcia_iowait); /* 0x01020a0c for a 100Mhz clock */
/* Set the timing for attribute accesses */
tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */
tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */
tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */
tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */
writel(tmp, &eir->pcmcia_attrwait); /* 0x01020a0c for a 100Mhz clock */
#endif
/* Make sure gpio0 and gpio5 are inputs */
outen = readl(&eir->gpio[0].outen);
outen &= ~(BCM47XX_PCMCIA_WP | BCM47XX_PCMCIA_STSCHG | BCM47XX_PCMCIA_RESET);
writel(outen, &eir->gpio[0].outen);
/* Issue a reset to the pcmcia socket */
bcm4710_pcmcia_reset();
#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS
/* Setup gpio5 to be the STSCHG interrupt */
intp = readl(&eir->gpiointpolarity);
writel(intp | BCM47XX_PCMCIA_STSCHG, &eir->gpiointpolarity); /* Active low */
intm = readl(&eir->gpiointmask);
writel(intm | BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask); /* Enable it */
#endif
DEBUG(2, "bcm4710_pcmcia after reset:\n");
DEBUG(2, "\textstatus\t= 0x%08x:\n", readl(&eir->extstatus));
DEBUG(2, "\tpcmcia_config\t= 0x%08x:\n", readl(&eir->pcmcia_config));
DEBUG(2, "\tpcmcia_memwait\t= 0x%08x:\n", readl(&eir->pcmcia_memwait));
DEBUG(2, "\tpcmcia_attrwait\t= 0x%08x:\n", readl(&eir->pcmcia_attrwait));
DEBUG(2, "\tpcmcia_iowait\t= 0x%08x:\n", readl(&eir->pcmcia_iowait));
DEBUG(2, "\tgpioin\t\t= 0x%08x:\n", readl(&eir->gpioin));
DEBUG(2, "\tgpio_outen0\t= 0x%08x:\n", readl(&eir->gpio[0].outen));
DEBUG(2, "\tgpio_out0\t= 0x%08x:\n", readl(&eir->gpio[0].out));
DEBUG(2, "\tgpiointpolarity\t= 0x%08x:\n", readl(&eir->gpiointpolarity));
DEBUG(2, "\tgpiointmask\t= 0x%08x:\n", readl(&eir->gpiointmask));
#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS
/* Request pcmcia interrupt */
rc = request_irq(BCM47XX_PCMCIA_IRQ, init->handler, SA_INTERRUPT,
"PCMCIA Interrupt", &bcm47xx_pcmcia_dev_id);
#endif
attrsp = (uint16 *)ioremap_nocache(EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF), 0x1000);
tmp = readw(&attrsp[0]);
DEBUG(2, "\tattr[0] = 0x%04x\n", tmp);
if ((tmp == 0x7fff) || (tmp == 0x7f00)) {
bcm47xx_pcmcia_present = 0;
} else {
bcm47xx_pcmcia_present = 1;
}
/* There's only one socket */
return 1;
}
static int bcm4710_pcmcia_shutdown(void)
{
extifregs_t *eir;
uint32 intm;
eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t));
/* Disable the pcmcia i/f */
writel(0, &eir->pcmcia_config);
/* Reset gpio's */
intm = readl(&eir->gpiointmask);
writel(intm & ~BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask); /* Disable it */
free_irq(BCM47XX_PCMCIA_IRQ, &bcm47xx_pcmcia_dev_id);
return 0;
}
static int
bcm4710_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
{
extifregs_t *eir;
eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t));
if (sock != 0) {
printk(KERN_ERR "bcm4710 socket_state bad sock %d\n", sock);
return -1;
}
if (bcm47xx_pcmcia_present) {
state->detect = 1;
state->ready = 1;
state->bvd1 = 1;
state->bvd2 = 1;
state->wrprot = (readl(&eir->gpioin) & BCM47XX_PCMCIA_WP) == BCM47XX_PCMCIA_WP;
state->vs_3v = 0;
state->vs_Xv = 0;
} else {
state->detect = 0;
state->ready = 0;
}
return 1;
}
static int bcm4710_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
{
if (info->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1;
info->irq = BCM47XX_PCMCIA_IRQ;
return 0;
}
static int
bcm4710_pcmcia_configure_socket(const struct pcmcia_configure *configure)
{
if (configure->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1;
DEBUG(2, "Vcc %dV Vpp %dV output %d speaker %d reset %d\n", configure->vcc,
configure->vpp, configure->output, configure->speaker, configure->reset);
if ((configure->vcc != 50) || (configure->vpp != 50)) {
printk("%s: bad Vcc/Vpp (%d:%d)\n", __FUNCTION__, configure->vcc,
configure->vpp);
}
if (configure->reset) {
/* Issue a reset to the pcmcia socket */
DEBUG(1, "%s: Reseting socket\n", __FUNCTION__);
bcm4710_pcmcia_reset();
}
return 0;
}
struct pcmcia_low_level bcm4710_pcmcia_ops = {
bcm4710_pcmcia_init,
bcm4710_pcmcia_shutdown,
bcm4710_pcmcia_socket_state,
bcm4710_pcmcia_get_irq_info,
bcm4710_pcmcia_configure_socket
};

View File

@ -1,118 +0,0 @@
/*
*
* bcm47xx pcmcia driver
*
* 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.
*
* Based on sa1100.h and include/asm-arm/arch-sa1100/pcmica.h
* from www.handhelds.org,
* and au1000_generic.c from oss.sgi.com.
*
* $Id$
*/
#if !defined(_BCM4710PCMCIA_H)
#define _BCM4710PCMCIA_H
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/bulkmem.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
/* The 47xx can only support one socket */
#define BCM47XX_PCMCIA_MAX_SOCK 1
/* In the bcm947xx gpio's are used for some pcmcia functions */
#define BCM47XX_PCMCIA_WP 0x01 /* Bit 0 is WP input */
#define BCM47XX_PCMCIA_STSCHG 0x20 /* Bit 5 is STSCHG input/interrupt */
#define BCM47XX_PCMCIA_RESET 0x80 /* Bit 7 is RESET */
#define BCM47XX_PCMCIA_IRQ 2
/* The socket driver actually works nicely in interrupt-driven form,
* so the (relatively infrequent) polling is "just to be sure."
*/
#define BCM47XX_PCMCIA_POLL_PERIOD (2 * HZ)
#define BCM47XX_PCMCIA_IO_SPEED (255)
#define BCM47XX_PCMCIA_MEM_SPEED (300)
struct pcmcia_state {
unsigned detect: 1,
ready: 1,
bvd1: 1,
bvd2: 1,
wrprot: 1,
vs_3v: 1,
vs_Xv: 1;
};
struct pcmcia_configure {
unsigned sock: 8,
vcc: 8,
vpp: 8,
output: 1,
speaker: 1,
reset: 1;
};
struct pcmcia_irq_info {
unsigned int sock;
unsigned int irq;
};
/* This structure encapsulates per-socket state which we might need to
* use when responding to a Card Services query of some kind.
*/
struct bcm47xx_pcmcia_socket {
socket_state_t cs_state;
struct pcmcia_state k_state;
unsigned int irq;
void (*handler)(void *, unsigned int);
void *handler_info;
pccard_io_map io_map[MAX_IO_WIN];
pccard_mem_map mem_map[MAX_WIN];
ioaddr_t virt_io, phys_attr, phys_mem;
unsigned short speed_io, speed_attr, speed_mem;
};
struct pcmcia_init {
void (*handler)(int irq, void *dev, struct pt_regs *regs);
};
struct pcmcia_low_level {
int (*init)(struct pcmcia_init *);
int (*shutdown)(void);
int (*socket_state)(unsigned sock, struct pcmcia_state *);
int (*get_irq_info)(struct pcmcia_irq_info *);
int (*configure_socket)(const struct pcmcia_configure *);
};
extern struct pcmcia_low_level bcm47xx_pcmcia_ops;
/* I/O pins replacing memory pins
* (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75)
*
* These signals change meaning when going from memory-only to
* memory-or-I/O interface:
*/
#define iostschg bvd1
#define iospkr bvd2
/*
* Declaration for implementation specific low_level operations.
*/
extern struct pcmcia_low_level bcm4710_pcmcia_ops;
#endif /* !defined(_BCM4710PCMCIA_H) */

View File

@ -1,91 +0,0 @@
/*
* BCM4710 address space map and definitions
* Think twice before adding to this file, this is not the kitchen sink
* These definitions are not guaranteed for all 47xx chips, only the 4710
*
* 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.
*
* $Id$
*/
#ifndef _bcm4710_h_
#define _bcm4710_h_
/* Address map */
#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */
#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */
#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */
#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */
#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */
/* Core register space */
#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */
#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */
#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */
#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */
#define BCM4710_REG_USB 0x18004000 /* USB core registers */
#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */
#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */
#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */
#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */
#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */
#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */
#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */
#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */
#define BCM4710_PROG 0x1f800000 /* Programable interface */
#define BCM4710_FLASH 0x1fc00000 /* Flash */
#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */
#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300)
#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000)
#define BCM4710_LED (BCM4710_EXTIF + 0x00900000)
#define SBFLAG_PCI 0
#define SBFLAG_ENET0 1
#define SBFLAG_ILINE20 2
#define SBFLAG_CODEC 3
#define SBFLAG_USB 4
#define SBFLAG_EXTIF 5
#define SBFLAG_ENET1 6
#ifdef CONFIG_HWSIM
#define BCM4710_TRACE(trval) do { *((int *)0xa0000f18) = (trval); } while (0)
#else
#define BCM4710_TRACE(trval)
#endif
/* BCM94702 CPCI -ExtIF used for LocalBus devs */
#define BCM94702_CPCI_RESET_ADDR BCM4710_EXTIF
#define BCM94702_CPCI_BOARDID_ADDR (BCM4710_EXTIF | 0x4000)
#define BCM94702_CPCI_DOC_ADDR (BCM4710_EXTIF | 0x6000)
#define BCM94702_DOC_ADDR BCM94702_CPCI_DOC_ADDR
#define BCM94702_CPCI_LED_ADDR (BCM4710_EXTIF | 0xc000)
#define BCM94702_CPCI_NVRAM_ADDR (BCM4710_EXTIF | 0xe000)
#define BCM94702_CPCI_NVRAM_SIZE 0x1ff0 /* 8K NVRAM : DS1743/STM48txx*/
#define BCM94702_CPCI_TOD_REG_BASE (BCM94702_CPCI_NVRAM_ADDR | 0x1ff0)
#define LED_REG(x) \
(*(volatile unsigned char *) (KSEG1ADDR(BCM94702_CPCI_LED_ADDR) + (x)))
/*
* Reset function implemented in PLD. Read or write should trigger hard reset
*/
#define SYS_HARD_RESET() \
{ for (;;) \
*( (volatile unsigned char *)\
KSEG1ADDR(BCM94702_CPCI_RESET_ADDR) ) = 0x80; \
}
#endif /* _bcm4710_h_ */

View File

@ -1,253 +0,0 @@
/*
* Broadcom device-specific manifest constants.
*
* 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.
* $Id$
*/
#ifndef _BCMDEVS_H
#define _BCMDEVS_H
/* Known PCI vendor Id's */
#define VENDOR_EPIGRAM 0xfeda
#define VENDOR_BROADCOM 0x14e4
#define VENDOR_3COM 0x10b7
#define VENDOR_NETGEAR 0x1385
#define VENDOR_DIAMOND 0x1092
#define VENDOR_DELL 0x1028
#define VENDOR_HP 0x0e11
#define VENDOR_APPLE 0x106b
/* PCI Device Id's */
#define BCM4210_DEVICE_ID 0x1072 /* never used */
#define BCM4211_DEVICE_ID 0x4211
#define BCM4230_DEVICE_ID 0x1086 /* never used */
#define BCM4231_DEVICE_ID 0x4231
#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */
#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */
#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */
#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */
#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */
#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */
#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */
#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */
#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */
#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */
#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */
#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */
#define BCM47XX_USB_ID 0x4715 /* 47xx usb */
#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */
#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */
#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */
#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */
#define BCM4610_DEVICE_ID 0x4610 /* 4610 primary function 0 */
#define BCM4610_ILINE_ID 0x4611 /* 4610 iline100 */
#define BCM4610_V90_ID 0x4612 /* 4610 v90 codec */
#define BCM4610_ENET_ID 0x4613 /* 4610 enet */
#define BCM4610_EXT_ID 0x4614 /* 4610 external i/f */
#define BCM4610_USB_ID 0x4615 /* 4610 usb */
#define BCM4402_DEVICE_ID 0x4402 /* 4402 primary function 0 */
#define BCM4402_ENET_ID 0x4402 /* 4402 enet */
#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */
#define BCM4301_DEVICE_ID 0x4301 /* 4301 primary function 0 */
#define BCM4301_D11B_ID 0x4301 /* 4301 802.11b */
#define BCM4307_DEVICE_ID 0x4307 /* 4307 primary function 0 */
#define BCM4307_V90_ID 0x4305 /* 4307 v90 codec */
#define BCM4307_ENET_ID 0x4306 /* 4307 enet */
#define BCM4307_D11B_ID 0x4307 /* 4307 802.11b */
#define BCM4306_DEVICE_ID 0x4306 /* 4306 chipcommon chipid */
#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */
#define BCM4306_D11G_ID2 0x4325
#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */
#define BCM4306_UART_ID 0x4322 /* 4306 uart */
#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */
#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */
#define BCM4309_PKG_ID 1 /* 4309 package id */
#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */
#define BCM4303_PKG_ID 2 /* 4303 package id */
#define BCM4310_DEVICE_ID 0x4310 /* 4310 chipcommon chipid */
#define BCM4310_D11B_ID 0x4311 /* 4310 802.11b */
#define BCM4310_UART_ID 0x4312 /* 4310 uart */
#define BCM4310_ENET_ID 0x4313 /* 4310 enet */
#define BCM4310_USB_ID 0x4315 /* 4310 usb */
#define BCM4704_DEVICE_ID 0x4704 /* 4704 chipcommon chipid */
#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */
#define BCM4317_DEVICE_ID 0x4317 /* 4317 chip common chipid */
#define BCM4712_DEVICE_ID 0x4712 /* 4712 chipcommon chipid */
#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */
#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */
#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */
#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */
#define SDIOH_FPGA_ID 0x4380 /* sdio host fpga */
#define BCM5365_DEVICE_ID 0x5365 /* 5365 chipcommon chipid */
/* PCMCIA vendor Id's */
#define VENDOR_BROADCOM_PCMCIA 0x02d0
/* SDIO vendor Id's */
#define VENDOR_BROADCOM_SDIO 0x00BF
/* boardflags */
#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */
#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */
#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */
#define BFL_ENETSPI 0x0010 /* This board has ephy roboswitch spi */
#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */
#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */
#define BFL_ENETVLAN 0x0100 /* This board can do vlan */
#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */
#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */
#define BFL_FEM 0x0800 /* This board supports the Front End Module */
/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
#define BOARD_GPIO_HWRAD_B 0x010 /* bit 4 is HWRAD input on 4301 */
#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */
#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */
#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
/* Bus types */
#define SB_BUS 0 /* Silicon Backplane */
#define PCI_BUS 1 /* PCI target */
#define PCMCIA_BUS 2 /* PCMCIA target */
#define SDIO_BUS 3 /* SDIO target */
/* power control defines */
#define PLL_DELAY 150 /* 150us pll on delay */
#define FREF_DELAY 200 /* 200us fref change delay */
#define MIN_SLOW_CLK 32 /* 32us Slow clock period */
/* Reference Board Types */
#define BU4710_BOARD 0x0400
#define VSIM4710_BOARD 0x0401
#define QT4710_BOARD 0x0402
#define BU4610_BOARD 0x0403
#define VSIM4610_BOARD 0x0404
#define BU4307_BOARD 0x0405
#define BCM94301CB_BOARD 0x0406
#define BCM94301PC_BOARD 0x0406 /* Pcmcia 5v card */
#define BCM94301MP_BOARD 0x0407
#define BCM94307MP_BOARD 0x0408
#define BCMAP4307_BOARD 0x0409
#define BU4309_BOARD 0x040a
#define BCM94309CB_BOARD 0x040b
#define BCM94309MP_BOARD 0x040c
#define BCM4309AP_BOARD 0x040d
#define BCM94302MP_BOARD 0x040e
#define VSIM4310_BOARD 0x040f
#define BU4711_BOARD 0x0410
#define BCM94310U_BOARD 0x0411
#define BCM94310AP_BOARD 0x0412
#define BCM94310MP_BOARD 0x0414
#define BU4306_BOARD 0x0416
#define BCM94306CB_BOARD 0x0417
#define BCM94306MP_BOARD 0x0418
#define BCM94710D_BOARD 0x041a
#define BCM94710R1_BOARD 0x041b
#define BCM94710R4_BOARD 0x041c
#define BCM94710AP_BOARD 0x041d
#define BU2050_BOARD 0x041f
#define BCM94309G_BOARD 0x0421
#define BCM94301PC3_BOARD 0x0422 /* Pcmcia 3.3v card */
#define BU4704_BOARD 0x0423
#define BU4702_BOARD 0x0424
#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */
#define BU4317_BOARD 0x0426
#define BCM94702MN_BOARD 0x0428
/* BCM4702 1U CompactPCI Board */
#define BCM94702CPCI_BOARD 0x0429
/* BCM4702 with BCM95380 VLAN Router */
#define BCM95380RR_BOARD 0x042a
/* cb4306 with SiGe PA */
#define BCM94306CBSG_BOARD 0x042b
/* mp4301 with 2050 radio */
#define BCM94301MPL_BOARD 0x042c
/* cb4306 with SiGe PA */
#define PCSG94306_BOARD 0x042d
/* bu4704 with sdram */
#define BU4704SD_BOARD 0x042e
/* Dual 11a/11g Router */
#define BCM94704AGR_BOARD 0x042f
/* 11a-only minipci */
#define BCM94308MP_BOARD 0x0430
/* BCM94317 boards */
#define BCM94317CB_BOARD 0x0440
#define BCM94317MP_BOARD 0x0441
#define BCM94317PCMCIA_BOARD 0x0442
#define BCM94317SDIO_BOARD 0x0443
#define BU4712_BOARD 0x0444
/* BCM4712 boards */
#define BCM94712AGR_BOARD 0x0445
#define BCM94712AP_BOARD 0x0446
/* BCM4702 boards */
#define CT4702AP_BOARD 0x0447
/* BRCM 4306 w/ Front End Modules */
#define BCM94306MPM 0x0450
#define BCM94306MPL 0x0453
#endif /* _BCMDEVS_H */

View File

@ -1,127 +0,0 @@
/*
* local version of endian.h - byte order defines
*
* 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.
*
* $Id$
*/
#ifndef _BCMENDIAN_H_
#define _BCMENDIAN_H_
#include <typedefs.h>
/* Byte swap a 16 bit value */
#define BCMSWAP16(val) \
((uint16)( \
(((uint16)(val) & (uint16)0x00ffU) << 8) | \
(((uint16)(val) & (uint16)0xff00U) >> 8) ))
/* Byte swap a 32 bit value */
#define BCMSWAP32(val) \
((uint32)( \
(((uint32)(val) & (uint32)0x000000ffUL) << 24) | \
(((uint32)(val) & (uint32)0x0000ff00UL) << 8) | \
(((uint32)(val) & (uint32)0x00ff0000UL) >> 8) | \
(((uint32)(val) & (uint32)0xff000000UL) >> 24) ))
static INLINE uint16
bcmswap16(uint16 val)
{
return BCMSWAP16(val);
}
static INLINE uint32
bcmswap32(uint32 val)
{
return BCMSWAP32(val);
}
/* buf - start of buffer of shorts to swap */
/* len - byte length of buffer */
static INLINE void
bcmswap16_buf(uint16 *buf, uint len)
{
len = len/2;
while(len--){
*buf = bcmswap16(*buf);
buf++;
}
}
#ifndef hton16
#ifndef IL_BIGENDIAN
#define HTON16(i) BCMSWAP16(i)
#define hton16(i) bcmswap16(i)
#define hton32(i) bcmswap32(i)
#define ntoh16(i) bcmswap16(i)
#define ntoh32(i) bcmswap32(i)
#define ltoh16(i) (i)
#define ltoh32(i) (i)
#define htol16(i) (i)
#define htol32(i) (i)
#else
#define HTON16(i) (i)
#define hton16(i) (i)
#define hton32(i) (i)
#define ntoh16(i) (i)
#define ntoh32(i) (i)
#define ltoh16(i) bcmswap16(i)
#define ltoh32(i) bcmswap32(i)
#define htol16(i) bcmswap16(i)
#define htol32(i) bcmswap32(i)
#endif
#endif
#ifndef IL_BIGENDIAN
#define ltoh16_buf(buf, i)
#define htol16_buf(buf, i)
#else
#define ltoh16_buf(buf, i) bcmswap16_buf((uint16*)buf, i)
#define htol16_buf(buf, i) bcmswap16_buf((uint16*)buf, i)
#endif
/*
* load 16-bit value from unaligned little endian byte array.
*/
static INLINE uint16
ltoh16_ua(uint8 *bytes)
{
return (bytes[1]<<8)+bytes[0];
}
/*
* load 32-bit value from unaligned little endian byte array.
*/
static INLINE uint32
ltoh32_ua(uint8 *bytes)
{
return (bytes[3]<<24)+(bytes[2]<<16)+(bytes[1]<<8)+bytes[0];
}
/*
* load 16-bit value from unaligned big(network) endian byte array.
*/
static INLINE uint16
ntoh16_ua(uint8 *bytes)
{
return (bytes[0]<<8)+bytes[1];
}
/*
* load 32-bit value from unaligned big(network) endian byte array.
*/
static INLINE uint32
ntoh32_ua(uint8 *bytes)
{
return (bytes[0]<<24)+(bytes[1]<<16)+(bytes[2]<<8)+bytes[3];
}
#endif /* _BCMENDIAN_H_ */

View File

@ -1,229 +0,0 @@
/*
* Hardware-specific definitions for
* Broadcom BCM47XX 10/100 Mbps Ethernet cores.
*
* 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.
* $Id$
*/
#ifndef _bcmenet_47xx_h_
#define _bcmenet_47xx_h_
#include <bcmdevs.h>
#include <hnddma.h>
#define BCMENET_NFILTERS 64 /* # ethernet address filter entries */
#define BCMENET_MCHASHBASE 0x200 /* multicast hash filter base address */
#define BCMENET_MCHASHSIZE 256 /* multicast hash filter size in bytes */
#define BCMENET_MAX_DMA 4096 /* chip has 12 bits of DMA addressing */
/* power management event wakeup pattern constants */
#define BCMENET_NPMP 4 /* chip supports 4 wakeup patterns */
#define BCMENET_PMPBASE 0x400 /* wakeup pattern base address */
#define BCMENET_PMPSIZE 0x80 /* 128bytes each pattern */
#define BCMENET_PMMBASE 0x600 /* wakeup mask base address */
#define BCMENET_PMMSIZE 0x10 /* 128bits each mask */
/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
#define _PADLINE(line) pad ## line
#define _XSTR(line) _PADLINE(line)
#define PAD _XSTR(__LINE__)
#endif /* PAD */
/* sometimes you just need the enet mib definitions */
#include <bcmenetmib.h>
/*
* Host Interface Registers
*/
typedef volatile struct _bcmenettregs {
/* Device and Power Control */
uint32 devcontrol;
uint32 PAD[2];
uint32 biststatus;
uint32 wakeuplength;
uint32 PAD[3];
/* Interrupt Control */
uint32 intstatus;
uint32 intmask;
uint32 gptimer;
uint32 PAD[23];
/* Ethernet MAC Address Filtering Control */
uint32 PAD[2];
uint32 enetftaddr;
uint32 enetftdata;
uint32 PAD[2];
/* Ethernet MAC Control */
uint32 emactxmaxburstlen;
uint32 emacrxmaxburstlen;
uint32 emaccontrol;
uint32 emacflowcontrol;
uint32 PAD[20];
/* DMA Lazy Interrupt Control */
uint32 intrecvlazy;
uint32 PAD[63];
/* DMA engine */
dmaregs_t dmaregs;
dmafifo_t dmafifo;
uint32 PAD[116];
/* EMAC Registers */
uint32 rxconfig;
uint32 rxmaxlength;
uint32 txmaxlength;
uint32 PAD;
uint32 mdiocontrol;
uint32 mdiodata;
uint32 emacintmask;
uint32 emacintstatus;
uint32 camdatalo;
uint32 camdatahi;
uint32 camcontrol;
uint32 enetcontrol;
uint32 txcontrol;
uint32 txwatermark;
uint32 mibcontrol;
uint32 PAD[49];
/* EMAC MIB counters */
bcmenetmib_t mib;
uint32 PAD[585];
/* Sonics SiliconBackplane config registers */
sbconfig_t sbconfig;
} bcmenetregs_t;
/* device control */
#define DC_PM ((uint32)1 << 7) /* pattern filtering enable */
#define DC_IP ((uint32)1 << 10) /* internal ephy present (rev >= 1) */
#define DC_ER ((uint32)1 << 15) /* ephy reset */
#define DC_MP ((uint32)1 << 16) /* mii phy mode enable */
#define DC_CO ((uint32)1 << 17) /* mii phy mode: enable clocks */
#define DC_PA_MASK 0x7c0000 /* mii phy mode: mdc/mdio phy address */
#define DC_PA_SHIFT 18
/* wakeup length */
#define WL_P0_MASK 0x7f /* pattern 0 */
#define WL_D0 ((uint32)1 << 7)
#define WL_P1_MASK 0x7f00 /* pattern 1 */
#define WL_P1_SHIFT 8
#define WL_D1 ((uint32)1 << 15)
#define WL_P2_MASK 0x7f0000 /* pattern 2 */
#define WL_P2_SHIFT 16
#define WL_D2 ((uint32)1 << 23)
#define WL_P3_MASK 0x7f000000 /* pattern 3 */
#define WL_P3_SHIFT 24
#define WL_D3 ((uint32)1 << 31)
/* intstatus and intmask */
#define I_PME ((uint32)1 << 6) /* power management event */
#define I_TO ((uint32)1 << 7) /* general purpose timeout */
#define I_PC ((uint32)1 << 10) /* descriptor error */
#define I_PD ((uint32)1 << 11) /* data error */
#define I_DE ((uint32)1 << 12) /* descriptor protocol error */
#define I_RU ((uint32)1 << 13) /* receive descriptor underflow */
#define I_RO ((uint32)1 << 14) /* receive fifo overflow */
#define I_XU ((uint32)1 << 15) /* transmit fifo underflow */
#define I_RI ((uint32)1 << 16) /* receive interrupt */
#define I_XI ((uint32)1 << 24) /* transmit interrupt */
#define I_EM ((uint32)1 << 26) /* emac interrupt */
#define I_MW ((uint32)1 << 27) /* mii write */
#define I_MR ((uint32)1 << 28) /* mii read */
/* emaccontrol */
#define EMC_CG ((uint32)1 << 0) /* crc32 generation enable */
#define EMC_EP ((uint32)1 << 2) /* onchip ephy: powerdown (rev >= 1) */
#define EMC_ED ((uint32)1 << 3) /* onchip ephy: energy detected (rev >= 1) */
#define EMC_LC_MASK 0xe0 /* onchip ephy: led control (rev >= 1) */
#define EMC_LC_SHIFT 5
/* emacflowcontrol */
#define EMF_RFH_MASK 0xff /* rx fifo hi water mark */
#define EMF_PG ((uint32)1 << 15) /* enable pause frame generation */
/* interrupt receive lazy */
#define IRL_TO_MASK 0x00ffffff /* timeout */
#define IRL_FC_MASK 0xff000000 /* frame count */
#define IRL_FC_SHIFT 24 /* frame count */
/* emac receive config */
#define ERC_DB ((uint32)1 << 0) /* disable broadcast */
#define ERC_AM ((uint32)1 << 1) /* accept all multicast */
#define ERC_RDT ((uint32)1 << 2) /* receive disable while transmitting */
#define ERC_PE ((uint32)1 << 3) /* promiscuous enable */
#define ERC_LE ((uint32)1 << 4) /* loopback enable */
#define ERC_FE ((uint32)1 << 5) /* enable flow control */
#define ERC_UF ((uint32)1 << 6) /* accept unicast flow control frame */
#define ERC_RF ((uint32)1 << 7) /* reject filter */
/* emac mdio control */
#define MC_MF_MASK 0x7f /* mdc frequency */
#define MC_PE ((uint32)1 << 7) /* mii preamble enable */
/* emac mdio data */
#define MD_DATA_MASK 0xffff /* r/w data */
#define MD_TA_MASK 0x30000 /* turnaround value */
#define MD_TA_SHIFT 16
#define MD_TA_VALID (2 << MD_TA_SHIFT) /* valid ta */
#define MD_RA_MASK 0x7c0000 /* register address */
#define MD_RA_SHIFT 18
#define MD_PMD_MASK 0xf800000 /* physical media device */
#define MD_PMD_SHIFT 23
#define MD_OP_MASK 0x30000000 /* opcode */
#define MD_OP_SHIFT 28
#define MD_OP_WRITE (1 << MD_OP_SHIFT) /* write op */
#define MD_OP_READ (2 << MD_OP_SHIFT) /* read op */
#define MD_SB_MASK 0xc0000000 /* start bits */
#define MD_SB_SHIFT 30
#define MD_SB_START (0x1 << MD_SB_SHIFT) /* start of frame */
/* emac intstatus and intmask */
#define EI_MII ((uint32)1 << 0) /* mii mdio interrupt */
#define EI_MIB ((uint32)1 << 1) /* mib interrupt */
#define EI_FLOW ((uint32)1 << 2) /* flow control interrupt */
/* emac cam data high */
#define CD_V ((uint32)1 << 16) /* valid bit */
/* emac cam control */
#define CC_CE ((uint32)1 << 0) /* cam enable */
#define CC_MS ((uint32)1 << 1) /* mask select */
#define CC_RD ((uint32)1 << 2) /* read */
#define CC_WR ((uint32)1 << 3) /* write */
#define CC_INDEX_MASK 0x3f0000 /* index */
#define CC_INDEX_SHIFT 16
#define CC_CB ((uint32)1 << 31) /* cam busy */
/* emac ethernet control */
#define EC_EE ((uint32)1 << 0) /* emac enable */
#define EC_ED ((uint32)1 << 1) /* emac disable */
#define EC_ES ((uint32)1 << 2) /* emac soft reset */
#define EC_EP ((uint32)1 << 3) /* external phy select */
/* emac transmit control */
#define EXC_FD ((uint32)1 << 0) /* full duplex */
#define EXC_FM ((uint32)1 << 1) /* flowmode */
#define EXC_SB ((uint32)1 << 2) /* single backoff enable */
#define EXC_SS ((uint32)1 << 3) /* small slottime */
/* emac mib control */
#define EMC_RZ ((uint32)1 << 0) /* autoclear on read */
/* sometimes you just need the enet rxheader definitions */
#include <bcmenetrxh.h>
#endif /* _bcmenet_47xx_h_ */

View File

@ -1,81 +0,0 @@
/*
* Hardware-specific MIB definition for
* Broadcom Home Networking Division
* BCM44XX and BCM47XX 10/100 Mbps Ethernet cores.
*
* 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.
* $Id$
*/
#ifndef _bcmenetmib_h_
#define _bcmenetmib_h_
/* cpp contortions to concatenate w/arg prescan */
#ifndef PAD
#define _PADLINE(line) pad ## line
#define _XSTR(line) _PADLINE(line)
#define PAD _XSTR(__LINE__)
#endif /* PAD */
/*
* EMAC MIB Registers
*/
typedef volatile struct {
uint32 tx_good_octets;
uint32 tx_good_pkts;
uint32 tx_octets;
uint32 tx_pkts;
uint32 tx_broadcast_pkts;
uint32 tx_multicast_pkts;
uint32 tx_len_64;
uint32 tx_len_65_to_127;
uint32 tx_len_128_to_255;
uint32 tx_len_256_to_511;
uint32 tx_len_512_to_1023;
uint32 tx_len_1024_to_max;
uint32 tx_jabber_pkts;
uint32 tx_oversize_pkts;
uint32 tx_fragment_pkts;
uint32 tx_underruns;
uint32 tx_total_cols;
uint32 tx_single_cols;
uint32 tx_multiple_cols;
uint32 tx_excessive_cols;
uint32 tx_late_cols;
uint32 tx_defered;
uint32 tx_carrier_lost;
uint32 tx_pause_pkts;
uint32 PAD[8];
uint32 rx_good_octets;
uint32 rx_good_pkts;
uint32 rx_octets;
uint32 rx_pkts;
uint32 rx_broadcast_pkts;
uint32 rx_multicast_pkts;
uint32 rx_len_64;
uint32 rx_len_65_to_127;
uint32 rx_len_128_to_255;
uint32 rx_len_256_to_511;
uint32 rx_len_512_to_1023;
uint32 rx_len_1024_to_max;
uint32 rx_jabber_pkts;
uint32 rx_oversize_pkts;
uint32 rx_fragment_pkts;
uint32 rx_missed_pkts;
uint32 rx_crc_align_errs;
uint32 rx_undersize;
uint32 rx_crc_errs;
uint32 rx_align_errs;
uint32 rx_symbol_errs;
uint32 rx_pause_pkts;
uint32 rx_nonpause_pkts;
} bcmenetmib_t;
#endif /* _bcmenetmib_h_ */

View File

@ -1,43 +0,0 @@
/*
* Hardware-specific Receive Data Header for the
* Broadcom Home Networking Division
* BCM44XX and BCM47XX 10/100 Mbps Ethernet cores.
*
* 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.
* $Id$
*/
#ifndef _bcmenetrxh_h_
#define _bcmenetrxh_h_
/*
* The Ethernet MAC core returns an 8-byte Receive Frame Data Header
* with every frame consisting of
* 16bits of frame length, followed by
* 16bits of EMAC rx descriptor info, followed by 32bits of undefined.
*/
typedef volatile struct {
uint16 len;
uint16 flags;
uint16 pad[12];
} bcmenetrxh_t;
#define RXHDR_LEN 28
#define RXF_L ((uint16)1 << 11) /* last buffer in a frame */
#define RXF_MISS ((uint16)1 << 7) /* received due to promisc mode */
#define RXF_BRDCAST ((uint16)1 << 6) /* dest is broadcast address */
#define RXF_MULT ((uint16)1 << 5) /* dest is multicast address */
#define RXF_LG ((uint16)1 << 4) /* frame length > rxmaxlength */
#define RXF_NO ((uint16)1 << 3) /* odd number of nibbles */
#define RXF_RXER ((uint16)1 << 2) /* receive symbol error */
#define RXF_CRC ((uint16)1 << 1) /* crc error */
#define RXF_OV ((uint16)1 << 0) /* fifo overflow */
#endif /* _bcmenetrxh_h_ */

View File

@ -1,148 +0,0 @@
/*
* NVRAM variable manipulation
*
* 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.
*
* $Id$
*/
#ifndef _bcmnvram_h_
#define _bcmnvram_h_
#ifndef _LANGUAGE_ASSEMBLY
#include <typedefs.h>
struct nvram_header {
uint32 magic;
uint32 len;
uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:27 init, mem. test 28, 29-31 reserved */
uint32 config_refresh; /* 0:15 config, 16:31 refresh */
uint32 config_ncdl; /* ncdl values for memc */
};
struct nvram_tuple {
char *name;
char *value;
struct nvram_tuple *next;
};
/*
* Initialize NVRAM access. May be unnecessary or undefined on certain
* platforms.
*/
extern int nvram_init(void *sbh);
/*
* Disable NVRAM access. May be unnecessary or undefined on certain
* platforms.
*/
extern void nvram_exit(void);
/*
* Get the value of an NVRAM variable. The pointer returned may be
* invalid after a set.
* @param name name of variable to get
* @return value of variable or NULL if undefined
*/
extern char * nvram_get(const char *name);
/*
* Get the value of an NVRAM variable.
* @param name name of variable to get
* @return value of variable or NUL if undefined
*/
#define nvram_safe_get(name) (nvram_get(name) ? : "")
#define nvram_safe_unset(name) ({ \
if(nvram_get(name)) \
nvram_unset(name); \
})
#define nvram_safe_set(name, value) ({ \
if(!nvram_get(name) || strcmp(nvram_get(name), value)) \
nvram_set(name, value); \
})
/*
* Match an NVRAM variable.
* @param name name of variable to match
* @param match value to compare against value of variable
* @return TRUE if variable is defined and its value is string equal
* to match or FALSE otherwise
*/
static INLINE int
nvram_match(char *name, char *match) {
const char *value = nvram_get(name);
return (value && !strcmp(value, match));
}
/*
* Inversely match an NVRAM variable.
* @param name name of variable to match
* @param match value to compare against value of variable
* @return TRUE if variable is defined and its value is not string
* equal to invmatch or FALSE otherwise
*/
static INLINE int
nvram_invmatch(char *name, char *invmatch) {
const char *value = nvram_get(name);
return (value && strcmp(value, invmatch));
}
/*
* Set the value of an NVRAM variable. The name and value strings are
* copied into private storage. Pointers to previously set values
* may become invalid. The new value may be immediately
* retrieved but will not be permanently stored until a commit.
* @param name name of variable to set
* @param value value of variable
* @return 0 on success and errno on failure
*/
extern int nvram_set(const char *name, const char *value);
/*
* Unset an NVRAM variable. Pointers to previously set values
* remain valid until a set.
* @param name name of variable to unset
* @return 0 on success and errno on failure
* NOTE: use nvram_commit to commit this change to flash.
*/
extern int nvram_unset(const char *name);
/*
* Commit NVRAM variables to permanent storage. All pointers to values
* may be invalid after a commit.
* NVRAM values are undefined after a commit.
* @return 0 on success and errno on failure
*/
extern int nvram_commit(void);
/*
* Get all NVRAM variables (format name=value\0 ... \0\0).
* @param buf buffer to store variables
* @param count size of buffer in bytes
* @return 0 on success and errno on failure
*/
extern int nvram_getall(char *buf, int count);
extern int file2nvram(char *filename, char *varname);
extern int nvram2file(char *varname, char *filename);
#endif /* _LANGUAGE_ASSEMBLY */
#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
#define NVRAM_VERSION 1
#define NVRAM_HEADER_SIZE 20
#define NVRAM_SPACE 0x8000
#define FLASH_BASE 0xbfc00000 /* Extif core */
#define FLASH_MIN 0x00100000 /* Minimum flash size */
#define FLASH_MAX 0x00400000 /* Maximum flash size with extif */
#endif /* _bcmnvram_h_ */

View File

@ -1,24 +0,0 @@
/*
* Misc useful routines to access NIC srom
*
* 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.
*
* $Id$
*/
#ifndef _bcmsrom_h_
#define _bcmsrom_h_
extern int srom_var_init(void *sbh, uint bus, void *curmap, void *osh, char **vars, int *count);
extern int srom_read(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf);
extern int srom_write(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf);
extern int srom_parsecis(uint8 *cis, char **vars, int *count);
#endif /* _bcmsrom_h_ */

View File

@ -1,157 +0,0 @@
/*
* Misc useful os-independent macros and functions.
*
* 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.
* $Id$
*/
#ifndef _bcmutils_h_
#define _bcmutils_h_
#ifndef MIN
#define MIN(a, b) (((a)<(b))?(a):(b))
#endif
#ifndef MAX
#define MAX(a, b) (((a)>(b))?(a):(b))
#endif
#define CEIL(x, y) (((x) + ((y)-1)) / (y))
#define ROUNDUP(x, y) ((((ulong)(x)+((y)-1))/(y))*(y))
#define ISALIGNED(a, x) (((uint)(a) & ((x)-1)) == 0)
#define ISPOWEROF2(x) ((((x)-1)&(x))==0)
#define OFFSETOF(type, member) ((uint) &((type *)0)->member)
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
/* bit map related macros */
#ifndef setbit
#define NBBY 8 /* 8 bits per byte */
#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
#endif
#define NBITS(type) (sizeof (type) * 8)
#define _BCM_U 0x01 /* upper */
#define _BCM_L 0x02 /* lower */
#define _BCM_D 0x04 /* digit */
#define _BCM_C 0x08 /* cntrl */
#define _BCM_P 0x10 /* punct */
#define _BCM_S 0x20 /* white space (space/lf/tab) */
#define _BCM_X 0x40 /* hex digit */
#define _BCM_SP 0x80 /* hard space (0x20) */
extern unsigned char bcm_ctype[];
#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)])
#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0)
#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0)
#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0)
#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0)
#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0)
#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0)
#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0)
#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0)
#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0)
#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0)
#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0)
/*
* Spin at most 'us' microseconds while 'exp' is true.
* Caller should explicitly test 'exp' when this completes
* and take appropriate error action if 'exp' is still true.
*/
#define SPINWAIT(exp, us) { \
uint countdown = (us) + 9; \
while ((exp) && (countdown >= 10)) {\
OSL_DELAY(10); \
countdown -= 10; \
} \
}
/* generic osl packet queue */
struct pktq {
void *head; /* first packet to dequeue */
void *tail; /* last packet to dequeue */
uint len; /* number of queued packets */
uint maxlen; /* maximum number of queued packets */
bool priority; /* enqueue by packet priority */
};
#define DEFAULT_QLEN 128
#define pktq_len(q) ((q)->len)
#define pktq_avail(q) ((q)->maxlen - (q)->len)
#define pktq_head(q) ((q)->head)
#define pktq_full(q) ((q)->len >= (q)->maxlen)
/* crc defines */
#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */
#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */
#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */
#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */
#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */
#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */
/* tag_ID/length/value_buffer tuple */
typedef struct bcm_tlv {
uint8 id;
uint8 len;
uint8 data[1];
} bcm_tlv_t;
/* Check that bcm_tlv_t fits into the given buflen */
#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (buflen) >= 2 + (elt)->len)
/* buffer length for ethernet address from bcm_ether_ntoa() */
#define ETHER_ADDR_STR_LEN 18
/*
* load 32-bit value from unaligned byte array
*/
#ifdef IL_BIGENDIAN
#define load32_ua(a) ((((uint8 *)(a))[0] << 24) + (((uint8 *)(a))[1] << 16) + \
(((uint8 *)(a))[2] << 8) + ((uint8 *)(a))[3])
#else
#define load32_ua(a) ((((uint8 *)(a))[3] << 24) + (((uint8 *)(a))[2] << 16) + \
(((uint8 *)(a))[1] << 8) + ((uint8 *)(a))[0])
#endif
/* externs */
extern uint bcm_atoi(char *s);
extern uchar bcm_toupper(uchar c);
extern ulong bcm_strtoul(char *cp, char **endp, uint base);
extern void deadbeef(char *p, uint len);
extern void prhex(char *msg, uchar *buf, uint len);
extern void prpkt(char *msg, void *drv, void *p0);
extern uint pktcopy(void *drv, void *p, uint offset, int len, uchar *buf);
extern uint pkttotlen(void *drv, void *);
extern uchar *bcm_ether_ntoa(char *ea, char *buf);
extern int bcm_ether_atoe(char *p, char *ea);
extern void bcm_mdelay(uint ms);
extern char *getvar(char *vars, char *name);
extern int getintvar(char *vars, char *name);
extern char *bcmstrstr(char *haystack, char *needle);
extern uint8 crc8(uint8 *p, uint nbytes, uint8 crc);
extern uint16 crc16(uint8 *p, uint nbytes, uint16 crc);
extern uint32 crc32(uint8 *p, uint nbytes, uint32 crc);
extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen);
extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key);
extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key);
extern void pktq_init(struct pktq *q, uint maxlen, bool priority);
extern bool pktenq(struct pktq *q, void *p, bool lifo);
extern void *pktdeq(struct pktq *q);
#define bcmlog(fmt, a1, a2)
#define bcmdumplog(buf, size) *buf = '\0'
#define bcmdumplogent(buf, idx) -1
#endif /* _bcmutils_h_ */

View File

@ -1,69 +0,0 @@
/*
* 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.
*
* $Id$
*
*/
#ifndef _epivers_h_
#define _epivers_h_
#ifdef linux
#include <linux/config.h>
#endif
/* Vendor Name, ASCII, 32 chars max */
#ifdef COMPANYNAME
#define HPNA_VENDOR COMPANYNAME
#else
#define HPNA_VENDOR "Broadcom Corporation"
#endif
/* Driver Date, ASCII, 32 chars max */
#define HPNA_DRV_BUILD_DATE __DATE__
/* Hardware Manufacture Date, ASCII, 32 chars max */
#define HPNA_HW_MFG_DATE "Not Specified"
/* See documentation for Device Type values, 32 values max */
#ifndef HPNA_DEV_TYPE
#if defined(CONFIG_BRCM_VJ)
#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_DISPLAY }
#elif defined(CONFIG_BCRM_93725)
#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_CM_BRIDGE, CDCF_V0_DEVICE_DISPLAY }
#else
#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_PCINIC }
#endif
#endif /* !HPNA_DEV_TYPE */
#define EPI_MAJOR_VERSION 3
#define EPI_MINOR_VERSION 60
#define EPI_RC_NUMBER 13
#define EPI_INCREMENTAL_NUMBER 0
#define EPI_BUILD_NUMBER 0
#define EPI_VERSION 3,60,13,0
#define EPI_VERSION_NUM 0x033c0d00
/* Driver Version String, ASCII, 32 chars max */
#define EPI_VERSION_STR "3.60.13.0"
#define EPI_ROUTER_VERSION_STR "3.61.13.0"
#endif /* _epivers_h_ */

View File

@ -1,58 +0,0 @@
/*
* Driver-specific socket ioctls
* used by BSD, Linux, and PSOS
* Broadcom BCM44XX 10/100Mbps Ethernet Device Driver
*
* 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.
*
* $Id$
*/
#ifndef _etsockio_h_
#define _etsockio_h_
/* THESE MUST BE CONTIGUOUS AND CONSISTENT WITH VALUES IN ETC.H */
#if defined(linux)
#define SIOCSETCUP (SIOCDEVPRIVATE + 0)
#define SIOCSETCDOWN (SIOCDEVPRIVATE + 1)
#define SIOCSETCLOOP (SIOCDEVPRIVATE + 2)
#define SIOCGETCDUMP (SIOCDEVPRIVATE + 3)
#define SIOCSETCSETMSGLEVEL (SIOCDEVPRIVATE + 4)
#define SIOCSETCPROMISC (SIOCDEVPRIVATE + 5)
#define SIOCSETCTXDOWN (SIOCDEVPRIVATE + 6) /* obsolete */
#define SIOCSETCSPEED (SIOCDEVPRIVATE + 7)
#define SIOCTXGEN (SIOCDEVPRIVATE + 8)
#define SIOCGETCPHYRD (SIOCDEVPRIVATE + 9)
#define SIOCSETCPHYWR (SIOCDEVPRIVATE + 10)
#else /* !linux */
#define SIOCSETCUP _IOWR('e', 130 + 0, struct ifreq)
#define SIOCSETCDOWN _IOWR('e', 130 + 1, struct ifreq)
#define SIOCSETCLOOP _IOWR('e', 130 + 2, struct ifreq)
#define SIOCGETCDUMP _IOWR('e', 130 + 3, struct ifreq)
#define SIOCSETCSETMSGLEVEL _IOWR('e', 130 + 4, struct ifreq)
#define SIOCSETCPROMISC _IOWR('e', 130 + 5, struct ifreq)
#define SIOCSETCTXDOWN _IOWR('e', 130 + 6, struct ifreq) /* obsolete */
#define SIOCSETCSPEED _IOWR('e', 130 + 7, struct ifreq)
#define SIOCTXGEN _IOWR('e', 130 + 8, struct ifreq)
#endif
/* arg to SIOCTXGEN */
struct txg {
uint32 num; /* number of frames to send */
uint32 delay; /* delay in microseconds between sending each */
uint32 size; /* size of ether frame to send */
uchar buf[1514]; /* starting ether frame data */
};
#endif

View File

@ -1,186 +0,0 @@
/*
* Generic Broadcom Home Networking Division (HND) DMA engine definitions.
* This supports the following chips: BCM42xx, 44xx, 47xx .
*
* 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.
* $Id$
*/
#ifndef _hnddma_h_
#define _hnddma_h_
/*
* Each DMA processor consists of a transmit channel and a receive channel.
*/
typedef volatile struct {
/* transmit channel */
uint32 xmtcontrol; /* enable, et al */
uint32 xmtaddr; /* descriptor ring base address (4K aligned) */
uint32 xmtptr; /* last descriptor posted to chip */
uint32 xmtstatus; /* current active descriptor, et al */
/* receive channel */
uint32 rcvcontrol; /* enable, et al */
uint32 rcvaddr; /* descriptor ring base address (4K aligned) */
uint32 rcvptr; /* last descriptor posted to chip */
uint32 rcvstatus; /* current active descriptor, et al */
} dmaregs_t;
typedef volatile struct {
/* diag access */
uint32 fifoaddr; /* diag address */
uint32 fifodatalow; /* low 32bits of data */
uint32 fifodatahigh; /* high 32bits of data */
uint32 pad; /* reserved */
} dmafifo_t;
/* transmit channel control */
#define XC_XE ((uint32)1 << 0) /* transmit enable */
#define XC_SE ((uint32)1 << 1) /* transmit suspend request */
#define XC_LE ((uint32)1 << 2) /* loopback enable */
#define XC_FL ((uint32)1 << 4) /* flush request */
/* transmit descriptor table pointer */
#define XP_LD_MASK 0xfff /* last valid descriptor */
/* transmit channel status */
#define XS_CD_MASK 0x0fff /* current descriptor pointer */
#define XS_XS_MASK 0xf000 /* transmit state */
#define XS_XS_SHIFT 12
#define XS_XS_DISABLED 0x0000 /* disabled */
#define XS_XS_ACTIVE 0x1000 /* active */
#define XS_XS_IDLE 0x2000 /* idle wait */
#define XS_XS_STOPPED 0x3000 /* stopped */
#define XS_XS_SUSP 0x4000 /* suspend pending */
#define XS_XE_MASK 0xf0000 /* transmit errors */
#define XS_XE_SHIFT 16
#define XS_XE_NOERR 0x00000 /* no error */
#define XS_XE_DPE 0x10000 /* descriptor protocol error */
#define XS_XE_DFU 0x20000 /* data fifo underrun */
#define XS_XE_BEBR 0x30000 /* bus error on buffer read */
#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */
#define XS_AD_MASK 0xfff00000 /* active descriptor */
#define XS_AD_SHIFT 20
/* receive channel control */
#define RC_RE ((uint32)1 << 0) /* receive enable */
#define RC_RO_MASK 0xfe /* receive frame offset */
#define RC_RO_SHIFT 1
#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */
/* receive descriptor table pointer */
#define RP_LD_MASK 0xfff /* last valid descriptor */
/* receive channel status */
#define RS_CD_MASK 0x0fff /* current descriptor pointer */
#define RS_RS_MASK 0xf000 /* receive state */
#define RS_RS_SHIFT 12
#define RS_RS_DISABLED 0x0000 /* disabled */
#define RS_RS_ACTIVE 0x1000 /* active */
#define RS_RS_IDLE 0x2000 /* idle wait */
#define RS_RS_STOPPED 0x3000 /* reserved */
#define RS_RE_MASK 0xf0000 /* receive errors */
#define RS_RE_SHIFT 16
#define RS_RE_NOERR 0x00000 /* no error */
#define RS_RE_DPE 0x10000 /* descriptor protocol error */
#define RS_RE_DFO 0x20000 /* data fifo overflow */
#define RS_RE_BEBW 0x30000 /* bus error on buffer write */
#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */
#define RS_AD_MASK 0xfff00000 /* active descriptor */
#define RS_AD_SHIFT 20
/* fifoaddr */
#define FA_OFF_MASK 0xffff /* offset */
#define FA_SEL_MASK 0xf0000 /* select */
#define FA_SEL_SHIFT 16
#define FA_SEL_XDD 0x00000 /* transmit dma data */
#define FA_SEL_XDP 0x10000 /* transmit dma pointers */
#define FA_SEL_RDD 0x40000 /* receive dma data */
#define FA_SEL_RDP 0x50000 /* receive dma pointers */
#define FA_SEL_XFD 0x80000 /* transmit fifo data */
#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */
#define FA_SEL_RFD 0xc0000 /* receive fifo data */
#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */
/*
* DMA Descriptor
* Descriptors are only read by the hardware, never written back.
*/
typedef volatile struct {
uint32 ctrl; /* misc control bits & bufcount */
uint32 addr; /* data buffer address */
} dmadd_t;
/*
* Each descriptor ring must be 4096byte aligned
* and fit within a single 4096byte page.
*/
#define DMAMAXRINGSZ 4096
#define DMARINGALIGN 4096
/* control flags */
#define CTRL_BC_MASK 0x1fff /* buffer byte count */
#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */
#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */
#define CTRL_EOF ((uint32)1 << 30) /* end of frame */
#define CTRL_SOF ((uint32)1 << 31) /* start of frame */
/* control flags in the range [27:20] are core-specific and not defined here */
#define CTRL_CORE_MASK 0x0ff00000
/* export structure */
typedef volatile struct {
/* rx error counters */
uint rxgiants; /* rx giant frames */
uint rxnobuf; /* rx out of dma descriptors */
/* tx error counters */
uint txnobuf; /* tx out of dma descriptors */
} hnddma_t;
#ifndef di_t
#define di_t void
#endif
/* externs */
extern void *dma_attach(void *drv, void *dev, char *name, dmaregs_t *dmaregs,
uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset,
uint ddoffset, uint dataoffset, uint *msg_level);
extern void dma_detach(di_t *di);
extern void dma_txreset(di_t *di);
extern void dma_rxreset(di_t *di);
extern void dma_txinit(di_t *di);
extern bool dma_txenabled(di_t *di);
extern void dma_rxinit(di_t *di);
extern void dma_rxenable(di_t *di);
extern bool dma_rxenabled(di_t *di);
extern void dma_txsuspend(di_t *di);
extern void dma_txresume(di_t *di);
extern bool dma_txsuspended(di_t *di);
extern bool dma_txstopped(di_t *di);
extern bool dma_rxstopped(di_t *di);
extern int dma_txfast(di_t *di, void *p, uint32 coreflags);
extern int dma_tx(di_t *di, void *p, uint32 coreflags);
extern void dma_fifoloopbackenable(di_t *di);
extern void *dma_rx(di_t *di);
extern void dma_rxfill(di_t *di);
extern void dma_txreclaim(di_t *di, bool forceall);
extern void dma_rxreclaim(di_t *di);
extern char *dma_dump(di_t *di, char *buf);
extern char *dma_dumptx(di_t *di, char *buf);
extern char *dma_dumprx(di_t *di, char *buf);
extern uint dma_getvar(di_t *di, char *name);
extern void *dma_getnexttxp(di_t *di, bool forceall);
extern void *dma_peeknexttxp(di_t *di);
extern void *dma_getnextrxp(di_t *di, bool forceall);
extern void dma_txblock(di_t *di);
extern void dma_txunblock(di_t *di);
extern uint dma_txactive(di_t *di);
extern void dma_txrotate(di_t *di);
#endif /* _hnddma_h_ */

View File

@ -1,16 +0,0 @@
/*
* Alternate include file for HND sbmips.h since CFE also ships with
* a sbmips.h.
*
* 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.
*
* $Id$
*/
#include "sbmips.h"

View File

@ -1,343 +0,0 @@
/*
* Linux OS Independent Layer
*
* 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.
*
* $Id$
*/
#ifndef _linux_osl_h_
#define _linux_osl_h_
#include <typedefs.h>
/* use current 2.4.x calling conventions */
#include <linuxver.h>
/* assert and panic */
#define ASSERT(exp) do {} while (0)
/* PCMCIA attribute space access macros */
#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
struct pcmcia_dev {
dev_link_t link; /* PCMCIA device pointer */
dev_node_t node; /* PCMCIA node structure */
void *base; /* Mapped attribute memory window */
size_t size; /* Size of window */
void *drv; /* Driver data */
};
#endif
#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \
osl_pcmcia_read_attr((osh), (offset), (buf), (size))
#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \
osl_pcmcia_write_attr((osh), (offset), (buf), (size))
extern void osl_pcmcia_read_attr(void *osh, uint offset, void *buf, int size);
extern void osl_pcmcia_write_attr(void *osh, uint offset, void *buf, int size);
/* PCI configuration space access macros */
#define OSL_PCI_READ_CONFIG(loc, offset, size) \
osl_pci_read_config((loc), (offset), (size))
#define OSL_PCI_WRITE_CONFIG(loc, offset, size, val) \
osl_pci_write_config((loc), (offset), (size), (val))
extern uint32 osl_pci_read_config(void *loc, uint size, uint offset);
extern void osl_pci_write_config(void *loc, uint offset, uint size, uint val);
/* OSL initialization */
#define osl_init() do {} while (0)
/* host/bus architecture-specific byte swap */
#define BUS_SWAP32(v) (v)
/* general purpose memory allocation */
#if defined(BINOSL)
#if defined(BCMDBG_MEM)
#define MALLOC(size) osl_debug_malloc((size), __LINE__, __FILE__)
#define MFREE(addr, size) osl_debug_mfree((addr), (size))
#define MALLOCED() osl_malloced()
extern void* osl_debug_malloc(uint size, int line, char* file);
extern void osl_debug_mfree(void *addr, uint size);
extern void osl_debug_memdump(void);
#else
#define MALLOC(size) osl_malloc((size))
#define MFREE(addr, size) osl_mfree((addr), (size))
#define MALLOCED() osl_malloced()
#endif
extern void *osl_malloc(uint size);
extern void osl_mfree(void *addr, uint size);
extern uint osl_malloced(void);
#else
#define MALLOC(size) kmalloc((size), GFP_ATOMIC)
#define MFREE(addr, size) kfree((addr))
#define MALLOCED() (0)
#endif
/*
* BINOSL selects the slightly slower function-call-based binary compatible osl.
* Macros expand to calls to functions defined in linux_osl.c .
*/
#ifndef BINOSL
/* string library, kernel mode */
#define printf(fmt, args...) printk(fmt, ## args)
#include <linux/kernel.h>
#include <linux/string.h>
/* register access macros */
#define R_REG(r) ( \
sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \
sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \
readl((volatile uint32*)(r)) \
)
#define W_REG(r, v) do { \
switch (sizeof(*(r))) { \
case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \
case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \
case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \
} \
} while (0)
#define AND_REG(r, v) W_REG((r), R_REG(r) & (v))
#define OR_REG(r, v) W_REG((r), R_REG(r) | (v))
/* bcopy, bcmp, and bzero */
#define bcopy(src, dst, len) memcpy((dst), (src), (len))
#define bcmp(b1, b2, len) memcmp((b1), (b2), (len))
#define bzero(b, len) memset((b), '\0', (len))
/* uncached virtual address */
#ifdef mips
#define OSL_UNCACHED(va) KSEG1ADDR((va))
#include <asm/addrspace.h>
#else
#define OSL_UNCACHED(va) (va)
#endif
/* get processor cycle count */
#if defined(mips)
#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2)
#elif defined(__i386__)
#define OSL_GETCYCLES(x) rdtscl((x))
#else
#define OSL_GETCYCLES(x) ((x) = 0)
#endif
/* dereference an address that may cause a bus exception */
#ifdef mips
#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17))
#define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into a module")
#else
#define BUSPROBE(val, addr) get_dbe((val), (addr))
#include <asm/paccess.h>
#endif
#else
#define BUSPROBE(val, addr) ({ (val) = R_REG((addr)); 0; })
#endif
/* map/unmap physical to virtual I/O */
#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
#define REG_UNMAP(va) iounmap((void *)(va))
/* allocate/free shared (dma-able) consistent (uncached) memory */
#define DMA_ALLOC_CONSISTENT(dev, size, pap) \
pci_alloc_consistent((dev), (size), (dma_addr_t*)(pap))
#define DMA_FREE_CONSISTENT(dev, va, size, pa) \
pci_free_consistent((dev), (size), (va), (dma_addr_t)(pa))
/* map/unmap direction */
#define DMA_TX PCI_DMA_TODEVICE
#define DMA_RX PCI_DMA_FROMDEVICE
/* map/unmap shared (dma-able) memory */
#define DMA_MAP(dev, va, size, direction, p) \
pci_map_single((dev), (va), (size), (direction))
#define DMA_UNMAP(dev, pa, size, direction, p) \
pci_unmap_single((dev), (dma_addr_t)(pa), (size), (direction))
/* microsecond delay */
#define OSL_DELAY(usec) udelay(usec)
#include <linux/delay.h>
/* shared (dma-able) memory access macros */
#define R_SM(r) *(r)
#define W_SM(r, v) (*(r) = (v))
#define BZERO_SM(r, len) memset((r), '\0', (len))
/* packet primitives */
#define PKTGET(drv, len, send) osl_pktget((drv), (len), (send))
#define PKTFREE(drv, skb, send) osl_pktfree((skb))
#define PKTDATA(drv, skb) (((struct sk_buff*)(skb))->data)
#define PKTLEN(drv, skb) (((struct sk_buff*)(skb))->len)
#define PKTHEADROOM(drv, skb) (PKTDATA(drv,skb)-(((struct sk_buff*)(skb))->head))
#define PKTTAILROOM(drv, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail))
#define PKTNEXT(drv, skb) (((struct sk_buff*)(skb))->next)
#define PKTSETNEXT(skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x))
#define PKTSETLEN(drv, skb, len) __skb_trim((struct sk_buff*)(skb), (len))
#define PKTPUSH(drv, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes))
#define PKTPULL(drv, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes))
#define PKTDUP(drv, skb) skb_clone((struct sk_buff*)(skb), GFP_ATOMIC)
#define PKTCOOKIE(skb) ((void*)((struct sk_buff*)(skb))->csum)
#define PKTSETCOOKIE(skb, x) (((struct sk_buff*)(skb))->csum = (uint)(x))
#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev)
#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x))
#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority)
#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x))
extern void *osl_pktget(void *drv, uint len, bool send);
extern void osl_pktfree(void *skb);
#else /* BINOSL */
/* string library */
#ifndef LINUX_OSL
#undef printf
#define printf(fmt, args...) osl_printf((fmt), ## args)
#undef sprintf
#define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt), ## args)
#undef strcmp
#define strcmp(s1, s2) osl_strcmp((s1), (s2))
#undef strncmp
#define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n))
#undef strlen
#define strlen(s) osl_strlen((s))
#undef strcpy
#define strcpy(d, s) osl_strcpy((d), (s))
#undef strncpy
#define strncpy(d, s, n) osl_strncpy((d), (s), (n))
#endif
extern int osl_printf(const char *format, ...);
extern int osl_sprintf(char *buf, const char *format, ...);
extern int osl_strcmp(const char *s1, const char *s2);
extern int osl_strncmp(const char *s1, const char *s2, uint n);
extern int osl_strlen(char *s);
extern char* osl_strcpy(char *d, const char *s);
extern char* osl_strncpy(char *d, const char *s, uint n);
/* register access macros */
#define R_REG(r) ( \
sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \
sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \
osl_readl((volatile uint32*)(r)) \
)
#define W_REG(r, v) do { \
switch (sizeof(*(r))) { \
case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \
case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \
case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \
} \
} while (0)
#define AND_REG(r, v) W_REG((r), R_REG(r) & (v))
#define OR_REG(r, v) W_REG((r), R_REG(r) | (v))
extern uint8 osl_readb(volatile uint8 *r);
extern uint16 osl_readw(volatile uint16 *r);
extern uint32 osl_readl(volatile uint32 *r);
extern void osl_writeb(uint8 v, volatile uint8 *r);
extern void osl_writew(uint16 v, volatile uint16 *r);
extern void osl_writel(uint32 v, volatile uint32 *r);
/* bcopy, bcmp, and bzero */
extern void bcopy(const void *src, void *dst, int len);
extern int bcmp(const void *b1, const void *b2, int len);
extern void bzero(void *b, int len);
/* uncached virtual address */
#define OSL_UNCACHED(va) osl_uncached((va))
extern void *osl_uncached(void *va);
/* get processor cycle count */
#define OSL_GETCYCLES(x) ((x) = osl_getcycles())
extern uint osl_getcycles(void);
/* dereference an address that may target abort */
#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr))
extern int osl_busprobe(uint32 *val, uint32 addr);
/* map/unmap physical to virtual */
#define REG_MAP(pa, size) osl_reg_map((pa), (size))
#define REG_UNMAP(va) osl_reg_unmap((va))
extern void *osl_reg_map(uint32 pa, uint size);
extern void osl_reg_unmap(void *va);
/* allocate/free shared (dma-able) consistent (uncached) memory */
#define DMA_ALLOC_CONSISTENT(dev, size, pap) \
osl_dma_alloc_consistent((dev), (size), (pap))
#define DMA_FREE_CONSISTENT(dev, va, size, pa) \
osl_dma_free_consistent((dev), (void*)(va), (size), (pa))
extern void *osl_dma_alloc_consistent(void *dev, uint size, ulong *pap);
extern void osl_dma_free_consistent(void *dev, void *va, uint size, ulong pa);
/* map/unmap direction */
#define DMA_TX 1
#define DMA_RX 2
/* map/unmap shared (dma-able) memory */
#define DMA_MAP(dev, va, size, direction, p) \
osl_dma_map((dev), (va), (size), (direction))
#define DMA_UNMAP(dev, pa, size, direction, p) \
osl_dma_unmap((dev), (pa), (size), (direction))
extern uint osl_dma_map(void *dev, void *va, uint size, int direction);
extern void osl_dma_unmap(void *dev, uint pa, uint size, int direction);
/* microsecond delay */
#define OSL_DELAY(usec) osl_delay((usec))
extern void osl_delay(uint usec);
/* shared (dma-able) memory access macros */
#define R_SM(r) *(r)
#define W_SM(r, v) (*(r) = (v))
#define BZERO_SM(r, len) bzero((r), (len))
/* packet primitives */
#define PKTGET(drv, len, send) osl_pktget((drv), (len), (send))
#define PKTFREE(drv, skb, send) osl_pktfree((skb))
#define PKTDATA(drv, skb) osl_pktdata((drv), (skb))
#define PKTLEN(drv, skb) osl_pktlen((drv), (skb))
#define PKTHEADROOM(drv, skb) osl_pktheadroom((drv), (skb))
#define PKTTAILROOM(drv, skb) osl_pkttailroom((drv), (skb))
#define PKTNEXT(drv, skb) osl_pktnext((drv), (skb))
#define PKTSETNEXT(skb, x) osl_pktsetnext((skb), (x))
#define PKTSETLEN(drv, skb, len) osl_pktsetlen((drv), (skb), (len))
#define PKTPUSH(drv, skb, bytes) osl_pktpush((drv), (skb), (bytes))
#define PKTPULL(drv, skb, bytes) osl_pktpull((drv), (skb), (bytes))
#define PKTDUP(drv, skb) osl_pktdup((drv), (skb))
#define PKTCOOKIE(skb) osl_pktcookie((skb))
#define PKTSETCOOKIE(skb, x) osl_pktsetcookie((skb), (x))
#define PKTLINK(skb) osl_pktlink((skb))
#define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x))
#define PKTPRIO(skb) osl_pktprio((skb))
#define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x))
extern void *osl_pktget(void *drv, uint len, bool send);
extern void osl_pktfree(void *skb);
extern uchar *osl_pktdata(void *drv, void *skb);
extern uint osl_pktlen(void *drv, void *skb);
extern uint osl_pktheadroom(void *drv, void *skb);
extern uint osl_pkttailroom(void *drv, void *skb);
extern void *osl_pktnext(void *drv, void *skb);
extern void osl_pktsetnext(void *skb, void *x);
extern void osl_pktsetlen(void *drv, void *skb, uint len);
extern uchar *osl_pktpush(void *drv, void *skb, int bytes);
extern uchar *osl_pktpull(void *drv, void *skb, int bytes);
extern void *osl_pktdup(void *drv, void *skb);
extern void *osl_pktcookie(void *skb);
extern void osl_pktsetcookie(void *skb, void *x);
extern void *osl_pktlink(void *skb);
extern void osl_pktsetlink(void *skb, void *x);
extern uint osl_pktprio(void *skb);
extern void osl_pktsetprio(void *skb, uint x);
#endif /* BINOSL */
#endif /* _linux_osl_h_ */

View File

@ -1,392 +0,0 @@
/*
* Linux-specific abstractions to gain some independence from linux kernel versions.
* Pave over some 2.2 versus 2.4 versus 2.6 kernel differences.
*
* 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.
*
* $Id$
*/
#ifndef _linuxver_h_
#define _linuxver_h_
#include <linux/config.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0))
/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */
#ifdef __UNDEF_NO_VERSION__
#undef __NO_VERSION__
#else
#define __NO_VERSION__
#endif
#endif
#if defined(MODULE) && defined(MODVERSIONS)
#include <linux/modversions.h>
#endif
/* linux/malloc.h is deprecated, use linux/slab.h instead. */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9))
#include <linux/malloc.h>
#else
#include <linux/slab.h>
#endif
#include <linux/types.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <asm/io.h>
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41))
#include <linux/workqueue.h>
#else
#include <linux/tqueue.h>
#define work_struct tq_struct
#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data))
#define schedule_work(_work) schedule_task((_work))
#define flush_scheduled_work() flush_scheduled_tasks()
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
/* Some distributions have their own 2.6.x compatibility layers */
#ifndef IRQ_NONE
typedef void irqreturn_t;
#define IRQ_NONE
#define IRQ_HANDLED
#define IRQ_RETVAL(x)
#endif
#endif
#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69))
/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which
* does this, but it's not in 2.4 so we do our own for now. */
static inline void
cs_error(client_handle_t handle, int func, int ret)
{
error_info_t err = { func, ret };
CardServices(ReportError, handle, &err);
}
#endif
#endif /* CONFIG_PCMCIA */
#ifndef __exit
#define __exit
#endif
#ifndef __devexit
#define __devexit
#endif
#ifndef __devinit
#define __devinit __init
#endif
#ifndef __devinitdata
#define __devinitdata
#endif
#ifndef __devexit_p
#define __devexit_p(x) x
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
#define pci_get_drvdata(dev) (dev)->sysdata
#define pci_set_drvdata(dev, value) (dev)->sysdata=(value)
/*
* New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration
*/
struct pci_device_id {
unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
unsigned long driver_data; /* Data private to the driver */
};
struct pci_driver {
struct list_head node;
char *name;
const struct pci_device_id *id_table; /* NULL if wants all devices */
int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
void (*suspend)(struct pci_dev *dev); /* Device suspended */
void (*resume)(struct pci_dev *dev); /* Device woken up */
};
#define MODULE_DEVICE_TABLE(type, name)
#define PCI_ANY_ID (~0)
/* compatpci.c */
#define pci_module_init pci_register_driver
extern int pci_register_driver(struct pci_driver *drv);
extern void pci_unregister_driver(struct pci_driver *drv);
#endif /* PCI registration */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18))
#ifdef MODULE
#define module_init(x) int init_module(void) { return x(); }
#define module_exit(x) void cleanup_module(void) { x(); }
#else
#define module_init(x) __initcall(x);
#define module_exit(x) __exitcall(x);
#endif
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48))
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13))
#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)])
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,44))
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,23))
#define pci_enable_device(dev) do { } while (0)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,14))
#define net_device device
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42))
/*
* DMA mapping
*
* See linux/Documentation/DMA-mapping.txt
*/
#ifndef PCI_DMA_TODEVICE
#define PCI_DMA_TODEVICE 1
#define PCI_DMA_FROMDEVICE 2
#endif
typedef u32 dma_addr_t;
/* Pure 2^n version of get_order */
static inline int get_order(unsigned long size)
{
int order;
size = (size-1) >> (PAGE_SHIFT-1);
order = -1;
do {
size >>= 1;
order++;
} while (size);
return order;
}
static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle)
{
void *ret;
int gfp = GFP_ATOMIC | GFP_DMA;
ret = (void *)__get_free_pages(gfp, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
*dma_handle = virt_to_bus(ret);
}
return ret;
}
static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
free_pages((unsigned long)vaddr, get_order(size));
}
#ifdef ILSIM
extern uint pci_map_single(void *dev, void *va, uint size, int direction);
extern void pci_unmap_single(void *dev, uint pa, uint size, int direction);
#else
#define pci_map_single(cookie, address, size, dir) virt_to_bus(address)
#define pci_unmap_single(cookie, address, size, dir)
#endif
#endif /* DMA mapping */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43))
#define dev_kfree_skb_any(a) dev_kfree_skb(a)
#define netif_down(dev) do { (dev)->start = 0; } while(0)
/* pcmcia-cs provides its own netdevice compatibility layer */
#ifndef _COMPAT_NETDEVICE_H
/*
* SoftNet
*
* For pre-softnet kernels we need to tell the upper layer not to
* re-enter start_xmit() while we are in there. However softnet
* guarantees not to enter while we are in there so there is no need
* to do the netif_stop_queue() dance unless the transmit queue really
* gets stuck. This should also improve performance according to tests
* done by Aman Singla.
*/
#define dev_kfree_skb_irq(a) dev_kfree_skb(a)
#define netif_wake_queue(dev) do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while(0)
#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy)
static inline void netif_start_queue(struct net_device *dev)
{
dev->tbusy = 0;
dev->interrupt = 0;
dev->start = 1;
}
#define netif_queue_stopped(dev) (dev)->tbusy
#define netif_running(dev) (dev)->start
#endif /* _COMPAT_NETDEVICE_H */
#define netif_device_attach(dev) netif_start_queue(dev)
#define netif_device_detach(dev) netif_stop_queue(dev)
/* 2.4.x renamed bottom halves to tasklets */
#define tasklet_struct tq_struct
static inline void tasklet_schedule(struct tasklet_struct *tasklet)
{
queue_task(tasklet, &tq_immediate);
mark_bh(IMMEDIATE_BH);
}
static inline void tasklet_init(struct tasklet_struct *tasklet,
void (*func)(unsigned long),
unsigned long data)
{
tasklet->next = NULL;
tasklet->sync = 0;
tasklet->routine = (void (*)(void *))func;
tasklet->data = (void *)data;
}
#define tasklet_kill(tasklet) {do{} while(0);}
/* 2.4.x introduced del_timer_sync() */
#define del_timer_sync(timer) del_timer(timer)
#else
#define netif_down(dev)
#endif /* SoftNet */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3))
/*
* Emit code to initialise a tq_struct's routine and data pointers
*/
#define PREPARE_TQUEUE(_tq, _routine, _data) \
do { \
(_tq)->routine = _routine; \
(_tq)->data = _data; \
} while (0)
/*
* Emit code to initialise all of a tq_struct
*/
#define INIT_TQUEUE(_tq, _routine, _data) \
do { \
INIT_LIST_HEAD(&(_tq)->list); \
(_tq)->sync = 0; \
PREPARE_TQUEUE((_tq), (_routine), (_data)); \
} while (0)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6))
/* Power management related routines */
static inline int
pci_save_state(struct pci_dev *dev, u32 *buffer)
{
int i;
if (buffer) {
for (i = 0; i < 16; i++)
pci_read_config_dword(dev, i * 4,&buffer[i]);
}
return 0;
}
static inline int
pci_restore_state(struct pci_dev *dev, u32 *buffer)
{
int i;
if (buffer) {
for (i = 0; i < 16; i++)
pci_write_config_dword(dev,i * 4, buffer[i]);
}
/*
* otherwise, write the context information we know from bootup.
* This works around a problem where warm-booting from Windows
* combined with a D3(hot)->D0 transition causes PCI config
* header data to be forgotten.
*/
else {
for (i = 0; i < 6; i ++)
pci_write_config_dword(dev,
PCI_BASE_ADDRESS_0 + (i * 4),
pci_resource_start(dev, i));
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
}
return 0;
}
#endif /* PCI power management */
/* Old cp0 access macros deprecated in 2.4.19 */
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19))
#define read_c0_count() read_32bit_cp0_register(CP0_COUNT)
#endif
/* Module refcount handled internally in 2.6.x */
#ifndef SET_MODULE_OWNER
#define SET_MODULE_OWNER(dev) do {} while (0)
#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT
#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT
#else
#define OLD_MOD_INC_USE_COUNT do {} while (0)
#define OLD_MOD_DEC_USE_COUNT do {} while (0)
#endif
#ifndef SET_NETDEV_DEV
#define SET_NETDEV_DEV(net, pdev) do {} while (0)
#endif
#ifndef HAVE_FREE_NETDEV
#define free_netdev(dev) kfree(dev)
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
/* struct packet_type redefined in 2.6.x */
#define af_packet_priv data
#endif
#endif /* _linuxver_h_ */

View File

@ -1,38 +0,0 @@
/*
* OS Independent Layer
*
* 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.
* $Id$
*/
#ifndef _osl_h_
#define _osl_h_
#ifdef V2_HAL
#include <v2hal_osl.h>
#elif defined(linux)
#include <linux_osl.h>
#elif PMON
#include <pmon_osl.h>
#elif defined(NDIS)
#include <ndis_osl.h>
#elif defined(_CFE_)
#include <cfe_osl.h>
#elif defined(MACOS9)
#include <macos9_osl.h>
#elif defined(MACOSX)
#include <macosx_osl.h>
#else
#error "Unsupported OSL requested"
#endif
/* handy */
#define SET_REG(r, mask, val) W_REG((r), ((R_REG(r) & ~(mask)) | (val)))
#endif /* _osl_h_ */

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