aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm-2.4
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2006-04-06 15:52:01 +0000
committerFelix Fietkau <nbd@openwrt.org>2006-04-06 15:52:01 +0000
commit435d6467475c6c5fdb78335e986f1766f7f97648 (patch)
tree64cc169c8261a03029a7e2802480fbebc92d033a /target/linux/brcm-2.4
parent2dcd30e37ea8cef218c6ba8595084a40343bb471 (diff)
downloadupstream-435d6467475c6c5fdb78335e986f1766f7f97648.tar.gz
upstream-435d6467475c6c5fdb78335e986f1766f7f97648.tar.bz2
upstream-435d6467475c6c5fdb78335e986f1766f7f97648.zip
integrate the newer broadcom wl driver from us robotics
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@3596 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/brcm-2.4')
-rw-r--r--target/linux/brcm-2.4/Makefile11
-rw-r--r--target/linux/brcm-2.4/config1
-rw-r--r--target/linux/brcm-2.4/patches/001-bcm47xx.patch7685
3 files changed, 5031 insertions, 2666 deletions
diff --git a/target/linux/brcm-2.4/Makefile b/target/linux/brcm-2.4/Makefile
index ab68b7ae88..17473be323 100644
--- a/target/linux/brcm-2.4/Makefile
+++ b/target/linux/brcm-2.4/Makefile
@@ -13,7 +13,7 @@ $(eval $(call KMOD_template,BRCM_WL,brcm-wl,\
,CONFIG_WL,,20,wl))
$(eval $(call KMOD_template,BRCM_WL2,brcm-wl2,\
- $(BUILD_DIR)/wl/wl2/wl.o \
+ $(MODULES_DIR)/kernel/drivers/net/wl2/wl.o \
,CONFIG_WL,,20,wl))
$(eval $(call KMOD_template,LP,lp,\
@@ -40,8 +40,8 @@ $(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked
LINUX_BINARY_DRIVER_SITE=http://openwrt.org/downloads/sources
# proprietary driver, extracted from Linksys GPL sourcetree WRT54GS 4.70.6
-LINUX_BINARY_WL_DRIVER=kernel-binary-wl-0.5.tar.gz
-LINUX_BINARY_WL_MD5SUM=78e839842bdc04022bb44469f92b1131
+LINUX_BINARY_WL_DRIVER=kernel-binary-wl-0.6.tar.gz
+LINUX_BINARY_WL_MD5SUM=4fc1d5b46bcb7a17d6d5dd31da9c8d7f
$(DL_DIR)/$(LINUX_BINARY_WL_DRIVER):
$(SCRIPT_DIR)/download.pl $(DL_DIR) $(LINUX_BINARY_WL_DRIVER) $(LINUX_BINARY_WL_MD5SUM) $(LINUX_BINARY_DRIVER_SITE) $(MAKE_TRACE)
@@ -56,12 +56,15 @@ $(LINUX_DIR)/.drivers-unpacked: $(LINUX_DIR)/.unpacked
zcat $(DL_DIR)/$(LINUX_BINARY_WL_DRIVER) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) -
# copy binary wlan driver
mkdir -p $(LINUX_DIR)/drivers/net/wl
- $(CP) $(BUILD_DIR)/wl/*.o $(LINUX_DIR)/drivers/net/wl
+ $(CP) $(BUILD_DIR)/kernel-binary-wl/old/*.o $(LINUX_DIR)/drivers/net/wl
+ $(CP) $(BUILD_DIR)/kernel-binary-wl/new/*.o $(LINUX_DIR)/drivers/net/wl2
touch $@
$(LINUX_DIR)/.drivers-installed: $(LINUX_DIR)/.modules_done
mkdir -p $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl
+ mkdir -p $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl2
@-[ -f $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/wl.o ] || $(CP) $(LINUX_DIR)/drivers/net/wl/wl.o $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/
+ @-[ -f $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl2/wl.o ] || $(CP) $(LINUX_DIR)/drivers/net/wl2/wl.o $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl2/
touch $@
linux-dirclean: drivers-clean
diff --git a/target/linux/brcm-2.4/config b/target/linux/brcm-2.4/config
index c4cf5340ea..9759b90f5f 100644
--- a/target/linux/brcm-2.4/config
+++ b/target/linux/brcm-2.4/config
@@ -833,6 +833,7 @@ CONFIG_NET_RADIO=y
# CONFIG_AIRO is not set
# CONFIG_HERMES is not set
CONFIG_WL=m
+CONFIG_WL2=m
# CONFIG_PLX_HERMES is not set
# CONFIG_TMD_HERMES is not set
# CONFIG_PCI_HERMES is not set
diff --git a/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/target/linux/brcm-2.4/patches/001-bcm47xx.patch
index 2e64b0fc3e..d662b4c015 100644
--- a/target/linux/brcm-2.4/patches/001-bcm47xx.patch
+++ b/target/linux/brcm-2.4/patches/001-bcm47xx.patch
@@ -1,6 +1,56 @@
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/cfe_env.c linux-2.4.32-brcm/arch/mips/bcm947xx/cfe_env.c
---- linux-2.4.32/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/cfe_env.c 2005-12-19 01:56:35.104829500 +0100
+diff -Naur linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile
+--- linux.old/arch/mips/Makefile 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/arch/mips/Makefile 2006-04-06 15:34:15.000000000 +0200
+@@ -726,6 +726,19 @@
+ endif
+
+ #
++# Broadcom BCM947XX variants
++#
++ifdef CONFIG_BCM947XX
++LIBS += arch/mips/bcm947xx/generic/brcm.o arch/mips/bcm947xx/bcm947xx.o
++SUBDIRS += arch/mips/bcm947xx/generic arch/mips/bcm947xx
++LOADADDR := 0x80001000
++
++zImage: vmlinux
++ $(MAKE) -C arch/$(ARCH)/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.
+@@ -778,6 +791,7 @@
+ $(MAKE) -C arch/$(ARCH)/tools clean
+ $(MAKE) -C arch/mips/baget clean
+ $(MAKE) -C arch/mips/lasat clean
++ $(MAKE) -C arch/mips/bcm947xx/compressed clean
+
+ archmrproper:
+ @$(MAKEBOOT) mrproper
+diff -Naur linux.old/arch/mips/bcm947xx/Makefile linux.dev/arch/mips/bcm947xx/Makefile
+--- linux.old/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/Makefile 2006-04-06 15:34:14.000000000 +0200
+@@ -0,0 +1,15 @@
++#
++# Makefile for the BCM947xx specific kernel interface routines
++# under Linux.
++#
++
++EXTRA_CFLAGS+=-I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER
++
++O_TARGET := bcm947xx.o
++
++export-objs := nvram_linux.o setup.o
++obj-y := prom.o setup.o time.o sbmips.o gpio.o
++obj-y += nvram.o nvram_linux.o sflash.o cfe_env.o
++obj-$(CONFIG_PCI) += sbpci.o pcibios.o
++
++include $(TOPDIR)/Rules.make
+diff -Naur linux.old/arch/mips/bcm947xx/cfe_env.c linux.dev/arch/mips/bcm947xx/cfe_env.c
+--- linux.old/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/cfe_env.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,234 @@
+/*
+ * NVRAM variable manipulation (Linux kernel half)
@@ -236,9 +286,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/cfe_env.c linux-2.4.32-brcm/arch/mips/
+
+}
+
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/compressed/Makefile
---- linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/compressed/Makefile 2005-12-16 23:39:10.668819500 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/compressed/Makefile linux.dev/arch/mips/bcm947xx/compressed/Makefile
+--- linux.old/arch/mips/bcm947xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/compressed/Makefile 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,33 @@
+#
+# Makefile for Broadcom BCM947XX boards
@@ -273,9 +323,28 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile linux-2.4.32-brcm/
+
+clean:
+ rm -f vmlinuz piggy
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S linux-2.4.32-brcm/arch/mips/bcm947xx/generic/int-handler.S
---- linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/int-handler.S 2005-12-16 23:39:10.668819500 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/generic/Makefile linux.dev/arch/mips/bcm947xx/generic/Makefile
+--- linux.old/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/generic/Makefile 2006-04-06 15:34:14.000000000 +0200
+@@ -0,0 +1,15 @@
++#
++# Makefile for the BCM947xx specific kernel interface routines
++# under Linux.
++#
++
++.S.s:
++ $(CPP) $(AFLAGS) $< -o $*.s
++.S.o:
++ $(CC) $(AFLAGS) -c $< -o $*.o
++
++O_TARGET := brcm.o
++
++obj-y := int-handler.o irq.o
++
++include $(TOPDIR)/Rules.make
+diff -Naur linux.old/arch/mips/bcm947xx/generic/int-handler.S linux.dev/arch/mips/bcm947xx/generic/int-handler.S
+--- linux.old/arch/mips/bcm947xx/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/generic/int-handler.S 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,51 @@
+/*
+ * Generic interrupt handler for Broadcom MIPS boards
@@ -328,9 +397,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S linux-2.4.32-brc
+ nop
+
+ END(brcmIRQ)
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/irq.c linux-2.4.32-brcm/arch/mips/bcm947xx/generic/irq.c
---- linux-2.4.32/arch/mips/bcm947xx/generic/irq.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/irq.c 2005-12-16 23:39:10.668819500 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/generic/irq.c linux.dev/arch/mips/bcm947xx/generic/irq.c
+--- linux.old/arch/mips/bcm947xx/generic/irq.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/generic/irq.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,130 @@
+/*
+ * Generic interrupt control functions for Broadcom MIPS boards
@@ -462,28 +531,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/irq.c linux-2.4.32-brcm/arch/m
+ breakpoint();
+#endif
+}
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/generic/Makefile
---- linux-2.4.32/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/Makefile 2005-12-16 23:39:10.668819500 +0100
-@@ -0,0 +1,15 @@
-+#
-+# Makefile for the BCM947xx specific kernel interface routines
-+# under Linux.
-+#
-+
-+.S.s:
-+ $(CPP) $(AFLAGS) $< -o $*.s
-+.S.o:
-+ $(CC) $(AFLAGS) -c $< -o $*.o
-+
-+O_TARGET := brcm.o
-+
-+obj-y := int-handler.o irq.o
-+
-+include $(TOPDIR)/Rules.make
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/gpio.c linux-2.4.32-brcm/arch/mips/bcm947xx/gpio.c
---- linux-2.4.32/arch/mips/bcm947xx/gpio.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/gpio.c 2005-12-16 23:39:10.668819500 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/gpio.c linux.dev/arch/mips/bcm947xx/gpio.c
+--- linux.old/arch/mips/bcm947xx/gpio.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/gpio.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,158 @@
+/*
+ * GPIO char driver
@@ -643,9 +693,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/gpio.c linux-2.4.32-brcm/arch/mips/bcm
+
+module_init(gpio_init);
+module_exit(gpio_exit);
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmdevs.h
---- linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmdevs.h 2005-12-16 23:39:10.672819750 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm947xx/include/bcmdevs.h
+--- linux.old/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/bcmdevs.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,391 @@
+/*
+ * Broadcom device-specific manifest constants.
@@ -1038,9 +1088,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h linux-2.4.32-brcm/ar
+#define GPIO_NUMPINS 16
+
+#endif /* _BCMDEVS_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmendian.h
---- linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmendian.h 2005-12-16 23:39:10.672819750 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/bcm947xx/include/bcmendian.h
+--- linux.old/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/bcmendian.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,152 @@
+/*
+ * local version of endian.h - byte order defines
@@ -1194,9 +1244,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h linux-2.4.32-brcm/
+)
+
+#endif /* _BCMENDIAN_H_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h
---- linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h 2005-12-16 23:39:10.700821500 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bcm947xx/include/bcmnvram.h
+--- linux.old/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/bcmnvram.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,141 @@
+/*
+ * NVRAM variable manipulation
@@ -1339,9 +1389,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h linux-2.4.32-brcm/a
+#define NVRAM_MAX_PARAM_LEN 64
+
+#endif /* _bcmnvram_h_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h
---- linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h 2005-12-16 23:39:10.704821750 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/bcmsrom.h linux.dev/arch/mips/bcm947xx/include/bcmsrom.h
+--- linux.old/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/bcmsrom.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,23 @@
+/*
+ * Misc useful routines to access NIC local SROM/OTP .
@@ -1366,10 +1416,10 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h linux-2.4.32-brcm/ar
+extern int srom_write(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf);
+
+#endif /* _bcmsrom_h_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmutils.h
---- linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmutils.h 2005-12-16 23:39:10.704821750 +0100
-@@ -0,0 +1,313 @@
+diff -Naur linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bcm947xx/include/bcmutils.h
+--- linux.old/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/bcmutils.h 2006-04-06 17:07:30.000000000 +0200
+@@ -0,0 +1,287 @@
+/*
+ * Misc useful os-independent macros and functions.
+ *
@@ -1429,32 +1479,6 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h linux-2.4.32-brcm/a
+ } \
+}
+
-+/* 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 */
-+ uint8 prio_map[MAXPRIO+1]; /* user priority to packet enqueue policy map */
-+};
-+#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)
-+#define _pktq_pri(q, pri) ((q)->prio_map[pri])
-+#define pktq_tailpri(q) ((q)->tail ? _pktq_pri(q, PKTPRIO((q)->tail)) : _pktq_pri(q, 0))
-+
-+/* externs */
-+/* packet */
-+extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf);
-+extern uint pkttotlen(osl_t *osh, void *);
-+extern void pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]);
-+extern void pktenq(struct pktq *q, void *p, bool lifo);
-+extern void *pktdeq(struct pktq *q);
-+extern void *pktdeqtail(struct pktq *q);
+/* string */
+extern uint bcm_atoi(char *s);
+extern uchar bcm_toupper(uchar c);
@@ -1683,84 +1707,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h linux-2.4.32-brcm/a
+extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len);
+
+#endif /* _bcmutils_h_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h
---- linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h 2005-12-16 23:39:10.708822000 +0100
-@@ -0,0 +1,71 @@
-+/*
-+ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface
-+ * This supports the following chips: BCM42xx, 44xx, 47xx .
-+ *
-+ * Copyright 2005, 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_
-+
-+/* 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
-+
-+#ifndef osl_t
-+#define osl_t void
-+#endif
-+
-+/* externs */
-+extern void * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx,
-+ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, 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_txsuspendedidle(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 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 uintptr 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);
-+
-+extern void dma_rxpiomode(dma32regs_t *);
-+extern void dma_txpioloopback(dma32regs_t *);
-+
-+
-+#endif /* _hnddma_h_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h
---- linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h 2005-12-16 23:39:10.708822000 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/hndmips.h linux.dev/arch/mips/bcm947xx/include/hndmips.h
+--- linux.old/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/hndmips.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,16 @@
+/*
+ * Alternate include file for HND sbmips.h since CFE also ships with
@@ -1778,9 +1727,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h linux-2.4.32-brcm/ar
+ */
+
+#include "sbmips.h"
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h
---- linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h 2005-12-16 23:39:10.708822000 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/bcm947xx/include/linux_osl.h
+--- linux.old/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/linux_osl.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,371 @@
+/*
+ * Linux OS Independent Layer
@@ -2153,9 +2102,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h linux-2.4.32-brcm/
+#define PKTBUFSZ 2048
+
+#endif /* _linux_osl_h_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h
---- linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h 2005-12-16 23:39:10.748824500 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/linuxver.h linux.dev/arch/mips/bcm947xx/include/linuxver.h
+--- linux.old/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/linuxver.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,411 @@
+/*
+ * Linux-specific abstractions to gain some independence from linux kernel versions.
@@ -2568,9 +2517,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h linux-2.4.32-brcm/a
+#endif
+
+#endif /* _linuxver_h_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h
---- linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h 2005-12-16 23:39:10.748824500 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm947xx/include/mipsinc.h
+--- linux.old/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/mipsinc.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,552 @@
+/*
+ * HND Run Time Environment for standalone MIPS programs.
@@ -3124,9 +3073,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h linux-2.4.32-brcm/ar
+#endif /* !_LANGUAGE_ASSEMBLY */
+
+#endif /* _MISPINC_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h
---- linux-2.4.32/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h 2005-12-16 23:39:10.748824500 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947xx/include/osl.h
+--- linux.old/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/osl.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,42 @@
+/*
+ * OS Abstraction Layer
@@ -3170,9 +3119,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/osl.h linux-2.4.32-brcm/arch/m
+#define MAXPRIO 7 /* 0-7 */
+
+#endif /* _osl_h_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h
---- linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h 2005-12-16 23:39:10.752824750 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm947xx/include/pcicfg.h
+--- linux.old/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/pcicfg.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,451 @@
+/*
+ * pcicfg.h: PCI configuration constants and structures.
@@ -3625,9 +3574,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h linux-2.4.32-brcm/arc
+#define PCI_CFG_CMD_STAT_TA 0x08000000 /* target abort status */
+
+#endif
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h 2005-12-16 23:39:10.932836000 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm947xx/include/sbchipc.h
+--- linux.old/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbchipc.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,440 @@
+/*
+ * SiliconBackplane Chipcommon core hardware definitions.
@@ -4069,9 +4018,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h linux-2.4.32-brcm/ar
+#define OTP_MAGIC 0x4e56
+
+#endif /* _SBCHIPC_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbconfig.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbconfig.h 2005-12-16 23:39:10.932836000 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bcm947xx/include/sbconfig.h
+--- linux.old/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbconfig.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,342 @@
+/*
+ * Broadcom SiliconBackplane hardware register definitions.
@@ -4415,9 +4364,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h linux-2.4.32-brcm/a
+#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */
+
+#endif /* _SBCONFIG_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbextif.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbextif.h 2005-12-16 23:39:10.932836000 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/sbextif.h linux.dev/arch/mips/bcm947xx/include/sbextif.h
+--- linux.old/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbextif.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,242 @@
+/*
+ * Hardware-specific External Interface I/O core definitions
@@ -4661,325 +4610,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h linux-2.4.32-brcm/ar
+#define CC_CLOCK_BASE 24000000 /* Half the clock freq. in the 4710 */
+
+#endif /* _SBEXTIF_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbhnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbhnddma.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbhnddma.h 2005-12-16 23:39:10.932836000 +0100
-@@ -0,0 +1,312 @@
-+/*
-+ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface
-+ * This supports the following chips: BCM42xx, 44xx, 47xx .
-+ *
-+ * Copyright 2005, 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 _sbhnddma_h_
-+#define _sbhnddma_h_
-+
-+
-+/* 2byte-wide pio register set per channel(xmt or rcv) */
-+typedef volatile struct {
-+ uint16 fifocontrol;
-+ uint16 fifodata;
-+ uint16 fifofree; /* only valid in xmt channel, not in rcv channel */
-+ uint16 PAD;
-+} pio2regs_t;
-+
-+/* a pair of pio channels(tx and rx) */
-+typedef volatile struct {
-+ pio2regs_t tx;
-+ pio2regs_t rx;
-+} pio2regp_t;
-+
-+/* 4byte-wide pio register set per channel(xmt or rcv) */
-+typedef volatile struct {
-+ uint32 fifocontrol;
-+ uint32 fifodata;
-+} pio4regs_t;
-+
-+/* a pair of pio channels(tx and rx) */
-+typedef volatile struct {
-+ pio4regs_t tx;
-+ pio4regs_t rx;
-+} pio4regp_t;
-+
-+
-+
-+/* DMA structure:
-+ * support two DMA engines: 32 bits address or 64 bit addressing
-+ * basic DMA register set is per channel(transmit or receive)
-+ * a pair of channels is defined for convenience
-+ */
-+
-+
-+/*** 32 bits addressing ***/
-+
-+/* dma registers per channel(xmt or rcv) */
-+typedef volatile struct {
-+ uint32 control; /* enable, et al */
-+ uint32 addr; /* descriptor ring base address (4K aligned) */
-+ uint32 ptr; /* last descriptor posted to chip */
-+ uint32 status; /* current active descriptor, et al */
-+} dma32regs_t;
-+
-+typedef volatile struct {
-+ dma32regs_t xmt; /* dma tx channel */
-+ dma32regs_t rcv; /* dma rx channel */
-+} dma32regp_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 */
-+} dma32diag_t;
-+
-+/*
-+ * 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 */
-+} dma32dd_t;
-+
-+/*
-+ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page.
-+ */
-+#define D32MAXRINGSZ 4096
-+#define D32RINGALIGN 4096
-+#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_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 */
-+#define XC_AE ((uint32)3 << 16) /* address extension bits */
-+#define XC_AE_SHIFT 16
-+
-+/* 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 */
-+#define RC_AE ((uint32)3 << 16) /* address extension bits */
-+#define RC_AE_SHIFT 16
-+
-+/* 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 */
-+#define FA_SEL_RSD 0xe0000 /* receive frame status data */
-+#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */
-+
-+/* descriptor control flags */
-+#define CTRL_BC_MASK 0x1fff /* buffer byte count */
-+#define CTRL_AE ((uint32)3 << 16) /* address extension bits */
-+#define CTRL_AE_SHIFT 16
-+#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
-+
-+/*** 64 bits addressing ***/
-+
-+/* dma registers per channel(xmt or rcv) */
-+typedef volatile struct {
-+ uint32 control; /* enable, et al */
-+ uint32 ptr; /* last descriptor posted to chip */
-+ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */
-+ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */
-+ uint32 status0; /* current descriptor, xmt state */
-+ uint32 status1; /* active descriptor, xmt error */
-+} dma64regs_t;
-+
-+typedef volatile struct {
-+ dma64regs_t tx; /* dma64 tx channel */
-+ dma64regs_t rx; /* dma64 rx channel */
-+} dma64regp_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 */
-+} dma64diag_t;
-+
-+/*
-+ * DMA Descriptor
-+ * Descriptors are only read by the hardware, never written back.
-+ */
-+typedef volatile struct {
-+ uint32 ctrl1; /* misc control bits & bufcount */
-+ uint32 ctrl2; /* buffer count and address extension */
-+ uint32 addrlow; /* memory address of the first byte of the date buffer, bits 31:0 */
-+ uint32 addrhigh; /* memory address of the first byte of the date buffer, bits 63:32 */
-+} dma64dd_t;
-+
-+/*
-+ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss.
-+ */
-+#define D64MAXRINGSZ 8192
-+#define D64RINGALIGN 8192
-+#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t))
-+
-+/* transmit channel control */
-+#define D64_XC_XE 0x00000001 /* transmit enable */
-+#define D64_XC_SE 0x00000002 /* transmit suspend request */
-+#define D64_XC_LE 0x00000004 /* loopback enable */
-+#define D64_XC_FL 0x00000010 /* flush request */
-+#define D64_XC_AE 0x00110000 /* address extension bits */
-+#define D64_XC_AE_SHIFT 16
-+
-+/* transmit descriptor table pointer */
-+#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */
-+
-+/* transmit channel status */
-+#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */
-+#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */
-+#define D64_XS0_XS_SHIFT 28
-+#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */
-+#define D64_XS0_XS_ACTIVE 0x10000000 /* active */
-+#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */
-+#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */
-+#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */
-+
-+#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */
-+#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */
-+#define D64_XS1_XE_SHIFT 28
-+#define D64_XS1_XE_NOERR 0x00000000 /* no error */
-+#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */
-+#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */
-+#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */
-+#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */
-+#define D64_XS1_XE_COREE 0x50000000 /* core error */
-+
-+/* receive channel control */
-+#define D64_RC_RE 0x00000001 /* receive enable */
-+#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */
-+#define D64_RC_RO_SHIFT 1
-+#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */
-+#define D64_RC_AE 0x00110000 /* address extension bits */
-+#define D64_RC_AE_SHIFT 16
-+
-+/* receive descriptor table pointer */
-+#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */
-+
-+/* receive channel status */
-+#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */
-+#define D64_RS0_RS_MASK 0xf0000000 /* receive state */
-+#define D64_RS0_RS_SHIFT 28
-+#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */
-+#define D64_RS0_RS_ACTIVE 0x10000000 /* active */
-+#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */
-+#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */
-+#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */
-+
-+#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */
-+#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */
-+#define D64_RS1_RE_SHIFT 28
-+#define D64_RS1_RE_NOERR 0x00000000 /* no error */
-+#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */
-+#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */
-+#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */
-+#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */
-+#define D64_RS1_RE_COREE 0x50000000 /* core error */
-+
-+/* fifoaddr */
-+#define D64_FA_OFF_MASK 0xffff /* offset */
-+#define D64_FA_SEL_MASK 0xf0000 /* select */
-+#define D64_FA_SEL_SHIFT 16
-+#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */
-+#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */
-+#define D64_FA_SEL_RDD 0x40000 /* receive dma data */
-+#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */
-+#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */
-+#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */
-+#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */
-+#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */
-+#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */
-+#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */
-+
-+/* descriptor control flags 1 */
-+#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */
-+#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */
-+#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */
-+#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */
-+
-+/* descriptor control flags 2 */
-+#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */
-+#define D64_CTRL2_AE 0x00110000 /* address extension bits */
-+#define D64_CTRL2_AE_SHIFT 16
-+
-+/* control flags in the range [27:20] are core-specific and not defined here */
-+#define D64_CTRL_CORE_MASK 0x0ff00000
-+
-+
-+#endif /* _sbhnddma_h_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmemc.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmemc.h 2005-12-16 23:39:10.932836000 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/sbmemc.h linux.dev/arch/mips/bcm947xx/include/sbmemc.h
+--- linux.old/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbmemc.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,148 @@
+/*
+ * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions.
@@ -5129,9 +4762,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h linux-2.4.32-brcm/arc
+#define MEMC_CONFIG_DDR 0x00000001
+
+#endif /* _SBMEMC_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmips.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmips.h 2005-12-16 23:39:10.936836250 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/sbmips.h linux.dev/arch/mips/bcm947xx/include/sbmips.h
+--- linux.old/arch/mips/bcm947xx/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbmips.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,62 @@
+/*
+ * Broadcom SiliconBackplane MIPS definitions
@@ -5195,9 +4828,135 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmips.h linux-2.4.32-brcm/arc
+#endif /* _LANGUAGE_ASSEMBLY */
+
+#endif /* _SBMIPS_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcie.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcie.h 2005-12-16 23:39:10.936836250 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/sbpci.h linux.dev/arch/mips/bcm947xx/include/sbpci.h
+--- linux.old/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbpci.h 2006-04-06 15:34:14.000000000 +0200
+@@ -0,0 +1,122 @@
++/*
++ * BCM47XX Sonics SiliconBackplane PCI core hardware definitions.
++ *
++ * $Id$
++ * Copyright 2005, Broadcom Corporation
++ * All Rights Reserved.
++ *
++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
++ */
++
++#ifndef _SBPCI_H
++#define _SBPCI_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
++
++/* Sonics side: PCI core and host control registers */
++typedef struct sbpciregs {
++ uint32 control; /* PCI control */
++ uint32 PAD[3];
++ uint32 arbcontrol; /* PCI arbiter control */
++ uint32 PAD[3];
++ uint32 intstatus; /* Interrupt status */
++ uint32 intmask; /* Interrupt mask */
++ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */
++ uint32 PAD[9];
++ uint32 bcastaddr; /* Sonics broadcast address */
++ uint32 bcastdata; /* Sonics broadcast data */
++ uint32 PAD[2];
++ uint32 gpioin; /* ro: gpio input (>=rev2) */
++ uint32 gpioout; /* rw: gpio output (>=rev2) */
++ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */
++ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */
++ uint32 PAD[36];
++ uint32 sbtopci0; /* Sonics to PCI translation 0 */
++ uint32 sbtopci1; /* Sonics to PCI translation 1 */
++ uint32 sbtopci2; /* Sonics to PCI translation 2 */
++ uint32 PAD[445];
++ uint16 sprom[36]; /* SPROM shadow Area */
++ uint32 PAD[46];
++} sbpciregs_t;
++
++/* PCI control */
++#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */
++#define PCI_RST 0x02 /* Value driven out to pin */
++#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */
++#define PCI_CLK 0x08 /* Gate for clock driven out to pin */
++
++/* PCI arbiter control */
++#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */
++#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */
++#define PCI_PARKID_MASK 0x06 /* Selects which agent is parked on an idle bus */
++#define PCI_PARKID_SHIFT 1
++#define PCI_PARKID_LAST 0 /* Last requestor */
++#define PCI_PARKID_4710 1 /* 4710 */
++#define PCI_PARKID_EXTREQ0 2 /* External requestor 0 */
++#define PCI_PARKID_EXTREQ1 3 /* External requestor 1 */
++
++/* Interrupt status/mask */
++#define PCI_INTA 0x01 /* PCI INTA# is asserted */
++#define PCI_INTB 0x02 /* PCI INTB# is asserted */
++#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */
++#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */
++#define PCI_PME 0x10 /* PCI PME# is asserted */
++
++/* (General) PCI/SB mailbox interrupts, two bits per pci function */
++#define MAILBOX_F0_0 0x100 /* function 0, int 0 */
++#define MAILBOX_F0_1 0x200 /* function 0, int 1 */
++#define MAILBOX_F1_0 0x400 /* function 1, int 0 */
++#define MAILBOX_F1_1 0x800 /* function 1, int 1 */
++#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */
++#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */
++#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */
++#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */
++
++/* Sonics broadcast address */
++#define BCAST_ADDR_MASK 0xff /* Broadcast register address */
++
++/* Sonics to PCI translation types */
++#define SBTOPCI0_MASK 0xfc000000
++#define SBTOPCI1_MASK 0xfc000000
++#define SBTOPCI2_MASK 0xc0000000
++#define SBTOPCI_MEM 0
++#define SBTOPCI_IO 1
++#define SBTOPCI_CFG0 2
++#define SBTOPCI_CFG1 3
++#define SBTOPCI_PREF 0x4 /* prefetch enable */
++#define SBTOPCI_BURST 0x8 /* burst enable */
++#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */
++#define SBTOPCI_RC_READ 0x00 /* memory read */
++#define SBTOPCI_RC_READLINE 0x10 /* memory read line */
++#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */
++
++/* PCI core index in SROM shadow area */
++#define SRSH_PI_OFFSET 0 /* first word */
++#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
++#define SRSH_PI_SHIFT 12 /* bit 15:12 */
++
++/* PCI side: Reserved PCI configuration registers (see pcicfg.h) */
++#define cap_list rsvd_a[0]
++#define bar0_window dev_dep[0x80 - 0x40]
++#define bar1_window dev_dep[0x84 - 0x40]
++#define sprom_control dev_dep[0x88 - 0x40]
++
++#ifndef _LANGUAGE_ASSEMBLY
++
++extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len);
++extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len);
++extern void sbpci_ban(uint16 core);
++extern int sbpci_init(sb_t *sbh);
++extern void sbpci_check(sb_t *sbh);
++
++#endif /* !_LANGUAGE_ASSEMBLY */
++
++#endif /* _SBPCI_H */
+diff -Naur linux.old/arch/mips/bcm947xx/include/sbpcie.h linux.dev/arch/mips/bcm947xx/include/sbpcie.h
+--- linux.old/arch/mips/bcm947xx/include/sbpcie.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbpcie.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,199 @@
+/*
+ * BCM43XX SiliconBackplane PCIE core hardware definitions.
@@ -5398,135 +5157,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h linux-2.4.32-brcm/arc
+#define SERDES_RX_CDRBW 7 /* CDR BW */
+
+#endif /* _SBPCIE_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpci.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpci.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpci.h 2005-12-16 23:39:10.936836250 +0100
-@@ -0,0 +1,122 @@
-+/*
-+ * BCM47XX Sonics SiliconBackplane PCI core hardware definitions.
-+ *
-+ * $Id$
-+ * Copyright 2005, Broadcom Corporation
-+ * All Rights Reserved.
-+ *
-+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
-+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
-+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
-+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
-+ */
-+
-+#ifndef _SBPCI_H
-+#define _SBPCI_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
-+
-+/* Sonics side: PCI core and host control registers */
-+typedef struct sbpciregs {
-+ uint32 control; /* PCI control */
-+ uint32 PAD[3];
-+ uint32 arbcontrol; /* PCI arbiter control */
-+ uint32 PAD[3];
-+ uint32 intstatus; /* Interrupt status */
-+ uint32 intmask; /* Interrupt mask */
-+ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */
-+ uint32 PAD[9];
-+ uint32 bcastaddr; /* Sonics broadcast address */
-+ uint32 bcastdata; /* Sonics broadcast data */
-+ uint32 PAD[2];
-+ uint32 gpioin; /* ro: gpio input (>=rev2) */
-+ uint32 gpioout; /* rw: gpio output (>=rev2) */
-+ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */
-+ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */
-+ uint32 PAD[36];
-+ uint32 sbtopci0; /* Sonics to PCI translation 0 */
-+ uint32 sbtopci1; /* Sonics to PCI translation 1 */
-+ uint32 sbtopci2; /* Sonics to PCI translation 2 */
-+ uint32 PAD[445];
-+ uint16 sprom[36]; /* SPROM shadow Area */
-+ uint32 PAD[46];
-+} sbpciregs_t;
-+
-+/* PCI control */
-+#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */
-+#define PCI_RST 0x02 /* Value driven out to pin */
-+#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */
-+#define PCI_CLK 0x08 /* Gate for clock driven out to pin */
-+
-+/* PCI arbiter control */
-+#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */
-+#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */
-+#define PCI_PARKID_MASK 0x06 /* Selects which agent is parked on an idle bus */
-+#define PCI_PARKID_SHIFT 1
-+#define PCI_PARKID_LAST 0 /* Last requestor */
-+#define PCI_PARKID_4710 1 /* 4710 */
-+#define PCI_PARKID_EXTREQ0 2 /* External requestor 0 */
-+#define PCI_PARKID_EXTREQ1 3 /* External requestor 1 */
-+
-+/* Interrupt status/mask */
-+#define PCI_INTA 0x01 /* PCI INTA# is asserted */
-+#define PCI_INTB 0x02 /* PCI INTB# is asserted */
-+#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */
-+#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */
-+#define PCI_PME 0x10 /* PCI PME# is asserted */
-+
-+/* (General) PCI/SB mailbox interrupts, two bits per pci function */
-+#define MAILBOX_F0_0 0x100 /* function 0, int 0 */
-+#define MAILBOX_F0_1 0x200 /* function 0, int 1 */
-+#define MAILBOX_F1_0 0x400 /* function 1, int 0 */
-+#define MAILBOX_F1_1 0x800 /* function 1, int 1 */
-+#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */
-+#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */
-+#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */
-+#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */
-+
-+/* Sonics broadcast address */
-+#define BCAST_ADDR_MASK 0xff /* Broadcast register address */
-+
-+/* Sonics to PCI translation types */
-+#define SBTOPCI0_MASK 0xfc000000
-+#define SBTOPCI1_MASK 0xfc000000
-+#define SBTOPCI2_MASK 0xc0000000
-+#define SBTOPCI_MEM 0
-+#define SBTOPCI_IO 1
-+#define SBTOPCI_CFG0 2
-+#define SBTOPCI_CFG1 3
-+#define SBTOPCI_PREF 0x4 /* prefetch enable */
-+#define SBTOPCI_BURST 0x8 /* burst enable */
-+#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */
-+#define SBTOPCI_RC_READ 0x00 /* memory read */
-+#define SBTOPCI_RC_READLINE 0x10 /* memory read line */
-+#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */
-+
-+/* PCI core index in SROM shadow area */
-+#define SRSH_PI_OFFSET 0 /* first word */
-+#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
-+#define SRSH_PI_SHIFT 12 /* bit 15:12 */
-+
-+/* PCI side: Reserved PCI configuration registers (see pcicfg.h) */
-+#define cap_list rsvd_a[0]
-+#define bar0_window dev_dep[0x80 - 0x40]
-+#define bar1_window dev_dep[0x84 - 0x40]
-+#define sprom_control dev_dep[0x88 - 0x40]
-+
-+#ifndef _LANGUAGE_ASSEMBLY
-+
-+extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len);
-+extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len);
-+extern void sbpci_ban(uint16 core);
-+extern int sbpci_init(sb_t *sbh);
-+extern void sbpci_check(sb_t *sbh);
-+
-+#endif /* !_LANGUAGE_ASSEMBLY */
-+
-+#endif /* _SBPCI_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcmcia.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcmcia.h 2005-12-16 23:39:10.936836250 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/sbpcmcia.h linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h
+--- linux.old/arch/mips/bcm947xx/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,146 @@
+/*
+ * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions.
@@ -5674,9 +5307,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.4.32-brcm/a
+#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */
+
+#endif /* _SBPCMCIA_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsdram.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsdram.h 2005-12-16 23:39:10.936836250 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/sbsdram.h linux.dev/arch/mips/bcm947xx/include/sbsdram.h
+--- linux.old/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbsdram.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,75 @@
+/*
+ * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions.
@@ -5753,9 +5386,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h linux-2.4.32-brcm/ar
+#define MEM8MX16X2 0xc29 /* 32 MB */
+
+#endif /* _SBSDRAM_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsocram.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsocram.h 2005-12-16 23:39:10.936836250 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/sbsocram.h linux.dev/arch/mips/bcm947xx/include/sbsocram.h
+--- linux.old/arch/mips/bcm947xx/include/sbsocram.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbsocram.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,37 @@
+/*
+ * BCM47XX Sonics SiliconBackplane embedded ram core
@@ -5794,9 +5427,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h linux-2.4.32-brcm/a
+#define SOCRAM_MEMSIZE_BASESHIFT 16
+
+#endif /* _SBSOCRAM_H */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbutils.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbutils.h 2005-12-16 23:39:10.936836250 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm947xx/include/sbutils.h
+--- linux.old/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbutils.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,140 @@
+/*
+ * Misc utility routines for accessing chip-specific features
@@ -5938,9 +5571,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h linux-2.4.32-brcm/ar
+#define SB_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
+
+#endif /* _sbutils_h_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sflash.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sflash.h
---- linux-2.4.32/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sflash.h 2005-12-16 23:39:10.936836250 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/sflash.h linux.dev/arch/mips/bcm947xx/include/sflash.h
+--- linux.old/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sflash.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,36 @@
+/*
+ * Broadcom SiliconBackplane chipcommon serial flash interface
@@ -5978,9 +5611,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sflash.h linux-2.4.32-brcm/arc
+extern struct sflash * sflash_init(chipcregs_t *cc);
+
+#endif /* _sflash_h_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/trxhdr.h
---- linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/trxhdr.h 2005-12-16 23:39:10.940836500 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/trxhdr.h linux.dev/arch/mips/bcm947xx/include/trxhdr.h
+--- linux.old/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/trxhdr.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,33 @@
+/*
+ * TRX image file header format.
@@ -6015,9 +5648,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h linux-2.4.32-brcm/arc
+
+/* Compatibility */
+typedef struct trx_header TRXHDR, *PTRXHDR;
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/typedefs.h
---- linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/typedefs.h 2005-12-16 23:39:10.940836500 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/include/typedefs.h linux.dev/arch/mips/bcm947xx/include/typedefs.h
+--- linux.old/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/typedefs.h 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2005, Broadcom Corporation
@@ -6345,28 +5978,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h linux-2.4.32-brcm/a
+#endif /* USE_TYPEDEF_DEFAULTS */
+
+#endif /* _TYPEDEFS_H_ */
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile
---- linux-2.4.32/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile 2005-12-19 01:56:51.733868750 +0100
-@@ -0,0 +1,15 @@
-+#
-+# Makefile for the BCM947xx specific kernel interface routines
-+# under Linux.
-+#
-+
-+EXTRA_CFLAGS+=-I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER
-+
-+O_TARGET := bcm947xx.o
-+
-+export-objs := nvram_linux.o setup.o
-+obj-y := prom.o setup.o time.o sbmips.o gpio.o
-+obj-y += nvram.o nvram_linux.o sflash.o cfe_env.o
-+obj-$(CONFIG_PCI) += sbpci.o pcibios.o
-+
-+include $(TOPDIR)/Rules.make
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram.c linux-2.4.32-brcm/arch/mips/bcm947xx/nvram.c
---- linux-2.4.32/arch/mips/bcm947xx/nvram.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/nvram.c 2005-12-19 01:05:00.079582750 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/nvram.c linux.dev/arch/mips/bcm947xx/nvram.c
+--- linux.old/arch/mips/bcm947xx/nvram.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/nvram.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,320 @@
+/*
+ * NVRAM variable manipulation (common)
@@ -6688,9 +6302,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram.c linux-2.4.32-brcm/arch/mips/bc
+{
+ BCMINIT(nvram_free)();
+}
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c linux-2.4.32-brcm/arch/mips/bcm947xx/nvram_linux.c
---- linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/nvram_linux.c 2005-12-19 01:09:59.782313000 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947xx/nvram_linux.c
+--- linux.old/arch/mips/bcm947xx/nvram_linux.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/nvram_linux.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,653 @@
+/*
+ * NVRAM variable manipulation (Linux kernel half)
@@ -7345,9 +6959,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c linux-2.4.32-brcm/arch/m
+
+module_init(dev_nvram_init);
+module_exit(dev_nvram_exit);
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/pcibios.c linux-2.4.32-brcm/arch/mips/bcm947xx/pcibios.c
---- linux-2.4.32/arch/mips/bcm947xx/pcibios.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/pcibios.c 2005-12-16 23:39:10.944836750 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/pcibios.c linux.dev/arch/mips/bcm947xx/pcibios.c
+--- linux.old/arch/mips/bcm947xx/pcibios.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/pcibios.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,355 @@
+/*
+ * Low-Level PCI and SB support for BCM47xx (Linux support code)
@@ -7704,9 +7318,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/pcibios.c linux-2.4.32-brcm/arch/mips/
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/prom.c linux-2.4.32-brcm/arch/mips/bcm947xx/prom.c
---- linux-2.4.32/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/prom.c 2005-12-16 23:39:10.944836750 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/prom.c linux.dev/arch/mips/bcm947xx/prom.c
+--- linux.old/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/prom.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,41 @@
+/*
+ * Early initialization code for BCM94710 boards
@@ -7749,9 +7363,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/prom.c linux-2.4.32-brcm/arch/mips/bcm
+prom_free_prom_memory(void)
+{
+}
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbmips.c linux-2.4.32-brcm/arch/mips/bcm947xx/sbmips.c
---- linux-2.4.32/arch/mips/bcm947xx/sbmips.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/sbmips.c 2005-12-16 23:39:10.944836750 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbmips.c
+--- linux.old/arch/mips/bcm947xx/sbmips.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/sbmips.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,1038 @@
+/*
+ * BCM47XX Sonics SiliconBackplane MIPS core routines
@@ -8791,9 +8405,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbmips.c linux-2.4.32-brcm/arch/mips/b
+ return ret;
+}
+
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbpci.c linux-2.4.32-brcm/arch/mips/bcm947xx/sbpci.c
---- linux-2.4.32/arch/mips/bcm947xx/sbpci.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/sbpci.c 2005-12-16 23:39:10.948837000 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpci.c
+--- linux.old/arch/mips/bcm947xx/sbpci.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/sbpci.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,588 @@
+/*
+ * Low-Level PCI and SB support for BCM47xx
@@ -9383,9 +8997,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbpci.c linux-2.4.32-brcm/arch/mips/bc
+ sb_setcoreidx(sbh, coreidx);
+}
+
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/setup.c linux-2.4.32-brcm/arch/mips/bcm947xx/setup.c
---- linux-2.4.32/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/setup.c 2005-12-20 00:29:40.187416500 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setup.c
+--- linux.old/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/setup.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,234 @@
+/*
+ * Generic setup routines for Broadcom MIPS boards
@@ -9621,9 +9235,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/setup.c linux-2.4.32-brcm/arch/mips/bc
+}
+
+EXPORT_SYMBOL(bcm947xx_sbh);
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/sflash.c linux-2.4.32-brcm/arch/mips/bcm947xx/sflash.c
---- linux-2.4.32/arch/mips/bcm947xx/sflash.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/sflash.c 2005-12-16 23:39:10.948837000 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/sflash.c linux.dev/arch/mips/bcm947xx/sflash.c
+--- linux.old/arch/mips/bcm947xx/sflash.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/sflash.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,418 @@
+/*
+ * Broadcom SiliconBackplane chipcommon serial flash interface
@@ -10043,9 +9657,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/sflash.c linux-2.4.32-brcm/arch/mips/b
+ return ret;
+}
+
-diff -Nur linux-2.4.32/arch/mips/bcm947xx/time.c linux-2.4.32-brcm/arch/mips/bcm947xx/time.c
---- linux-2.4.32/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/bcm947xx/time.c 2005-12-16 23:39:10.948837000 +0100
+diff -Naur linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time.c
+--- linux.old/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/time.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2004, Broadcom Corporation
@@ -10165,10 +9779,10 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/time.c linux-2.4.32-brcm/arch/mips/bcm
+ /* Enable the timer interrupt */
+ setup_irq(7, &bcm947xx_timer_irqaction);
+}
-diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/config-shared.in
---- linux-2.4.32/arch/mips/config-shared.in 2005-01-19 15:09:27.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/config-shared.in 2005-12-16 23:39:11.080845250 +0100
-@@ -205,6 +205,14 @@
+diff -Naur linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared.in
+--- linux.old/arch/mips/config-shared.in 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/arch/mips/config-shared.in 2006-04-06 15:34:14.000000000 +0200
+@@ -208,6 +208,14 @@
fi
define_bool CONFIG_MIPS_RTC y
fi
@@ -10183,7 +9797,7 @@ diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/co
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
-@@ -226,6 +234,11 @@
+@@ -229,6 +237,11 @@
define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
#
@@ -10195,7 +9809,7 @@ diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/co
# Select some configuration options automatically based on user selections.
#
if [ "$CONFIG_ACER_PICA_61" = "y" ]; then
-@@ -533,6 +546,13 @@
+@@ -554,6 +567,13 @@
define_bool CONFIG_SWAP_IO_SPACE_L y
define_bool CONFIG_BOOT_ELF32 y
fi
@@ -10209,7 +9823,7 @@ diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/co
if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then
define_bool CONFIG_ARC32 y
define_bool CONFIG_ARC_MEMORY y
-@@ -1011,7 +1031,11 @@
+@@ -1042,7 +1062,11 @@
bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE
bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG
@@ -10222,10 +9836,10 @@ diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/co
dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB
if [ "$CONFIG_KGDB" = "y" ]; then
define_bool CONFIG_DEBUG_INFO y
-diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/kernel/cpu-probe.c
---- linux-2.4.32/arch/mips/kernel/cpu-probe.c 2005-01-19 15:09:29.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/kernel/cpu-probe.c 2005-12-16 23:39:11.084845500 +0100
-@@ -174,7 +174,7 @@
+diff -Naur linux.old/arch/mips/kernel/cpu-probe.c linux.dev/arch/mips/kernel/cpu-probe.c
+--- linux.old/arch/mips/kernel/cpu-probe.c 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/arch/mips/kernel/cpu-probe.c 2006-04-06 15:34:14.000000000 +0200
+@@ -162,7 +162,7 @@
static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
{
@@ -10234,7 +9848,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/
case PRID_IMP_R2000:
c->cputype = CPU_R2000;
c->isa_level = MIPS_CPU_ISA_I;
-@@ -184,7 +184,7 @@
+@@ -172,7 +172,7 @@
c->tlbsize = 64;
break;
case PRID_IMP_R3000:
@@ -10243,7 +9857,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/
if (cpu_has_confreg())
c->cputype = CPU_R3081E;
else
-@@ -199,12 +199,12 @@
+@@ -187,12 +187,12 @@
break;
case PRID_IMP_R4000:
if (read_c0_config() & CONF_SC) {
@@ -10258,7 +9872,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/
c->cputype = CPU_R4400SC;
else
c->cputype = CPU_R4000SC;
-@@ -450,7 +450,7 @@
+@@ -438,7 +438,7 @@
static inline void cpu_probe_mips(struct cpuinfo_mips *c)
{
decode_config1(c);
@@ -10267,7 +9881,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/
case PRID_IMP_4KC:
c->cputype = CPU_4KC;
c->isa_level = MIPS_CPU_ISA_M32;
-@@ -491,10 +491,10 @@
+@@ -479,10 +479,10 @@
{
decode_config1(c);
c->options |= MIPS_CPU_PREFETCH;
@@ -10280,7 +9894,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/
case 0:
c->cputype = CPU_AU1000;
break;
-@@ -522,10 +522,34 @@
+@@ -510,10 +510,34 @@
}
}
@@ -10316,7 +9930,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/
case PRID_IMP_SB1:
c->cputype = CPU_SB1;
c->isa_level = MIPS_CPU_ISA_M64;
-@@ -547,7 +571,7 @@
+@@ -535,7 +559,7 @@
static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c)
{
decode_config1(c);
@@ -10325,7 +9939,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/
case PRID_IMP_SR71000:
c->cputype = CPU_SR71000;
c->isa_level = MIPS_CPU_ISA_M64;
-@@ -572,7 +596,7 @@
+@@ -560,7 +584,7 @@
c->cputype = CPU_UNKNOWN;
c->processor_id = read_c0_prid();
@@ -10334,7 +9948,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/
case PRID_COMP_LEGACY:
cpu_probe_legacy(c);
-@@ -583,6 +607,9 @@
+@@ -571,6 +595,9 @@
case PRID_COMP_ALCHEMY:
cpu_probe_alchemy(c);
break;
@@ -10344,9 +9958,9 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/
case PRID_COMP_SIBYTE:
cpu_probe_sibyte(c);
break;
-diff -Nur linux-2.4.32/arch/mips/kernel/head.S linux-2.4.32-brcm/arch/mips/kernel/head.S
---- linux-2.4.32/arch/mips/kernel/head.S 2005-01-19 15:09:29.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/kernel/head.S 2005-12-16 23:39:11.084845500 +0100
+diff -Naur linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S
+--- linux.old/arch/mips/kernel/head.S 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/arch/mips/kernel/head.S 2006-04-06 15:34:14.000000000 +0200
@@ -28,12 +28,20 @@
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
@@ -10369,9 +9983,9 @@ diff -Nur linux-2.4.32/arch/mips/kernel/head.S linux-2.4.32-brcm/arch/mips/kerne
/* The following two symbols are used for kernel profiling. */
EXPORT(stext)
-diff -Nur linux-2.4.32/arch/mips/kernel/proc.c linux-2.4.32-brcm/arch/mips/kernel/proc.c
---- linux-2.4.32/arch/mips/kernel/proc.c 2005-01-19 15:09:29.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/kernel/proc.c 2005-12-16 23:39:11.084845500 +0100
+diff -Naur linux.old/arch/mips/kernel/proc.c linux.dev/arch/mips/kernel/proc.c
+--- linux.old/arch/mips/kernel/proc.c 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/arch/mips/kernel/proc.c 2006-04-06 15:34:14.000000000 +0200
@@ -78,9 +78,10 @@
[CPU_AU1550] "Au1550",
[CPU_24K] "MIPS 24K",
@@ -10384,10 +9998,10 @@ diff -Nur linux-2.4.32/arch/mips/kernel/proc.c linux-2.4.32-brcm/arch/mips/kerne
static int show_cpuinfo(struct seq_file *m, void *v)
{
unsigned int version = current_cpu_data.processor_id;
-diff -Nur linux-2.4.32/arch/mips/kernel/setup.c linux-2.4.32-brcm/arch/mips/kernel/setup.c
---- linux-2.4.32/arch/mips/kernel/setup.c 2005-01-19 15:09:29.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/kernel/setup.c 2005-12-16 23:39:11.140849000 +0100
-@@ -495,6 +495,7 @@
+diff -Naur linux.old/arch/mips/kernel/setup.c linux.dev/arch/mips/kernel/setup.c
+--- linux.old/arch/mips/kernel/setup.c 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/arch/mips/kernel/setup.c 2006-04-06 15:34:14.000000000 +0200
+@@ -493,6 +493,7 @@
void swarm_setup(void);
void hp_setup(void);
void au1x00_setup(void);
@@ -10395,7 +10009,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/setup.c linux-2.4.32-brcm/arch/mips/kern
void frame_info_init(void);
frame_info_init();
-@@ -693,6 +694,11 @@
+@@ -691,6 +692,11 @@
pmc_yosemite_setup();
break;
#endif
@@ -10407,10 +10021,10 @@ diff -Nur linux-2.4.32/arch/mips/kernel/setup.c linux-2.4.32-brcm/arch/mips/kern
default:
panic("Unsupported architecture");
}
-diff -Nur linux-2.4.32/arch/mips/kernel/traps.c linux-2.4.32-brcm/arch/mips/kernel/traps.c
---- linux-2.4.32/arch/mips/kernel/traps.c 2005-01-19 15:09:29.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/kernel/traps.c 2005-12-16 23:39:11.140849000 +0100
-@@ -913,6 +913,7 @@
+diff -Naur linux.old/arch/mips/kernel/traps.c linux.dev/arch/mips/kernel/traps.c
+--- linux.old/arch/mips/kernel/traps.c 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/arch/mips/kernel/traps.c 2006-04-06 15:34:14.000000000 +0200
+@@ -920,6 +920,7 @@
void __init trap_init(void)
{
extern char except_vec1_generic;
@@ -10418,7 +10032,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/traps.c linux-2.4.32-brcm/arch/mips/kern
extern char except_vec3_generic, except_vec3_r4000;
extern char except_vec_ejtag_debug;
extern char except_vec4;
-@@ -922,6 +923,7 @@
+@@ -927,6 +928,7 @@
/* Copy the generic exception handler code to it's final destination. */
memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80);
@@ -10426,7 +10040,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/traps.c linux-2.4.32-brcm/arch/mips/kern
/*
* Setup default vectors
-@@ -980,6 +982,12 @@
+@@ -985,6 +987,12 @@
set_except_vector(13, handle_tr);
set_except_vector(22, handle_mdmx);
@@ -10439,41 +10053,10 @@ diff -Nur linux-2.4.32/arch/mips/kernel/traps.c linux-2.4.32-brcm/arch/mips/kern
if (cpu_has_fpu && !cpu_has_nofpuex)
set_except_vector(15, handle_fpe);
-diff -Nur linux-2.4.32/arch/mips/Makefile linux-2.4.32-brcm/arch/mips/Makefile
---- linux-2.4.32/arch/mips/Makefile 2005-01-19 15:09:26.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/Makefile 2005-12-16 23:39:10.668819500 +0100
-@@ -715,6 +715,19 @@
- endif
-
- #
-+# Broadcom BCM947XX variants
-+#
-+ifdef CONFIG_BCM947XX
-+LIBS += arch/mips/bcm947xx/generic/brcm.o arch/mips/bcm947xx/bcm947xx.o
-+SUBDIRS += arch/mips/bcm947xx/generic arch/mips/bcm947xx
-+LOADADDR := 0x80001000
-+
-+zImage: vmlinux
-+ $(MAKE) -C arch/$(ARCH)/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.
-@@ -767,6 +780,7 @@
- $(MAKE) -C arch/$(ARCH)/tools clean
- $(MAKE) -C arch/mips/baget clean
- $(MAKE) -C arch/mips/lasat clean
-+ $(MAKE) -C arch/mips/bcm947xx/compressed clean
-
- archmrproper:
- @$(MAKEBOOT) mrproper
-diff -Nur linux-2.4.32/arch/mips/mm/c-r4k.c linux-2.4.32-brcm/arch/mips/mm/c-r4k.c
---- linux-2.4.32/arch/mips/mm/c-r4k.c 2005-01-19 15:09:29.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/mm/c-r4k.c 2005-12-16 23:39:11.144849250 +0100
-@@ -1114,3 +1114,47 @@
+diff -Naur linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c
+--- linux.old/arch/mips/mm/c-r4k.c 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/arch/mips/mm/c-r4k.c 2006-04-06 15:34:15.000000000 +0200
+@@ -1166,3 +1166,47 @@
build_clear_page();
build_copy_page();
}
@@ -10521,9 +10104,9 @@ diff -Nur linux-2.4.32/arch/mips/mm/c-r4k.c linux-2.4.32-brcm/arch/mips/mm/c-r4k
+}
+
+
-diff -Nur linux-2.4.32/arch/mips/pci/Makefile linux-2.4.32-brcm/arch/mips/pci/Makefile
---- linux-2.4.32/arch/mips/pci/Makefile 2005-01-19 15:09:29.000000000 +0100
-+++ linux-2.4.32-brcm/arch/mips/pci/Makefile 2005-12-16 23:39:11.144849250 +0100
+diff -Naur linux.old/arch/mips/pci/Makefile linux.dev/arch/mips/pci/Makefile
+--- linux.old/arch/mips/pci/Makefile 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/arch/mips/pci/Makefile 2006-04-06 15:34:14.000000000 +0200
@@ -13,7 +13,9 @@
obj-$(CONFIG_MIPS_MSC) += ops-msc.o
obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o
@@ -10534,10 +10117,10 @@ diff -Nur linux-2.4.32/arch/mips/pci/Makefile linux-2.4.32-brcm/arch/mips/pci/Ma
obj-$(CONFIG_PCI_AUTO) += pci_auto.o
include $(TOPDIR)/Rules.make
-diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/serial.c
---- linux-2.4.32/drivers/char/serial.c 2005-11-16 20:12:54.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/char/serial.c 2005-12-16 23:39:11.200852750 +0100
-@@ -422,6 +422,10 @@
+diff -Naur linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c
+--- linux.old/drivers/char/serial.c 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/drivers/char/serial.c 2006-04-06 15:34:14.000000000 +0200
+@@ -444,6 +444,10 @@
return inb(info->port+1);
#endif
case SERIAL_IO_MEM:
@@ -10548,7 +10131,7 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri
return readb((unsigned long) info->iomem_base +
(offset<<info->iomem_reg_shift));
default:
-@@ -442,6 +446,9 @@
+@@ -464,6 +468,9 @@
case SERIAL_IO_MEM:
writeb(value, (unsigned long) info->iomem_base +
(offset<<info->iomem_reg_shift));
@@ -10558,7 +10141,7 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri
break;
default:
outb(value, info->port+offset);
-@@ -1704,7 +1711,7 @@
+@@ -1728,7 +1735,7 @@
/* Special case since 134 is really 134.5 */
quot = (2*baud_base / 269);
else if (baud)
@@ -10567,7 +10150,7 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri
}
/* If the quotient is zero refuse the change */
if (!quot && old_termios) {
-@@ -1721,12 +1728,12 @@
+@@ -1745,12 +1752,12 @@
/* Special case since 134 is really 134.5 */
quot = (2*baud_base / 269);
else if (baud)
@@ -10582,7 +10165,7 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri
/*
* Work around a bug in the Oxford Semiconductor 952 rev B
* chip which causes it to seriously miscalculate baud rates
-@@ -5982,6 +5989,13 @@
+@@ -5994,6 +6001,13 @@
* Divisor, bytesize and parity
*/
state = rs_table + co->index;
@@ -10596,7 +10179,7 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri
if (doflow)
state->flags |= ASYNC_CONS_FLOW;
info = &async_sercons;
-@@ -5995,7 +6009,7 @@
+@@ -6007,7 +6021,7 @@
info->io_type = state->io_type;
info->iomem_base = state->iomem_base;
info->iomem_reg_shift = state->iomem_reg_shift;
@@ -10605,9 +10188,9 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri
cval = cflag & (CSIZE | CSTOPB);
#if defined(__powerpc__) || defined(__alpha__)
cval >>= 8;
-diff -Nur linux-2.4.32/drivers/net/Config.in linux-2.4.32-brcm/drivers/net/Config.in
---- linux-2.4.32/drivers/net/Config.in 2005-01-19 15:09:56.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/net/Config.in 2005-12-16 23:39:11.232854750 +0100
+diff -Naur linux.old/drivers/net/Config.in linux.dev/drivers/net/Config.in
+--- linux.old/drivers/net/Config.in 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/drivers/net/Config.in 2006-04-06 15:34:14.000000000 +0200
@@ -2,6 +2,8 @@
# Network device configuration
#
@@ -10617,9 +10200,65 @@ diff -Nur linux-2.4.32/drivers/net/Config.in linux-2.4.32-brcm/drivers/net/Confi
source drivers/net/arcnet/Config.in
tristate 'Dummy net driver support' CONFIG_DUMMY
-diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c
---- linux-2.4.32/drivers/net/hnd/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c 2005-12-16 23:39:11.284858000 +0100
+diff -Naur linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile
+--- linux.old/drivers/net/Makefile 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/drivers/net/Makefile 2006-04-06 16:45:29.000000000 +0200
+@@ -3,6 +3,8 @@
+ # Makefile for the Linux network (ethercard) device drivers.
+ #
+
++EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include
++
+ obj-y :=
+ obj-m :=
+ obj-n :=
+@@ -39,6 +41,9 @@
+ obj-$(CONFIG_ISDN) += slhc.o
+ endif
+
++subdir-$(CONFIG_HND) += hnd
++subdir-$(CONFIG_WL) += wl
++subdir-$(CONFIG_WL2) += wl2
+ subdir-$(CONFIG_NET_PCMCIA) += pcmcia
+ subdir-$(CONFIG_NET_WIRELESS) += wireless
+ subdir-$(CONFIG_TULIP) += tulip
+@@ -69,6 +74,10 @@
+ obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o
+ obj-$(CONFIG_SUNGEM) += sungem.o
+
++ifeq ($(CONFIG_HND),y)
++ obj-y += hnd/hnd.o
++endif
++
+ obj-$(CONFIG_MACE) += mace.o
+ obj-$(CONFIG_BMAC) += bmac.o
+ obj-$(CONFIG_GMAC) += gmac.o
+diff -Naur linux.old/drivers/net/hnd/Makefile linux.dev/drivers/net/hnd/Makefile
+--- linux.old/drivers/net/hnd/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/hnd/Makefile 2006-04-06 16:20:00.000000000 +0200
+@@ -0,0 +1,19 @@
++#
++# Makefile for the BCM47xx specific kernel interface routines
++# under Linux.
++#
++
++EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER
++
++O_TARGET := hnd.o
++
++HND_OBJS := bcmutils.o linux_osl.o sbutils.o bcmsrom.o
++
++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) > $@
+diff -Naur linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom.c
+--- linux.old/drivers/net/hnd/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/hnd/bcmsrom.c 2006-04-06 15:34:14.000000000 +0200
@@ -0,0 +1,938 @@
+/*
+ * Misc useful routines to access NIC SROM/OTP .
@@ -11559,10 +11198,10 @@ diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/h
+ return (rc);
+}
+
-diff -Nur linux-2.4.32/drivers/net/hnd/bcmutils.c linux-2.4.32-brcm/drivers/net/hnd/bcmutils.c
---- linux-2.4.32/drivers/net/hnd/bcmutils.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/net/hnd/bcmutils.c 2005-12-16 23:39:11.288858250 +0100
-@@ -0,0 +1,1081 @@
+diff -Naur linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutils.c
+--- linux.old/drivers/net/hnd/bcmutils.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/hnd/bcmutils.c 2006-04-06 16:05:56.000000000 +0200
+@@ -0,0 +1,875 @@
+/*
+ * Misc useful OS-independent routines.
+ *
@@ -11590,212 +11229,6 @@ diff -Nur linux-2.4.32/drivers/net/hnd/bcmutils.c linux-2.4.32-brcm/drivers/net/
+#include <bcmdevs.h>
+
+#ifdef BCMDRIVER
-+/* copy a pkt buffer chain into a buffer */
-+uint
-+pktcopy(osl_t *osh, 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(osh, p)) {
-+ if (offset < (uint)PKTLEN(osh, p))
-+ break;
-+ offset -= PKTLEN(osh, p);
-+ }
-+
-+ if (!p)
-+ return 0;
-+
-+ /* copy the data */
-+ for (; p && len; p = PKTNEXT(osh, p)) {
-+ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len);
-+ bcopy(PKTDATA(osh, p) + offset, buf, n);
-+ buf += n;
-+ len -= n;
-+ ret += n;
-+ offset = 0;
-+ }
-+
-+ return ret;
-+}
-+
-+/* return total length of buffer chain */
-+uint
-+pkttotlen(osl_t *osh, void *p)
-+{
-+ uint total;
-+
-+ total = 0;
-+ for (; p; p = PKTNEXT(osh, p))
-+ total += PKTLEN(osh, p);
-+ return (total);
-+}
-+
-+void
-+pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[])
-+{
-+ q->head = q->tail = NULL;
-+ q->maxlen = maxlen;
-+ q->len = 0;
-+ if (prio_map) {
-+ q->priority = TRUE;
-+ bcopy(prio_map, q->prio_map, sizeof(q->prio_map));
-+ }
-+ else
-+ q->priority = FALSE;
-+}
-+
-+/* should always check pktq_full before calling pktenq */
-+void
-+pktenq(struct pktq *q, void *p, bool lifo)
-+{
-+ void *next, *prev;
-+
-+ /* allow 10 pkts slack */
-+ ASSERT(q->len < (q->maxlen + 10));
-+
-+ /* 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 {
-+ /* legal priorities 0-7 */
-+ ASSERT(PKTPRIO(p) <= MAXPRIO);
-+
-+ ASSERT(q->head);
-+ ASSERT(q->tail);
-+ /* Shortcut to insertion at tail */
-+ if (_pktq_pri(q, PKTPRIO(p)) < _pktq_pri(q, PKTPRIO(q->tail)) ||
-+ (!lifo && _pktq_pri(q, PKTPRIO(p)) <= _pktq_pri(q, 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 || _pktq_pri(q, PKTPRIO(prev)) >= _pktq_pri(q, PKTPRIO(next)));
-+ /* Insert at head of string of packets of same priority (LIFO) */
-+ if (lifo) {
-+ if (_pktq_pri(q, PKTPRIO(p)) >= _pktq_pri(q, PKTPRIO(next)))
-+ break;
-+ }
-+ /* Insert at tail of string of packets of same priority (FIFO) */
-+ else {
-+ if (_pktq_pri(q, PKTPRIO(p)) > _pktq_pri(q, 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++;
-+}
-+
-+/* dequeue packet at head */
-+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);
-+}
-+
-+/* dequeue packet at tail */
-+void*
-+pktdeqtail(struct pktq *q)
-+{
-+ void *p;
-+ void *next, *prev;
-+
-+ if (q->head == q->tail) { /* last packet on queue or queue empty */
-+ p = q->head;
-+ q->head = q->tail = NULL;
-+ q->len = 0;
-+ return(p);
-+ }
-+
-+ /* start walk at head */
-+ prev = NULL;
-+ next = q->head;
-+
-+ /* Walk the queue to find prev of q->tail */
-+ for (; next; prev = next, next = PKTLINK(next)) {
-+ if (next == q->tail)
-+ break;
-+ }
-+
-+ ASSERT(prev);
-+
-+ PKTSETLINK(prev, NULL);
-+ q->tail = prev;
-+ q->len--;
-+ p = next;
-+
-+ return (p);
-+}
-+
+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 */
@@ -12644,1540 +12077,9 @@ diff -Nur linux-2.4.32/drivers/net/hnd/bcmutils.c linux-2.4.32-brcm/drivers/net/
+
+ return(qdbm);
+}
-diff -Nur linux-2.4.32/drivers/net/hnd/hnddma.c linux-2.4.32-brcm/drivers/net/hnd/hnddma.c
---- linux-2.4.32/drivers/net/hnd/hnddma.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/net/hnd/hnddma.c 2005-12-16 23:39:11.288858250 +0100
-@@ -0,0 +1,1527 @@
-+/*
-+ * Generic Broadcom Home Networking Division (HND) DMA module.
-+ * This supports the following chips: BCM42xx, 44xx, 47xx .
-+ *
-+ * Copyright 2005, 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 <sbconfig.h>
-+#include <bcmutils.h>
-+#include <bcmdevs.h>
-+#include <sbutils.h>
-+
-+struct dma_info; /* forward declaration */
-+#define di_t struct dma_info
-+
-+#include <sbhnddma.h>
-+#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
-+
-+/* 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 *osh; /* os handle */
-+ sb_t *sbh; /* sb handle */
-+
-+ bool dma64; /* dma64 enabled */
-+ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
-+
-+ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */
-+ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */
-+ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */
-+ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */
-+
-+ uint32 dma64align; /* either 8k or 4k depends on number of dd */
-+ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */
-+ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */
-+ uint ntxd; /* # tx descriptors tunable */
-+ uint txin; /* index of next descriptor to reclaim */
-+ uint txout; /* index of next descriptor to post */
-+ uint txavail; /* # free tx descriptors */
-+ void **txp; /* pointer to parallel array of pointers to packets */
-+ ulong txdpa; /* physical address of descriptor ring */
-+ uint txdalign; /* #bytes added to alloc'd mem to align txd */
-+ uint txdalloc; /* #bytes allocated for the ring */
-+
-+ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */
-+ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */
-+ uint nrxd; /* # rx descriptors tunable */
-+ uint rxin; /* index of next descriptor to reclaim */
-+ uint rxout; /* index of next descriptor to post */
-+ void **rxp; /* pointer to parallel array of pointers to packets */
-+ ulong rxdpa; /* physical address of descriptor ring */
-+ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */
-+ uint rxdalloc; /* #bytes allocated for the ring */
-+
-+ /* tunables */
-+ uint rxbufsize; /* rx buffer size in bytes */
-+ uint nrxpost; /* # rx buffers to keep posted */
-+ uint rxoffset; /* rxcontrol offset */
-+ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */
-+ uint ddoffsethigh; /* add to get dma address of descriptor ring, high 32 bits */
-+ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */
-+ uint dataoffsethigh; /* add to get dma address of data buffer, high 32 bits */
-+} dma_info_t;
-+
-+#ifdef BCMDMA64
-+#define DMA64_ENAB(di) ((di)->dma64)
-+#else
-+#define DMA64_ENAB(di) (0)
-+#endif
-+
-+/* descriptor bumping macros */
-+#define XXD(x, n) ((x) & ((n) - 1))
-+#define TXD(x) XXD((x), di->ntxd)
-+#define RXD(x) XXD((x), di->nrxd)
-+#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, type) ((bytes) / sizeof(type))
-+#define I2B(index, type) ((index) * sizeof(type))
-+
-+#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */
-+#define PCI32ADDR_HIGH_SHIFT 30
-+
-+
-+/* prototypes */
-+static bool dma_isaddrext(dma_info_t *di);
-+static bool dma_alloc(dma_info_t *di, uint direction);
-+
-+static bool dma32_alloc(dma_info_t *di, uint direction);
-+static void dma32_txreset(dma_info_t *di);
-+static void dma32_rxreset(dma_info_t *di);
-+static bool dma32_txsuspendedidle(dma_info_t *di);
-+static int dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags);
-+static void* dma32_getnexttxp(dma_info_t *di, bool forceall);
-+static void* dma32_getnextrxp(dma_info_t *di, bool forceall);
-+static void dma32_txrotate(di_t *di);
-+
-+/* prototype or stubs */
-+#ifdef BCMDMA64
-+static bool dma64_alloc(dma_info_t *di, uint direction);
-+static void dma64_txreset(dma_info_t *di);
-+static void dma64_rxreset(dma_info_t *di);
-+static bool dma64_txsuspendedidle(dma_info_t *di);
-+static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags);
-+static void* dma64_getnexttxp(dma_info_t *di, bool forceall);
-+static void* dma64_getnextrxp(dma_info_t *di, bool forceall);
-+static void dma64_txrotate(di_t *di);
-+#else
-+static bool dma64_alloc(dma_info_t *di, uint direction) { return TRUE; }
-+static void dma64_txreset(dma_info_t *di) {}
-+static void dma64_rxreset(dma_info_t *di) {}
-+static bool dma64_txsuspendedidle(dma_info_t *di) { return TRUE;}
-+static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) { return 0; }
-+static void* dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; }
-+static void* dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; }
-+static void dma64_txrotate(di_t *di) { return; }
-+#endif
-+
-+/* old dmaregs struct for compatibility */
-+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 struct {
-+ uint ddoffset;
-+ uint dataoffset;
-+} compat_data;
-+
-+static compat_data *ugly_hack = NULL;
-+
-+void*
-+dma_attold(void *drv, void *osh, char *name, dmaregs_t *regs, uint ntxd, uint nrxd,
-+ uint rxbufsize, uint nrxpost, uint rxoffset, uint ddoffset, uint dataoffset, uint *msg_level)
-+{
-+ dma32regs_t *dtx = regs;
-+ dma32regs_t *drx = dtx + 1;
-+
-+ ugly_hack = kmalloc(sizeof(ugly_hack), GFP_KERNEL);
-+ ugly_hack->ddoffset = ddoffset;
-+ ugly_hack->dataoffset = dataoffset;
-+ dma_attach((osl_t *) osh, name, NULL, dtx, drx, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, msg_level);
-+ ugly_hack = NULL;
-+}
-+
-+
-+void*
-+dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx,
-+ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level)
-+{
-+ dma_info_t *di;
-+ uint size;
-+
-+ /* allocate private info structure */
-+ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) {
-+ return (NULL);
-+ }
-+ bzero((char*)di, sizeof (dma_info_t));
-+
-+ di->msg_level = msg_level ? msg_level : &dma_msg_level;
-+
-+ if (sbh != NULL)
-+ di->dma64 = ((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64);
-+
-+#ifndef BCMDMA64
-+ if (di->dma64) {
-+ DMA_ERROR(("dma_attach: driver doesn't have the capability to support 64 bits DMA\n"));
-+ goto fail;
-+ }
-+#endif
-+
-+ /* check arguments */
-+ ASSERT(ISPOWEROF2(ntxd));
-+ ASSERT(ISPOWEROF2(nrxd));
-+ if (nrxd == 0)
-+ ASSERT(dmaregsrx == NULL);
-+ if (ntxd == 0)
-+ ASSERT(dmaregstx == NULL);
-+
-+
-+ /* init dma reg pointer */
-+ if (di->dma64) {
-+ ASSERT(ntxd <= D64MAXDD);
-+ ASSERT(nrxd <= D64MAXDD);
-+ di->d64txregs = (dma64regs_t *)dmaregstx;
-+ di->d64rxregs = (dma64regs_t *)dmaregsrx;
-+
-+ di->dma64align = D64RINGALIGN;
-+ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
-+ /* for smaller dd table, HW relax the alignment requirement */
-+ di->dma64align = D64RINGALIGN / 2;
-+ }
-+ } else {
-+ ASSERT(ntxd <= D32MAXDD);
-+ ASSERT(nrxd <= D32MAXDD);
-+ di->d32txregs = (dma32regs_t *)dmaregstx;
-+ di->d32rxregs = (dma32regs_t *)dmaregsrx;
-+ }
-+
-+
-+ /* make a private copy of our callers name */
-+ strncpy(di->name, name, MAXNAMEL);
-+ di->name[MAXNAMEL-1] = '\0';
-+
-+ di->osh = osh;
-+ di->sbh = sbh;
-+
-+ /* save tunables */
-+ di->ntxd = ntxd;
-+ di->nrxd = nrxd;
-+ di->rxbufsize = rxbufsize;
-+ di->nrxpost = nrxpost;
-+ di->rxoffset = rxoffset;
-+
-+ /*
-+ * figure out the DMA physical address offset for dd and data
-+ * for old chips w/o sb, use zero
-+ * for new chips w sb,
-+ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset
-+ * Other bus: use zero
-+ * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
-+ */
-+ di->ddoffsetlow = 0;
-+ di->dataoffsetlow = 0;
-+ if (ugly_hack != NULL) {
-+ di->ddoffsetlow = ugly_hack->ddoffset;
-+ di->dataoffsetlow = ugly_hack->dataoffset;
-+ di->ddoffsethigh = 0;
-+ di->dataoffsethigh = 0;
-+ } else if (sbh != NULL) {
-+ if (sbh->bustype == PCI_BUS) { /* for pci bus, add offset */
-+ if ((sbh->buscoretype == SB_PCIE) && di->dma64){
-+ di->ddoffsetlow = 0;
-+ di->ddoffsethigh = SB_PCIE_DMA_H32;
-+ } else {
-+ di->ddoffsetlow = SB_PCI_DMA;
-+ di->ddoffsethigh = 0;
-+ }
-+ di->dataoffsetlow = di->ddoffsetlow;
-+ di->dataoffsethigh = di->ddoffsethigh;
-+ }
-+#if defined(__mips__) && defined(IL_BIGENDIAN)
-+ /* use sdram swapped region for data buffers but not dma descriptors */
-+ di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED;
-+#endif
-+ }
-+
-+ di->addrext = ((ugly_hack == NULL) ? dma_isaddrext(di) : 0);
-+
-+ DMA_TRACE(("%s: dma_attach: osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n",
-+ name, osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, di->ddoffsetlow, di->dataoffsetlow));
-+
-+ /* allocate tx packet pointer vector */
-+ if (ntxd) {
-+ size = ntxd * sizeof (void*);
-+ if ((di->txp = MALLOC(osh, size)) == NULL) {
-+ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh)));
-+ goto fail;
-+ }
-+ bzero((char*)di->txp, size);
-+ }
-+
-+ /* allocate rx packet pointer vector */
-+ if (nrxd) {
-+ size = nrxd * sizeof (void*);
-+ if ((di->rxp = MALLOC(osh, size)) == NULL) {
-+ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh)));
-+ goto fail;
-+ }
-+ bzero((char*)di->rxp, size);
-+ }
-+
-+ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
-+ if (ntxd) {
-+ if (!dma_alloc(di, DMA_TX))
-+ goto fail;
-+ }
-+
-+ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
-+ if (nrxd) {
-+ if (!dma_alloc(di, DMA_RX))
-+ goto fail;
-+ }
-+
-+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) {
-+ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", di->name, di->txdpa));
-+ goto fail;
-+ }
-+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) {
-+ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", di->name, di->rxdpa));
-+ goto fail;
-+ }
-+
-+ return ((void*)di);
-+
-+fail:
-+ dma_detach((void*)di);
-+ return (NULL);
-+}
-+
-+static bool
-+dma_alloc(dma_info_t *di, uint direction)
-+{
-+ if (DMA64_ENAB(di)) {
-+ return dma64_alloc(di, direction);
-+ } else {
-+ return dma32_alloc(di, direction);
-+ }
-+}
-+
-+/* 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->txd32)
-+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), di->txdalloc, (di->txdpa - di->txdalign));
-+ if (di->rxd32)
-+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), di->rxdalloc, (di->rxdpa - di->rxdalign));
-+
-+ /* free packet pointer vectors */
-+ if (di->txp)
-+ MFREE(di->osh, (void*)di->txp, (di->ntxd * sizeof (void*)));
-+ if (di->rxp)
-+ MFREE(di->osh, (void*)di->rxp, (di->nrxd * sizeof (void*)));
-+
-+ /* free our private info structure */
-+ MFREE(di->osh, (void*)di, sizeof (dma_info_t));
-+}
-+
-+/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */
-+static bool
-+dma_isaddrext(dma_info_t *di)
-+{
-+ uint32 w;
-+
-+ if (DMA64_ENAB(di)) {
-+ OR_REG(&di->d64txregs->control, D64_XC_AE);
-+ w = R_REG(&di->d32txregs->control);
-+ AND_REG(&di->d32txregs->control, ~D64_XC_AE);
-+ return ((w & XC_AE) == D64_XC_AE);
-+ } else {
-+ OR_REG(&di->d32txregs->control, XC_AE);
-+ w = R_REG(&di->d32txregs->control);
-+ AND_REG(&di->d32txregs->control, ~XC_AE);
-+ return ((w & XC_AE) == XC_AE);
-+ }
-+}
-+
-+void
-+dma_txreset(dma_info_t *di)
-+{
-+ DMA_TRACE(("%s: dma_txreset\n", di->name));
-+
-+ if (DMA64_ENAB(di))
-+ dma64_txreset(di);
-+ else
-+ dma32_txreset(di);
-+}
-+
-+void
-+dma_rxreset(dma_info_t *di)
-+{
-+ DMA_TRACE(("%s: dma_rxreset\n", di->name));
-+
-+ if (DMA64_ENAB(di))
-+ dma64_rxreset(di);
-+ else
-+ dma32_rxreset(di);
-+}
-+
-+/* initialize descriptor table base address */
-+static void
-+dma_ddtable_init(dma_info_t *di, uint direction, ulong pa)
-+{
-+ if (DMA64_ENAB(di)) {
-+ if (direction == DMA_TX) {
-+ W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow);
-+ W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh);
-+ } else {
-+ W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow);
-+ W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh);
-+ }
-+ } else {
-+ uint32 offset = di->ddoffsetlow;
-+ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
-+ if (direction == DMA_TX)
-+ W_REG(&di->d32txregs->addr, (pa + offset));
-+ else
-+ W_REG(&di->d32rxregs->addr, (pa + offset));
-+ } else {
-+ /* dma32 address extension */
-+ uint32 ae;
-+ ASSERT(di->addrext);
-+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
-+
-+ if (direction == DMA_TX) {
-+ W_REG(&di->d32txregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset));
-+ SET_REG(&di->d32txregs->control, XC_AE, (ae << XC_AE_SHIFT));
-+ } else {
-+ W_REG(&di->d32rxregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset));
-+ SET_REG(&di->d32rxregs->control, RC_AE, (ae << RC_AE_SHIFT));
-+ }
-+ }
-+ }
-+}
-+
-+/* init the tx or rx descriptor */
-+static INLINE void
-+dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *ctrl)
-+{
-+ uint offset = di->dataoffsetlow;
-+
-+ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
-+ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + offset));
-+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl));
-+ } else {
-+ /* address extension */
-+ uint32 ae;
-+ ASSERT(di->addrext);
-+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
-+
-+ *ctrl |= (ae << CTRL_AE_SHIFT);
-+ W_SM(&ddring[outidx].addr, BUS_SWAP32((pa & ~PCI32ADDR_HIGH) + offset));
-+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl));
-+ }
-+}
-+
-+/* init the tx or rx descriptor */
-+static INLINE void
-+dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, uint32 bufcount)
-+{
-+ uint32 bufaddr_low = pa + di->dataoffsetlow;
-+ uint32 bufaddr_high = 0 + di->dataoffsethigh;
-+
-+ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
-+
-+ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(bufaddr_low));
-+ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(bufaddr_high));
-+ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
-+ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
-+}
-+
-+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 */
-+ if (DMA64_ENAB(di)) {
-+ BZERO_SM((void*)di->txd64, (di->ntxd * sizeof (dma64dd_t)));
-+ W_REG(&di->d64txregs->control, XC_XE);
-+ dma_ddtable_init(di, DMA_TX, di->txdpa);
-+ } else {
-+ BZERO_SM((void*)di->txd32, (di->ntxd * sizeof (dma32dd_t)));
-+ W_REG(&di->d32txregs->control, XC_XE);
-+ dma_ddtable_init(di, DMA_TX, di->txdpa);
-+ }
-+}
-+
-+bool
-+dma_txenabled(dma_info_t *di)
-+{
-+ uint32 xc;
-+
-+ /* If the chip is dead, it is not enabled :-) */
-+ if (DMA64_ENAB(di)) {
-+ xc = R_REG(&di->d64txregs->control);
-+ return ((xc != 0xffffffff) && (xc & D64_XC_XE));
-+ } else {
-+ xc = R_REG(&di->d32txregs->control);
-+ return ((xc != 0xffffffff) && (xc & XC_XE));
-+ }
-+}
-+
-+void
-+dma_txsuspend(dma_info_t *di)
-+{
-+ DMA_TRACE(("%s: dma_txsuspend\n", di->name));
-+ if (DMA64_ENAB(di))
-+ OR_REG(&di->d64txregs->control, D64_XC_SE);
-+ else
-+ OR_REG(&di->d32txregs->control, XC_SE);
-+}
-+
-+void
-+dma_txresume(dma_info_t *di)
-+{
-+ DMA_TRACE(("%s: dma_txresume\n", di->name));
-+ if (DMA64_ENAB(di))
-+ AND_REG(&di->d64txregs->control, ~D64_XC_SE);
-+ else
-+ AND_REG(&di->d32txregs->control, ~XC_SE);
-+}
-+
-+bool
-+dma_txsuspendedidle(dma_info_t *di)
-+{
-+ if (DMA64_ENAB(di))
-+ return dma64_txsuspendedidle(di);
-+ else
-+ return dma32_txsuspendedidle(di);
-+}
-+
-+bool
-+dma_txsuspended(dma_info_t *di)
-+{
-+ if (DMA64_ENAB(di))
-+ return ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE);
-+ else
-+ return ((R_REG(&di->d32txregs->control) & XC_SE) == XC_SE);
-+}
-+
-+bool
-+dma_txstopped(dma_info_t *di)
-+{
-+ if (DMA64_ENAB(di))
-+ return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED);
-+ else
-+ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED);
-+}
-+
-+bool
-+dma_rxstopped(dma_info_t *di)
-+{
-+ if (DMA64_ENAB(di))
-+ return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED);
-+ else
-+ return ((R_REG(&di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED);
-+}
-+
-+void
-+dma_fifoloopbackenable(dma_info_t *di)
-+{
-+ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
-+ if (DMA64_ENAB(di))
-+ OR_REG(&di->d64txregs->control, D64_XC_LE);
-+ else
-+ OR_REG(&di->d32txregs->control, 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 */
-+ if (DMA64_ENAB(di)) {
-+ BZERO_SM((void*)di->rxd64, (di->nrxd * sizeof (dma64dd_t)));
-+ dma_rxenable(di);
-+ dma_ddtable_init(di, DMA_RX, di->rxdpa);
-+ } else {
-+ BZERO_SM((void*)di->rxd32, (di->nrxd * sizeof (dma32dd_t)));
-+ dma_rxenable(di);
-+ dma_ddtable_init(di, DMA_RX, di->rxdpa);
-+ }
-+}
-+
-+void
-+dma_rxenable(dma_info_t *di)
-+{
-+ DMA_TRACE(("%s: dma_rxenable\n", di->name));
-+ if (DMA64_ENAB(di))
-+ W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE));
-+ else
-+ W_REG(&di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE));
-+}
-+
-+bool
-+dma_rxenabled(dma_info_t *di)
-+{
-+ uint32 rc;
-+
-+ if (DMA64_ENAB(di)) {
-+ rc = R_REG(&di->d64rxregs->control);
-+ return ((rc != 0xffffffff) && (rc & D64_RC_RE));
-+ } else {
-+ rc = R_REG(&di->d32rxregs->control);
-+ return ((rc != 0xffffffff) && (rc & RC_RE));
-+ }
-+}
-+
-+
-+/* !! tx entry routine */
-+int
-+dma_txfast(dma_info_t *di, void *p0, uint32 coreflags)
-+{
-+ if (DMA64_ENAB(di)) {
-+ return dma64_txfast(di, p0, coreflags);
-+ } else {
-+ return dma32_txfast(di, p0, coreflags);
-+ }
-+}
-+
-+/* !! rx entry routine, 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->osh, p, FALSE);
-+ continue;
-+ }
-+
-+ len = ltoh16(*(uint16*)(PKTDATA(di->osh, 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->osh, p, FALSE);
-+ di->hnddma.rxgiants++;
-+ continue;
-+ }
-+
-+ /* set actual length */
-+ PKTSETLEN(di->osh, p, (di->rxoffset + len));
-+
-+ break;
-+ }
-+
-+ return (p);
-+}
-+
-+/* post receive buffers */
-+void
-+dma_rxfill(dma_info_t *di)
-+{
-+ void *p;
-+ uint rxin, rxout;
-+ uint32 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->osh, rxbufsize, FALSE)) == NULL) {
-+ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name));
-+ di->hnddma.rxnobuf++;
-+ break;
-+ }
-+
-+ /* Do a cached write instead of uncached write since DMA_MAP
-+ * will flush the cache. */
-+ *(uint32*)(PKTDATA(di->osh, p)) = 0;
-+
-+ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p);
-+ ASSERT(ISALIGNED(pa, 4));
-+
-+ /* save the free packet pointer */
-+ ASSERT(di->rxp[rxout] == NULL);
-+ di->rxp[rxout] = p;
-+
-+ if (DMA64_ENAB(di)) {
-+ /* prep the descriptor control value */
-+ if (rxout == (di->nrxd - 1))
-+ ctrl = CTRL_EOT;
-+
-+ dma64_dd_upd(di, di->rxd64, pa, rxout, &ctrl, rxbufsize);
-+ } else {
-+ /* prep the descriptor control value */
-+ ctrl = rxbufsize;
-+ if (rxout == (di->nrxd - 1))
-+ ctrl |= CTRL_EOT;
-+ dma32_dd_upd(di, di->rxd32, pa, rxout, &ctrl);
-+ }
-+
-+ rxout = NEXTRXD(rxout);
-+ }
-+
-+ di->rxout = rxout;
-+
-+ /* update the chip lastdscr pointer */
-+ if (DMA64_ENAB(di)) {
-+ W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t));
-+ } else {
-+ W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t));
-+ }
-+}
-+
-+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->osh, 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)
-+{
-+ if (DMA64_ENAB(di)) {
-+ return dma64_getnexttxp(di, forceall);
-+ } else {
-+ return dma32_getnexttxp(di, forceall);
-+ }
-+}
-+
-+/* like getnexttxp but no reclaim */
-+void*
-+dma_peeknexttxp(dma_info_t *di)
-+{
-+ uint end, i;
-+
-+ if (DMA64_ENAB(di)) {
-+ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
-+ } else {
-+ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
-+ }
-+
-+ for (i = di->txin; i != end; i = NEXTTXD(i))
-+ if (di->txp[i])
-+ return (di->txp[i]);
-+
-+ return (NULL);
-+}
-+
-+/*
-+ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
-+ */
-+void
-+dma_txrotate(di_t *di)
-+{
-+ if (DMA64_ENAB(di)) {
-+ dma64_txrotate(di);
-+ } else {
-+ dma32_txrotate(di);
-+ }
-+}
-+
-+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->osh, p, FALSE);
-+}
-+
-+void *
-+dma_getnextrxp(dma_info_t *di, bool forceall)
-+{
-+ if (DMA64_ENAB(di)) {
-+ return dma64_getnextrxp(di, forceall);
-+ } else {
-+ return dma32_getnextrxp(di, forceall);
-+ }
-+}
-+
-+uintptr
-+dma_getvar(dma_info_t *di, char *name)
-+{
-+ if (!strcmp(name, "&txavail"))
-+ return ((uintptr) &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));
-+}
-+
-+void
-+dma_rxpiomode(dma32regs_t *regs)
-+{
-+ W_REG(&regs->control, RC_FM);
-+}
-+
-+void
-+dma_txpioloopback(dma32regs_t *regs)
-+{
-+ OR_REG(&regs->control, XC_LE);
-+}
-+
-+
-+
-+
-+/*** 32 bits DMA non-inline functions ***/
-+static bool
-+dma32_alloc(dma_info_t *di, uint direction)
-+{
-+ uint size;
-+ uint ddlen;
-+ void *va;
-+
-+ ddlen = sizeof (dma32dd_t);
-+
-+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
-+
-+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN))
-+ size += D32RINGALIGN;
-+
-+
-+ if (direction == DMA_TX) {
-+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) {
-+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
-+ return FALSE;
-+ }
-+
-+ di->txd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN);
-+ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va);
-+ di->txdpa += di->txdalign;
-+ di->txdalloc = size;
-+ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN));
-+ } else {
-+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) {
-+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
-+ return FALSE;
-+ }
-+ di->rxd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN);
-+ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va);
-+ di->rxdpa += di->rxdalign;
-+ di->rxdalloc = size;
-+ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN));
-+ }
-+
-+ return TRUE;
-+}
-+
-+static void
-+dma32_txreset(dma_info_t *di)
-+{
-+ uint32 status;
-+
-+ /* suspend tx DMA first */
-+ W_REG(&di->d32txregs->control, XC_SE);
-+ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED &&
-+ status != XS_XS_IDLE &&
-+ status != XS_XS_STOPPED,
-+ 10000);
-+
-+ W_REG(&di->d32txregs->control, 0);
-+ SPINWAIT((status = (R_REG(&di->d32txregs->status) & 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);
-+}
-+
-+static void
-+dma32_rxreset(dma_info_t *di)
-+{
-+ uint32 status;
-+
-+ W_REG(&di->d32rxregs->control, 0);
-+ SPINWAIT((status = (R_REG(&di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED,
-+ 10000);
-+
-+ if (status != RS_RS_DISABLED) {
-+ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name));
-+ }
-+}
-+
-+static bool
-+dma32_txsuspendedidle(dma_info_t *di)
-+{
-+ if (!(R_REG(&di->d32txregs->control) & XC_SE))
-+ return 0;
-+
-+ if ((R_REG(&di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE)
-+ return 0;
-+
-+ OSL_DELAY(2);
-+ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE);
-+}
-+
-+/*
-+ * supports full 32bit dma engine buffer addressing so
-+ * dma buffers can cross 4 Kbyte page boundaries.
-+ */
-+static int
-+dma32_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->osh, p);
-+ len = PKTLEN(di->osh, p);
-+ next = PKTNEXT(di->osh, 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->osh, 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;
-+
-+ if (DMA64_ENAB(di)) {
-+ dma64_dd_upd(di, di->txd64, pa, txout, &ctrl, len);
-+ } else {
-+ dma32_dd_upd(di, di->txd32, pa, txout, &ctrl);
-+ }
-+
-+ ASSERT(di->txp[txout] == NULL);
-+
-+ txout = NEXTTXD(txout);
-+ }
-+
-+ /* if last txd eof not set, fix it */
-+ if (!(ctrl & CTRL_EOF))
-+ W_SM(&di->txd32[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 */
-+ if (DMA64_ENAB(di)) {
-+ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t));
-+ } else {
-+ W_REG(&di->d32txregs->ptr, I2B(txout, dma32dd_t));
-+ }
-+
-+ /* 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->osh, p0, TRUE);
-+ di->txavail = 0;
-+ di->hnddma.txnobuf++;
-+ return (-1);
-+}
-+
-+static void*
-+dma32_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->d32txregs->status) & XS_CD_MASK, dma32dd_t);
-+
-+ if ((start == 0) && (end > di->txout))
-+ goto bogus;
-+
-+ for (i = start; i != end && !txp; i = NEXTTXD(i)) {
-+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow),
-+ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]);
-+
-+ W_SM(&di->txd32[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);
-+}
-+
-+static void *
-+dma32_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->d32rxregs->status) & RS_CD_MASK, dma32dd_t)))
-+ 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->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow),
-+ di->rxbufsize, DMA_RX, rxp);
-+ W_SM(&di->rxd32[i].addr, 0xdeadbeef);
-+
-+ di->rxin = NEXTRXD(i);
-+
-+ return (rxp);
-+}
-+
-+static void
-+dma32_txrotate(di_t *di)
-+{
-+ uint ad;
-+ uint nactive;
-+ uint rot;
-+ uint old, new;
-+ uint32 w;
-+ uint first, last;
-+
-+ ASSERT(dma_txsuspendedidle(di));
-+
-+ nactive = dma_txactive(di);
-+ ad = B2I(((R_REG(&di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t);
-+ 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->txd32[old].ctrl) & ~CTRL_EOT;
-+ if (new == (di->ntxd - 1))
-+ w |= CTRL_EOT;
-+ W_SM(&di->txd32[new].ctrl, w);
-+ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr));
-+
-+ /* zap the old tx dma descriptor address field */
-+ W_SM(&di->txd32[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->d32txregs->ptr, I2B(di->txout, dma32dd_t));
-+}
-+
-+/*** 64 bits DMA non-inline functions ***/
-+
-+#ifdef BCMDMA64
-+
-+static bool
-+dma64_alloc(dma_info_t *di, uint direction)
-+{
-+ uint size;
-+ uint ddlen;
-+ uint32 alignbytes;
-+ void *va;
-+
-+ ddlen = sizeof (dma64dd_t);
-+
-+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
-+
-+ alignbytes = di->dma64align;
-+
-+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes))
-+ size += alignbytes;
-+
-+
-+ if (direction == DMA_TX) {
-+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) {
-+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
-+ return FALSE;
-+ }
-+
-+ di->txd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes);
-+ di->txdalign = (uint)((int8*)di->txd64 - (int8*)va);
-+ di->txdpa += di->txdalign;
-+ di->txdalloc = size;
-+ ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes));
-+ } else {
-+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) {
-+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
-+ return FALSE;
-+ }
-+ di->rxd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes);
-+ di->rxdalign = (uint)((int8*)di->rxd64 - (int8*)va);
-+ di->rxdpa += di->rxdalign;
-+ di->rxdalloc = size;
-+ ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes));
-+ }
-+
-+ return TRUE;
-+}
-+
-+static void
-+dma64_txreset(dma_info_t *di)
-+{
-+ uint32 status;
-+
-+ /* suspend tx DMA first */
-+ W_REG(&di->d64txregs->control, D64_XC_SE);
-+ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED &&
-+ status != D64_XS0_XS_IDLE &&
-+ status != D64_XS0_XS_STOPPED,
-+ 10000);
-+
-+ W_REG(&di->d64txregs->control, 0);
-+ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED,
-+ 10000);
-+
-+ if (status != D64_XS0_XS_DISABLED) {
-+ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name));
-+ }
-+
-+ /* wait for the last transaction to complete */
-+ OSL_DELAY(300);
-+}
-+
-+static void
-+dma64_rxreset(dma_info_t *di)
-+{
-+ uint32 status;
-+
-+ W_REG(&di->d64rxregs->control, 0);
-+ SPINWAIT((status = (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED,
-+ 10000);
-+
-+ if (status != D64_RS0_RS_DISABLED) {
-+ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name));
-+ }
-+}
-+
-+static bool
-+dma64_txsuspendedidle(dma_info_t *di)
-+{
-+
-+ if (!(R_REG(&di->d64txregs->control) & D64_XC_SE))
-+ return 0;
-+
-+ if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+/*
-+ * supports full 32bit dma engine buffer addressing so
-+ * dma buffers can cross 4 Kbyte page boundaries.
-+ */
-+static int
-+dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags)
-+{
-+ void *p, *next;
-+ uchar *data;
-+ uint len;
-+ uint txout;
-+ uint32 flags;
-+ uint32 pa;
-+
-+ DMA_TRACE(("%s: dma_txfast\n", di->name));
-+
-+ txout = di->txout;
-+ flags = 0;
-+
-+ /*
-+ * Walk the chain of packet buffers
-+ * allocating and initializing transmit descriptor entries.
-+ */
-+ for (p = p0; p; p = next) {
-+ data = PKTDATA(di->osh, p);
-+ len = PKTLEN(di->osh, p);
-+ next = PKTNEXT(di->osh, 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->osh, data, len, DMA_TX, p);
-+
-+ flags = coreflags;
-+
-+ if (p == p0)
-+ flags |= D64_CTRL1_SOF;
-+ if (next == NULL)
-+ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
-+ if (txout == (di->ntxd - 1))
-+ flags |= D64_CTRL1_EOT;
-+
-+ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
-+
-+ ASSERT(di->txp[txout] == NULL);
-+
-+ txout = NEXTTXD(txout);
-+ }
-+
-+ /* if last txd eof not set, fix it */
-+ if (!(flags & D64_CTRL1_EOF))
-+ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
-+
-+ /* save the packet */
-+ di->txp[PREVTXD(txout)] = p0;
-+
-+ /* bump the tx descriptor index */
-+ di->txout = txout;
-+
-+ /* kick the chip */
-+ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t));
-+
-+ /* 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->osh, p0, TRUE);
-+ di->txavail = 0;
-+ di->hnddma.txnobuf++;
-+ return (-1);
-+}
-+
-+static void*
-+dma64_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->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
-+
-+ if ((start == 0) && (end > di->txout))
-+ goto bogus;
-+
-+ for (i = start; i != end && !txp; i = NEXTTXD(i)) {
-+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow),
-+ (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK), DMA_TX, di->txp[i]);
-+
-+ W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
-+ W_SM(&di->txd64[i].addrhigh, 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);
-+}
-+
-+static void *
-+dma64_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->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t)))
-+ 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->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow),
-+ di->rxbufsize, DMA_RX, rxp);
-+
-+ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
-+ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
-+
-+ di->rxin = NEXTRXD(i);
-+
-+ return (rxp);
-+}
-+
-+static void
-+dma64_txrotate(di_t *di)
-+{
-+ uint ad;
-+ uint nactive;
-+ uint rot;
-+ uint old, new;
-+ uint32 w;
-+ uint first, last;
-+
-+ ASSERT(dma_txsuspendedidle(di));
-+
-+ nactive = dma_txactive(di);
-+ ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t);
-+ 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->txd64[old].ctrl1) & ~D64_CTRL1_EOT;
-+ if (new == (di->ntxd - 1))
-+ w |= D64_CTRL1_EOT;
-+ W_SM(&di->txd64[new].ctrl1, w);
-+
-+ w = R_SM(&di->txd64[old].ctrl2);
-+ W_SM(&di->txd64[new].ctrl2, w);
-+
-+ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
-+ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
-+
-+ /* zap the old tx dma descriptor address field */
-+ W_SM(&di->txd64[old].addrlow, 0xdeadbeef);
-+ W_SM(&di->txd64[old].addrhigh, 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->d64txregs->ptr, I2B(di->txout, dma64dd_t));
-+}
-+
-+#endif
-+
-diff -Nur linux-2.4.32/drivers/net/hnd/linux_osl.c linux-2.4.32-brcm/drivers/net/hnd/linux_osl.c
---- linux-2.4.32/drivers/net/hnd/linux_osl.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/net/hnd/linux_osl.c 2005-12-16 23:39:11.292858500 +0100
+diff -Naur linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_osl.c
+--- linux.old/drivers/net/hnd/linux_osl.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/hnd/linux_osl.c 2006-04-06 15:34:15.000000000 +0200
@@ -0,0 +1,708 @@
+/*
+ * Linux OS Independent Layer
@@ -14887,32 +12789,9 @@ diff -Nur linux-2.4.32/drivers/net/hnd/linux_osl.c linux-2.4.32-brcm/drivers/net
+
+
+#endif /* BINOSL */
-diff -Nur linux-2.4.32/drivers/net/hnd/Makefile linux-2.4.32-brcm/drivers/net/hnd/Makefile
---- linux-2.4.32/drivers/net/hnd/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/net/hnd/Makefile 2005-12-16 23:39:11.284858000 +0100
-@@ -0,0 +1,19 @@
-+#
-+# Makefile for the BCM47xx specific kernel interface routines
-+# under Linux.
-+#
-+
-+EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER
-+
-+O_TARGET := hnd.o
-+
-+HND_OBJS := bcmutils.o hnddma.o linux_osl.o sbutils.o bcmsrom.o
-+
-+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) > $@
-diff -Nur linux-2.4.32/drivers/net/hnd/sbutils.c linux-2.4.32-brcm/drivers/net/hnd/sbutils.c
---- linux-2.4.32/drivers/net/hnd/sbutils.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/net/hnd/sbutils.c 2005-12-16 23:39:11.316860000 +0100
+diff -Naur linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils.c
+--- linux.old/drivers/net/hnd/sbutils.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/hnd/sbutils.c 2006-04-06 15:34:15.000000000 +0200
@@ -0,0 +1,2837 @@
+/*
+ * Misc utility routines for accessing chip-specific features
@@ -17751,9 +15630,9 @@ diff -Nur linux-2.4.32/drivers/net/hnd/sbutils.c linux-2.4.32-brcm/drivers/net/h
+ return 0;
+}
+
-diff -Nur linux-2.4.32/drivers/net/hnd/shared_ksyms.sh linux-2.4.32-brcm/drivers/net/hnd/shared_ksyms.sh
---- linux-2.4.32/drivers/net/hnd/shared_ksyms.sh 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/net/hnd/shared_ksyms.sh 2005-12-16 23:39:11.316860000 +0100
+diff -Naur linux.old/drivers/net/hnd/shared_ksyms.sh linux.dev/drivers/net/hnd/shared_ksyms.sh
+--- linux.old/drivers/net/hnd/shared_ksyms.sh 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/hnd/shared_ksyms.sh 2006-04-06 15:34:15.000000000 +0200
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
@@ -17776,56 +15655,22 @@ diff -Nur linux-2.4.32/drivers/net/hnd/shared_ksyms.sh linux-2.4.32-brcm/drivers
+for file in $* ; do
+ ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p'
+done
-diff -Nur linux-2.4.32/drivers/net/Makefile linux-2.4.32-brcm/drivers/net/Makefile
---- linux-2.4.32/drivers/net/Makefile 2005-01-19 15:09:56.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/net/Makefile 2005-12-16 23:39:11.284858000 +0100
-@@ -3,6 +3,8 @@
- # Makefile for the Linux network (ethercard) device drivers.
- #
-
-+EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include
-+
- obj-y :=
- obj-m :=
- obj-n :=
-@@ -39,6 +41,8 @@
- obj-$(CONFIG_ISDN) += slhc.o
- endif
-
-+subdir-$(CONFIG_HND) += hnd
-+subdir-$(CONFIG_WL) += wl
- subdir-$(CONFIG_NET_PCMCIA) += pcmcia
- subdir-$(CONFIG_NET_WIRELESS) += wireless
- subdir-$(CONFIG_TULIP) += tulip
-@@ -69,6 +74,13 @@
- obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o
- obj-$(CONFIG_SUNGEM) += sungem.o
-
-+ifeq ($(CONFIG_HND),y)
-+ obj-y += hnd/hnd.o
-+endif
-+ifeq ($(CONFIG_WL),y)
-+ obj-y += wl/wl.o
-+endif
-+
- obj-$(CONFIG_MACE) += mace.o
- obj-$(CONFIG_BMAC) += bmac.o
- obj-$(CONFIG_GMAC) += gmac.o
-diff -Nur linux-2.4.32/drivers/net/wireless/Config.in linux-2.4.32-brcm/drivers/net/wireless/Config.in
---- linux-2.4.32/drivers/net/wireless/Config.in 2004-11-17 12:54:21.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/net/wireless/Config.in 2005-12-16 23:39:11.364863000 +0100
-@@ -13,6 +13,7 @@
+diff -Naur linux.old/drivers/net/wireless/Config.in linux.dev/drivers/net/wireless/Config.in
+--- linux.old/drivers/net/wireless/Config.in 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/drivers/net/wireless/Config.in 2006-04-06 17:04:48.000000000 +0200
+@@ -13,6 +13,8 @@
fi
if [ "$CONFIG_PCI" = "y" ]; then
-+ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL
++ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support (old)' CONFIG_WL
++ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support (new)' CONFIG_WL2
dep_tristate ' Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
dep_tristate ' Hermes in TMD7160/NCP130 based PCI adaptor support (Pheecom WL-PCI etc.) (EXPERIMENTAL)' CONFIG_TMD_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
dep_tristate ' Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
-diff -Nur linux-2.4.32/drivers/net/wl/Makefile linux-2.4.32-brcm/drivers/net/wl/Makefile
---- linux-2.4.32/drivers/net/wl/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/net/wl/Makefile 2005-12-16 23:39:11.364863000 +0100
-@@ -0,0 +1,26 @@
+diff -Naur linux.old/drivers/net/wl/Makefile linux.dev/drivers/net/wl/Makefile
+--- linux.old/drivers/net/wl/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl/Makefile 2006-04-06 16:56:38.000000000 +0200
+@@ -0,0 +1,27 @@
+#
+# Makefile for the Broadcom wl driver
+#
@@ -17839,7 +15684,7 @@ diff -Nur linux-2.4.32/drivers/net/wl/Makefile linux-2.4.32-brcm/drivers/net/wl/
+#
+# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $
+
-+EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include
++EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER
+
+O_TARGET := wl.o
+
@@ -17848,13 +15693,4529 @@ diff -Nur linux-2.4.32/drivers/net/wl/Makefile linux-2.4.32-brcm/drivers/net/wl/
+obj-y += apsta_rijndael-alg-fst.o apsta_sha1.o apsta_tkhash.o apsta_wlc_led.o
+obj-y += apsta_wlc_phy.o apsta_wlc_rate.o apsta_wlc_security.o
+obj-y += apsta_wlc_sup.o apsta_wlc_wet.o apsta_wl_linux.o apsta_wlc.o
++obj-y += compat.o hnddma.o
++
++obj-m := $(O_TARGET)
++
++include $(TOPDIR)/Rules.make
+diff -Naur linux.old/drivers/net/wl/compat.c linux.dev/drivers/net/wl/compat.c
+--- linux.old/drivers/net/wl/compat.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl/compat.c 2006-04-06 17:12:19.000000000 +0200
+@@ -0,0 +1,237 @@
++/*
++ * Misc useful OS-independent routines.
++ *
++ * Copyright 2005, 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>
++#ifdef BCMDRIVER
++#include <osl.h>
++#include <sbutils.h>
++#include <bcmnvram.h>
++#else
++#include <stdio.h>
++#include <string.h>
++#endif
++#include "pktq.h"
++#include <bcmutils.h>
++#include <bcmendian.h>
++#include <bcmdevs.h>
++
++#ifdef BCMDRIVER
++/* copy a pkt buffer chain into a buffer */
++uint
++pktcopy(osl_t *osh, 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(osh, p)) {
++ if (offset < (uint)PKTLEN(osh, p))
++ break;
++ offset -= PKTLEN(osh, p);
++ }
++
++ if (!p)
++ return 0;
++
++ /* copy the data */
++ for (; p && len; p = PKTNEXT(osh, p)) {
++ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len);
++ bcopy(PKTDATA(osh, p) + offset, buf, n);
++ buf += n;
++ len -= n;
++ ret += n;
++ offset = 0;
++ }
++
++ return ret;
++}
++
++/* return total length of buffer chain */
++uint
++pkttotlen(osl_t *osh, void *p)
++{
++ uint total;
++
++ total = 0;
++ for (; p; p = PKTNEXT(osh, p))
++ total += PKTLEN(osh, p);
++ return (total);
++}
++
++void
++pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[])
++{
++ q->head = q->tail = NULL;
++ q->maxlen = maxlen;
++ q->len = 0;
++ if (prio_map) {
++ q->priority = TRUE;
++ bcopy(prio_map, q->prio_map, sizeof(q->prio_map));
++ }
++ else
++ q->priority = FALSE;
++}
++
++
++/* should always check pktq_full before calling pktenq */
++void
++pktenq(struct pktq *q, void *p, bool lifo)
++{
++ void *next, *prev;
++
++ /* allow 10 pkts slack */
++ ASSERT(q->len < (q->maxlen + 10));
++
++ /* 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 {
++ /* legal priorities 0-7 */
++ ASSERT(PKTPRIO(p) <= MAXPRIO);
++
++ ASSERT(q->head);
++ ASSERT(q->tail);
++ /* Shortcut to insertion at tail */
++ if (_pktq_pri(q, PKTPRIO(p)) < _pktq_pri(q, PKTPRIO(q->tail)) ||
++ (!lifo && _pktq_pri(q, PKTPRIO(p)) <= _pktq_pri(q, 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 || _pktq_pri(q, PKTPRIO(prev)) >= _pktq_pri(q, PKTPRIO(next)));
++ /* Insert at head of string of packets of same priority (LIFO) */
++ if (lifo) {
++ if (_pktq_pri(q, PKTPRIO(p)) >= _pktq_pri(q, PKTPRIO(next)))
++ break;
++ }
++ /* Insert at tail of string of packets of same priority (FIFO) */
++ else {
++ if (_pktq_pri(q, PKTPRIO(p)) > _pktq_pri(q, 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++;
++}
++
++/* dequeue packet at head */
++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);
++}
++
++/* dequeue packet at tail */
++void*
++pktdeqtail(struct pktq *q)
++{
++ void *p;
++ void *next, *prev;
++
++ if (q->head == q->tail) { /* last packet on queue or queue empty */
++ p = q->head;
++ q->head = q->tail = NULL;
++ q->len = 0;
++ return(p);
++ }
++
++ /* start walk at head */
++ prev = NULL;
++ next = q->head;
++
++ /* Walk the queue to find prev of q->tail */
++ for (; next; prev = next, next = PKTLINK(next)) {
++ if (next == q->tail)
++ break;
++ }
++
++ ASSERT(prev);
++
++ PKTSETLINK(prev, NULL);
++ q->tail = prev;
++ q->len--;
++ p = next;
++
++ return (p);
++}
++#endif
++
++
+diff -Naur linux.old/drivers/net/wl/hnddma.c linux.dev/drivers/net/wl/hnddma.c
+--- linux.old/drivers/net/wl/hnddma.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl/hnddma.c 2006-04-06 16:58:24.000000000 +0200
+@@ -0,0 +1,1453 @@
++/*
++ * Generic Broadcom Home Networking Division (HND) DMA module.
++ * This supports the following chips: BCM42xx, 44xx, 47xx .
++ *
++ * Copyright 2005, 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 <sbconfig.h>
++#include <bcmutils.h>
++#include <bcmdevs.h>
++#include <sbutils.h>
++
++struct dma_info; /* forward declaration */
++#define di_t struct dma_info
++
++#include "sbhnddma.h"
++#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
++
++/* 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 *osh; /* os handle */
++ sb_t *sbh; /* sb handle */
++
++ bool dma64; /* dma64 enabled */
++ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
++
++ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */
++ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */
++ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */
++ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */
++
++ uint32 dma64align; /* either 8k or 4k depends on number of dd */
++ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */
++ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */
++ uint ntxd; /* # tx descriptors tunable */
++ uint txin; /* index of next descriptor to reclaim */
++ uint txout; /* index of next descriptor to post */
++ uint txavail; /* # free tx descriptors */
++ void **txp; /* pointer to parallel array of pointers to packets */
++ ulong txdpa; /* physical address of descriptor ring */
++ uint txdalign; /* #bytes added to alloc'd mem to align txd */
++ uint txdalloc; /* #bytes allocated for the ring */
++
++ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */
++ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */
++ uint nrxd; /* # rx descriptors tunable */
++ uint rxin; /* index of next descriptor to reclaim */
++ uint rxout; /* index of next descriptor to post */
++ void **rxp; /* pointer to parallel array of pointers to packets */
++ ulong rxdpa; /* physical address of descriptor ring */
++ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */
++ uint rxdalloc; /* #bytes allocated for the ring */
++
++ /* tunables */
++ uint rxbufsize; /* rx buffer size in bytes */
++ uint nrxpost; /* # rx buffers to keep posted */
++ uint rxoffset; /* rxcontrol offset */
++ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */
++ uint ddoffsethigh; /* add to get dma address of descriptor ring, high 32 bits */
++ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */
++ uint dataoffsethigh; /* add to get dma address of data buffer, high 32 bits */
++} dma_info_t;
++
++#ifdef BCMDMA64
++#define DMA64_ENAB(di) ((di)->dma64)
++#else
++#define DMA64_ENAB(di) (0)
++#endif
++
++/* descriptor bumping macros */
++#define XXD(x, n) ((x) & ((n) - 1))
++#define TXD(x) XXD((x), di->ntxd)
++#define RXD(x) XXD((x), di->nrxd)
++#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, type) ((bytes) / sizeof(type))
++#define I2B(index, type) ((index) * sizeof(type))
++
++#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */
++#define PCI32ADDR_HIGH_SHIFT 30
++
++
++/* prototypes */
++static bool dma_isaddrext(dma_info_t *di);
++static bool dma_alloc(dma_info_t *di, uint direction);
++
++static bool dma32_alloc(dma_info_t *di, uint direction);
++static void dma32_txreset(dma_info_t *di);
++static void dma32_rxreset(dma_info_t *di);
++static bool dma32_txsuspendedidle(dma_info_t *di);
++static int dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags);
++static void* dma32_getnexttxp(dma_info_t *di, bool forceall);
++static void* dma32_getnextrxp(dma_info_t *di, bool forceall);
++static void dma32_txrotate(di_t *di);
++
++/* prototype or stubs */
++#ifdef BCMDMA64
++static bool dma64_alloc(dma_info_t *di, uint direction);
++static void dma64_txreset(dma_info_t *di);
++static void dma64_rxreset(dma_info_t *di);
++static bool dma64_txsuspendedidle(dma_info_t *di);
++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags);
++static void* dma64_getnexttxp(dma_info_t *di, bool forceall);
++static void* dma64_getnextrxp(dma_info_t *di, bool forceall);
++static void dma64_txrotate(di_t *di);
++#else
++static bool dma64_alloc(dma_info_t *di, uint direction) { return TRUE; }
++static void dma64_txreset(dma_info_t *di) {}
++static void dma64_rxreset(dma_info_t *di) {}
++static bool dma64_txsuspendedidle(dma_info_t *di) { return TRUE;}
++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) { return 0; }
++static void* dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; }
++static void* dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; }
++static void dma64_txrotate(di_t *di) { return; }
++#endif
++
++/* old dmaregs struct for compatibility */
++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;
++
++void*
++dma_attach(void *drv, void *osh, 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;
++ uint size;
++ dma32regs_t *dmaregstx = regs;
++ dma32regs_t *dmaregsrx = dmaregstx + 1;
++
++ /* allocate private info structure */
++ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) {
++ return (NULL);
++ }
++ bzero((char*)di, sizeof (dma_info_t));
++ di->msg_level = msg_level ? msg_level : &dma_msg_level;
++
++ /* check arguments */
++ ASSERT(ISPOWEROF2(ntxd));
++ ASSERT(ISPOWEROF2(nrxd));
++ if (nrxd == 0)
++ ASSERT(dmaregsrx == NULL);
++ if (ntxd == 0)
++ ASSERT(dmaregstx == NULL);
++
++ ASSERT(ntxd <= D32MAXDD);
++ ASSERT(nrxd <= D32MAXDD);
++ di->d32txregs = (dma32regs_t *)dmaregstx;
++ di->d32rxregs = (dma32regs_t *)dmaregsrx;
++
++ /* make a private copy of our callers name */
++ strncpy(di->name, name, MAXNAMEL);
++ di->name[MAXNAMEL-1] = '\0';
++
++ di->osh = osh;
++ di->sbh = NULL;
++
++ /* save tunables */
++ di->ntxd = ntxd;
++ di->nrxd = nrxd;
++ di->rxbufsize = rxbufsize;
++ di->nrxpost = nrxpost;
++ di->rxoffset = rxoffset;
++
++ di->ddoffsetlow = ddoffset;
++ di->dataoffsetlow = dataoffset;
++ di->ddoffsethigh = 0;
++ di->dataoffsethigh = 0;
++
++ di->addrext = 0;
++
++ DMA_TRACE(("%s: dma_attach: osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n",
++ name, osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, di->ddoffsetlow, di->dataoffsetlow));
++
++ /* allocate tx packet pointer vector */
++ if (ntxd) {
++ size = ntxd * sizeof (void*);
++ if ((di->txp = MALLOC(osh, size)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh)));
++ goto fail;
++ }
++ bzero((char*)di->txp, size);
++ }
++
++ /* allocate rx packet pointer vector */
++ if (nrxd) {
++ size = nrxd * sizeof (void*);
++ if ((di->rxp = MALLOC(osh, size)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh)));
++ goto fail;
++ }
++ bzero((char*)di->rxp, size);
++ }
++
++ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
++ if (ntxd) {
++ if (!dma_alloc(di, DMA_TX))
++ goto fail;
++ }
++
++ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
++ if (nrxd) {
++ if (!dma_alloc(di, DMA_RX))
++ goto fail;
++ }
++
++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) {
++ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", di->name, di->txdpa));
++ goto fail;
++ }
++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) {
++ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", di->name, di->rxdpa));
++ goto fail;
++ }
++
++ return ((void*)di);
++
++fail:
++ dma_detach((void*)di);
++ return (NULL);
++}
++
++
++static bool
++dma_alloc(dma_info_t *di, uint direction)
++{
++ if (DMA64_ENAB(di)) {
++ return dma64_alloc(di, direction);
++ } else {
++ return dma32_alloc(di, direction);
++ }
++}
++
++/* 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->txd32)
++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), di->txdalloc, (di->txdpa - di->txdalign));
++ if (di->rxd32)
++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), di->rxdalloc, (di->rxdpa - di->rxdalign));
++
++ /* free packet pointer vectors */
++ if (di->txp)
++ MFREE(di->osh, (void*)di->txp, (di->ntxd * sizeof (void*)));
++ if (di->rxp)
++ MFREE(di->osh, (void*)di->rxp, (di->nrxd * sizeof (void*)));
++
++ /* free our private info structure */
++ MFREE(di->osh, (void*)di, sizeof (dma_info_t));
++}
++
++/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */
++static bool
++dma_isaddrext(dma_info_t *di)
++{
++ uint32 w;
++
++ if (DMA64_ENAB(di)) {
++ OR_REG(&di->d64txregs->control, D64_XC_AE);
++ w = R_REG(&di->d32txregs->control);
++ AND_REG(&di->d32txregs->control, ~D64_XC_AE);
++ return ((w & XC_AE) == D64_XC_AE);
++ } else {
++ OR_REG(&di->d32txregs->control, XC_AE);
++ w = R_REG(&di->d32txregs->control);
++ AND_REG(&di->d32txregs->control, ~XC_AE);
++ return ((w & XC_AE) == XC_AE);
++ }
++}
++
++void
++dma_txreset(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_txreset\n", di->name));
++
++ if (DMA64_ENAB(di))
++ dma64_txreset(di);
++ else
++ dma32_txreset(di);
++}
++
++void
++dma_rxreset(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_rxreset\n", di->name));
++
++ if (DMA64_ENAB(di))
++ dma64_rxreset(di);
++ else
++ dma32_rxreset(di);
++}
++
++/* initialize descriptor table base address */
++static void
++dma_ddtable_init(dma_info_t *di, uint direction, ulong pa)
++{
++ if (DMA64_ENAB(di)) {
++ if (direction == DMA_TX) {
++ W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow);
++ W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh);
++ } else {
++ W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow);
++ W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh);
++ }
++ } else {
++ uint32 offset = di->ddoffsetlow;
++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
++ if (direction == DMA_TX)
++ W_REG(&di->d32txregs->addr, (pa + offset));
++ else
++ W_REG(&di->d32rxregs->addr, (pa + offset));
++ } else {
++ /* dma32 address extension */
++ uint32 ae;
++ ASSERT(di->addrext);
++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
++
++ if (direction == DMA_TX) {
++ W_REG(&di->d32txregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset));
++ SET_REG(&di->d32txregs->control, XC_AE, (ae << XC_AE_SHIFT));
++ } else {
++ W_REG(&di->d32rxregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset));
++ SET_REG(&di->d32rxregs->control, RC_AE, (ae << RC_AE_SHIFT));
++ }
++ }
++ }
++}
++
++/* init the tx or rx descriptor */
++static INLINE void
++dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *ctrl)
++{
++ uint offset = di->dataoffsetlow;
++
++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
++ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + offset));
++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl));
++ } else {
++ /* address extension */
++ uint32 ae;
++ ASSERT(di->addrext);
++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
++
++ *ctrl |= (ae << CTRL_AE_SHIFT);
++ W_SM(&ddring[outidx].addr, BUS_SWAP32((pa & ~PCI32ADDR_HIGH) + offset));
++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl));
++ }
++}
++
++/* init the tx or rx descriptor */
++static INLINE void
++dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, uint32 bufcount)
++{
++ uint32 bufaddr_low = pa + di->dataoffsetlow;
++ uint32 bufaddr_high = 0 + di->dataoffsethigh;
++
++ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
++
++ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(bufaddr_low));
++ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(bufaddr_high));
++ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
++ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
++}
++
++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 */
++ if (DMA64_ENAB(di)) {
++ BZERO_SM((void*)di->txd64, (di->ntxd * sizeof (dma64dd_t)));
++ W_REG(&di->d64txregs->control, XC_XE);
++ dma_ddtable_init(di, DMA_TX, di->txdpa);
++ } else {
++ BZERO_SM((void*)di->txd32, (di->ntxd * sizeof (dma32dd_t)));
++ W_REG(&di->d32txregs->control, XC_XE);
++ dma_ddtable_init(di, DMA_TX, di->txdpa);
++ }
++}
++
++bool
++dma_txenabled(dma_info_t *di)
++{
++ uint32 xc;
++
++ /* If the chip is dead, it is not enabled :-) */
++ if (DMA64_ENAB(di)) {
++ xc = R_REG(&di->d64txregs->control);
++ return ((xc != 0xffffffff) && (xc & D64_XC_XE));
++ } else {
++ xc = R_REG(&di->d32txregs->control);
++ return ((xc != 0xffffffff) && (xc & XC_XE));
++ }
++}
++
++void
++dma_txsuspend(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_txsuspend\n", di->name));
++ if (DMA64_ENAB(di))
++ OR_REG(&di->d64txregs->control, D64_XC_SE);
++ else
++ OR_REG(&di->d32txregs->control, XC_SE);
++}
++
++void
++dma_txresume(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_txresume\n", di->name));
++ if (DMA64_ENAB(di))
++ AND_REG(&di->d64txregs->control, ~D64_XC_SE);
++ else
++ AND_REG(&di->d32txregs->control, ~XC_SE);
++}
++
++bool
++dma_txsuspendedidle(dma_info_t *di)
++{
++ if (DMA64_ENAB(di))
++ return dma64_txsuspendedidle(di);
++ else
++ return dma32_txsuspendedidle(di);
++}
++
++bool
++dma_txsuspended(dma_info_t *di)
++{
++ if (DMA64_ENAB(di))
++ return ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE);
++ else
++ return ((R_REG(&di->d32txregs->control) & XC_SE) == XC_SE);
++}
++
++bool
++dma_txstopped(dma_info_t *di)
++{
++ if (DMA64_ENAB(di))
++ return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED);
++ else
++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED);
++}
++
++bool
++dma_rxstopped(dma_info_t *di)
++{
++ if (DMA64_ENAB(di))
++ return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED);
++ else
++ return ((R_REG(&di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED);
++}
++
++void
++dma_fifoloopbackenable(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
++ if (DMA64_ENAB(di))
++ OR_REG(&di->d64txregs->control, D64_XC_LE);
++ else
++ OR_REG(&di->d32txregs->control, 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 */
++ if (DMA64_ENAB(di)) {
++ BZERO_SM((void*)di->rxd64, (di->nrxd * sizeof (dma64dd_t)));
++ dma_rxenable(di);
++ dma_ddtable_init(di, DMA_RX, di->rxdpa);
++ } else {
++ BZERO_SM((void*)di->rxd32, (di->nrxd * sizeof (dma32dd_t)));
++ dma_rxenable(di);
++ dma_ddtable_init(di, DMA_RX, di->rxdpa);
++ }
++}
++
++void
++dma_rxenable(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_rxenable\n", di->name));
++ if (DMA64_ENAB(di))
++ W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE));
++ else
++ W_REG(&di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE));
++}
++
++bool
++dma_rxenabled(dma_info_t *di)
++{
++ uint32 rc;
++
++ if (DMA64_ENAB(di)) {
++ rc = R_REG(&di->d64rxregs->control);
++ return ((rc != 0xffffffff) && (rc & D64_RC_RE));
++ } else {
++ rc = R_REG(&di->d32rxregs->control);
++ return ((rc != 0xffffffff) && (rc & RC_RE));
++ }
++}
++
++
++/* !! tx entry routine */
++int
++dma_txfast(dma_info_t *di, void *p0, uint32 coreflags)
++{
++ if (DMA64_ENAB(di)) {
++ return dma64_txfast(di, p0, coreflags);
++ } else {
++ return dma32_txfast(di, p0, coreflags);
++ }
++}
++
++/* !! rx entry routine, 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->osh, p, FALSE);
++ continue;
++ }
++
++ len = ltoh16(*(uint16*)(PKTDATA(di->osh, 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->osh, p, FALSE);
++ di->hnddma.rxgiants++;
++ continue;
++ }
++
++ /* set actual length */
++ PKTSETLEN(di->osh, p, (di->rxoffset + len));
++
++ break;
++ }
++
++ return (p);
++}
++
++/* post receive buffers */
++void
++dma_rxfill(dma_info_t *di)
++{
++ void *p;
++ uint rxin, rxout;
++ uint32 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->osh, rxbufsize, FALSE)) == NULL) {
++ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name));
++ di->hnddma.rxnobuf++;
++ break;
++ }
++
++ /* Do a cached write instead of uncached write since DMA_MAP
++ * will flush the cache. */
++ *(uint32*)(PKTDATA(di->osh, p)) = 0;
++
++ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p);
++ ASSERT(ISALIGNED(pa, 4));
++
++ /* save the free packet pointer */
++ ASSERT(di->rxp[rxout] == NULL);
++ di->rxp[rxout] = p;
++
++ if (DMA64_ENAB(di)) {
++ /* prep the descriptor control value */
++ if (rxout == (di->nrxd - 1))
++ ctrl = CTRL_EOT;
++
++ dma64_dd_upd(di, di->rxd64, pa, rxout, &ctrl, rxbufsize);
++ } else {
++ /* prep the descriptor control value */
++ ctrl = rxbufsize;
++ if (rxout == (di->nrxd - 1))
++ ctrl |= CTRL_EOT;
++ dma32_dd_upd(di, di->rxd32, pa, rxout, &ctrl);
++ }
++
++ rxout = NEXTRXD(rxout);
++ }
++
++ di->rxout = rxout;
++
++ /* update the chip lastdscr pointer */
++ if (DMA64_ENAB(di)) {
++ W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t));
++ } else {
++ W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t));
++ }
++}
++
++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->osh, 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)
++{
++ if (DMA64_ENAB(di)) {
++ return dma64_getnexttxp(di, forceall);
++ } else {
++ return dma32_getnexttxp(di, forceall);
++ }
++}
++
++/* like getnexttxp but no reclaim */
++void*
++dma_peeknexttxp(dma_info_t *di)
++{
++ uint end, i;
++
++ if (DMA64_ENAB(di)) {
++ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
++ } else {
++ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
++ }
++
++ for (i = di->txin; i != end; i = NEXTTXD(i))
++ if (di->txp[i])
++ return (di->txp[i]);
++
++ return (NULL);
++}
++
++/*
++ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
++ */
++void
++dma_txrotate(di_t *di)
++{
++ if (DMA64_ENAB(di)) {
++ dma64_txrotate(di);
++ } else {
++ dma32_txrotate(di);
++ }
++}
++
++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->osh, p, FALSE);
++}
++
++void *
++dma_getnextrxp(dma_info_t *di, bool forceall)
++{
++ if (DMA64_ENAB(di)) {
++ return dma64_getnextrxp(di, forceall);
++ } else {
++ return dma32_getnextrxp(di, forceall);
++ }
++}
++
++uintptr
++dma_getvar(dma_info_t *di, char *name)
++{
++ if (!strcmp(name, "&txavail"))
++ return ((uintptr) &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));
++}
++
++void
++dma_rxpiomode(dma32regs_t *regs)
++{
++ W_REG(&regs->control, RC_FM);
++}
++
++void
++dma_txpioloopback(dma32regs_t *regs)
++{
++ OR_REG(&regs->control, XC_LE);
++}
++
++
++
++
++/*** 32 bits DMA non-inline functions ***/
++static bool
++dma32_alloc(dma_info_t *di, uint direction)
++{
++ uint size;
++ uint ddlen;
++ void *va;
++
++ ddlen = sizeof (dma32dd_t);
++
++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
++
++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN))
++ size += D32RINGALIGN;
++
++
++ if (direction == DMA_TX) {
++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
++ return FALSE;
++ }
++
++ di->txd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN);
++ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va);
++ di->txdpa += di->txdalign;
++ di->txdalloc = size;
++ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN));
++ } else {
++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
++ return FALSE;
++ }
++ di->rxd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN);
++ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va);
++ di->rxdpa += di->rxdalign;
++ di->rxdalloc = size;
++ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN));
++ }
++
++ return TRUE;
++}
++
++static void
++dma32_txreset(dma_info_t *di)
++{
++ uint32 status;
++
++ /* suspend tx DMA first */
++ W_REG(&di->d32txregs->control, XC_SE);
++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED &&
++ status != XS_XS_IDLE &&
++ status != XS_XS_STOPPED,
++ 10000);
++
++ W_REG(&di->d32txregs->control, 0);
++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & 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);
++}
++
++static void
++dma32_rxreset(dma_info_t *di)
++{
++ uint32 status;
++
++ W_REG(&di->d32rxregs->control, 0);
++ SPINWAIT((status = (R_REG(&di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED,
++ 10000);
++
++ if (status != RS_RS_DISABLED) {
++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name));
++ }
++}
++
++static bool
++dma32_txsuspendedidle(dma_info_t *di)
++{
++ if (!(R_REG(&di->d32txregs->control) & XC_SE))
++ return 0;
++
++ if ((R_REG(&di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE)
++ return 0;
++
++ OSL_DELAY(2);
++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE);
++}
++
++/*
++ * supports full 32bit dma engine buffer addressing so
++ * dma buffers can cross 4 Kbyte page boundaries.
++ */
++static int
++dma32_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->osh, p);
++ len = PKTLEN(di->osh, p);
++ next = PKTNEXT(di->osh, 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->osh, 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;
++
++ if (DMA64_ENAB(di)) {
++ dma64_dd_upd(di, di->txd64, pa, txout, &ctrl, len);
++ } else {
++ dma32_dd_upd(di, di->txd32, pa, txout, &ctrl);
++ }
++
++ ASSERT(di->txp[txout] == NULL);
++
++ txout = NEXTTXD(txout);
++ }
++
++ /* if last txd eof not set, fix it */
++ if (!(ctrl & CTRL_EOF))
++ W_SM(&di->txd32[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 */
++ if (DMA64_ENAB(di)) {
++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t));
++ } else {
++ W_REG(&di->d32txregs->ptr, I2B(txout, dma32dd_t));
++ }
++
++ /* 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->osh, p0, TRUE);
++ di->txavail = 0;
++ di->hnddma.txnobuf++;
++ return (-1);
++}
++
++static void*
++dma32_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->d32txregs->status) & XS_CD_MASK, dma32dd_t);
++
++ if ((start == 0) && (end > di->txout))
++ goto bogus;
++
++ for (i = start; i != end && !txp; i = NEXTTXD(i)) {
++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow),
++ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]);
++
++ W_SM(&di->txd32[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);
++}
++
++static void *
++dma32_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->d32rxregs->status) & RS_CD_MASK, dma32dd_t)))
++ 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->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow),
++ di->rxbufsize, DMA_RX, rxp);
++ W_SM(&di->rxd32[i].addr, 0xdeadbeef);
++
++ di->rxin = NEXTRXD(i);
++
++ return (rxp);
++}
++
++static void
++dma32_txrotate(di_t *di)
++{
++ uint ad;
++ uint nactive;
++ uint rot;
++ uint old, new;
++ uint32 w;
++ uint first, last;
++
++ ASSERT(dma_txsuspendedidle(di));
++
++ nactive = dma_txactive(di);
++ ad = B2I(((R_REG(&di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t);
++ 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->txd32[old].ctrl) & ~CTRL_EOT;
++ if (new == (di->ntxd - 1))
++ w |= CTRL_EOT;
++ W_SM(&di->txd32[new].ctrl, w);
++ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr));
++
++ /* zap the old tx dma descriptor address field */
++ W_SM(&di->txd32[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->d32txregs->ptr, I2B(di->txout, dma32dd_t));
++}
++
++/*** 64 bits DMA non-inline functions ***/
++
++#ifdef BCMDMA64
++
++static bool
++dma64_alloc(dma_info_t *di, uint direction)
++{
++ uint size;
++ uint ddlen;
++ uint32 alignbytes;
++ void *va;
++
++ ddlen = sizeof (dma64dd_t);
++
++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
++
++ alignbytes = di->dma64align;
++
++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes))
++ size += alignbytes;
++
++
++ if (direction == DMA_TX) {
++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
++ return FALSE;
++ }
++
++ di->txd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes);
++ di->txdalign = (uint)((int8*)di->txd64 - (int8*)va);
++ di->txdpa += di->txdalign;
++ di->txdalloc = size;
++ ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes));
++ } else {
++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
++ return FALSE;
++ }
++ di->rxd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes);
++ di->rxdalign = (uint)((int8*)di->rxd64 - (int8*)va);
++ di->rxdpa += di->rxdalign;
++ di->rxdalloc = size;
++ ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes));
++ }
++
++ return TRUE;
++}
++
++static void
++dma64_txreset(dma_info_t *di)
++{
++ uint32 status;
++
++ /* suspend tx DMA first */
++ W_REG(&di->d64txregs->control, D64_XC_SE);
++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED &&
++ status != D64_XS0_XS_IDLE &&
++ status != D64_XS0_XS_STOPPED,
++ 10000);
++
++ W_REG(&di->d64txregs->control, 0);
++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED,
++ 10000);
++
++ if (status != D64_XS0_XS_DISABLED) {
++ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name));
++ }
++
++ /* wait for the last transaction to complete */
++ OSL_DELAY(300);
++}
++
++static void
++dma64_rxreset(dma_info_t *di)
++{
++ uint32 status;
++
++ W_REG(&di->d64rxregs->control, 0);
++ SPINWAIT((status = (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED,
++ 10000);
++
++ if (status != D64_RS0_RS_DISABLED) {
++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name));
++ }
++}
++
++static bool
++dma64_txsuspendedidle(dma_info_t *di)
++{
++
++ if (!(R_REG(&di->d64txregs->control) & D64_XC_SE))
++ return 0;
++
++ if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE)
++ return 1;
++
++ return 0;
++}
++
++/*
++ * supports full 32bit dma engine buffer addressing so
++ * dma buffers can cross 4 Kbyte page boundaries.
++ */
++static int
++dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags)
++{
++ void *p, *next;
++ uchar *data;
++ uint len;
++ uint txout;
++ uint32 flags;
++ uint32 pa;
++
++ DMA_TRACE(("%s: dma_txfast\n", di->name));
++
++ txout = di->txout;
++ flags = 0;
++
++ /*
++ * Walk the chain of packet buffers
++ * allocating and initializing transmit descriptor entries.
++ */
++ for (p = p0; p; p = next) {
++ data = PKTDATA(di->osh, p);
++ len = PKTLEN(di->osh, p);
++ next = PKTNEXT(di->osh, 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->osh, data, len, DMA_TX, p);
++
++ flags = coreflags;
++
++ if (p == p0)
++ flags |= D64_CTRL1_SOF;
++ if (next == NULL)
++ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
++ if (txout == (di->ntxd - 1))
++ flags |= D64_CTRL1_EOT;
++
++ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
++
++ ASSERT(di->txp[txout] == NULL);
++
++ txout = NEXTTXD(txout);
++ }
++
++ /* if last txd eof not set, fix it */
++ if (!(flags & D64_CTRL1_EOF))
++ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
++
++ /* save the packet */
++ di->txp[PREVTXD(txout)] = p0;
++
++ /* bump the tx descriptor index */
++ di->txout = txout;
++
++ /* kick the chip */
++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t));
++
++ /* 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->osh, p0, TRUE);
++ di->txavail = 0;
++ di->hnddma.txnobuf++;
++ return (-1);
++}
++
++static void*
++dma64_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->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
++
++ if ((start == 0) && (end > di->txout))
++ goto bogus;
++
++ for (i = start; i != end && !txp; i = NEXTTXD(i)) {
++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow),
++ (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK), DMA_TX, di->txp[i]);
++
++ W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
++ W_SM(&di->txd64[i].addrhigh, 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);
++}
++
++static void *
++dma64_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->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t)))
++ 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->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow),
++ di->rxbufsize, DMA_RX, rxp);
++
++ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
++ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
++
++ di->rxin = NEXTRXD(i);
++
++ return (rxp);
++}
++
++static void
++dma64_txrotate(di_t *di)
++{
++ uint ad;
++ uint nactive;
++ uint rot;
++ uint old, new;
++ uint32 w;
++ uint first, last;
++
++ ASSERT(dma_txsuspendedidle(di));
++
++ nactive = dma_txactive(di);
++ ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t);
++ 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->txd64[old].ctrl1) & ~D64_CTRL1_EOT;
++ if (new == (di->ntxd - 1))
++ w |= D64_CTRL1_EOT;
++ W_SM(&di->txd64[new].ctrl1, w);
++
++ w = R_SM(&di->txd64[old].ctrl2);
++ W_SM(&di->txd64[new].ctrl2, w);
++
++ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
++ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
++
++ /* zap the old tx dma descriptor address field */
++ W_SM(&di->txd64[old].addrlow, 0xdeadbeef);
++ W_SM(&di->txd64[old].addrhigh, 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->d64txregs->ptr, I2B(di->txout, dma64dd_t));
++}
++
++#endif
++
+diff -Naur linux.old/drivers/net/wl/hnddma.h linux.dev/drivers/net/wl/hnddma.h
+--- linux.old/drivers/net/wl/hnddma.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl/hnddma.h 2006-04-06 16:57:44.000000000 +0200
+@@ -0,0 +1,69 @@
++/*
++ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface
++ * This supports the following chips: BCM42xx, 44xx, 47xx .
++ *
++ * Copyright 2005, 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_
++
++/* 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
++
++#ifndef osl_t
++#define osl_t void
++#endif
++
++/* externs */
++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_txsuspendedidle(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 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 uintptr 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);
++
++extern void dma_rxpiomode(dma32regs_t *);
++extern void dma_txpioloopback(dma32regs_t *);
++
++
++#endif /* _hnddma_h_ */
+diff -Naur linux.old/drivers/net/wl/pktq.h linux.dev/drivers/net/wl/pktq.h
+--- linux.old/drivers/net/wl/pktq.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl/pktq.h 2006-04-06 17:32:52.000000000 +0200
+@@ -0,0 +1,48 @@
++/*
++ * Misc useful os-independent macros and functions.
++ *
++ * Copyright 2005, 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 _pktq_h_
++#define _pktq_h_
++
++/*** driver-only section ***/
++#ifdef BCMDRIVER
++
++/* 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 */
++ uint8 prio_map[MAXPRIO+1]; /* user priority to packet enqueue policy map */
++};
++#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)
++#define _pktq_pri(q, pri) ((q)->prio_map[pri])
++#define pktq_tailpri(q) ((q)->tail ? _pktq_pri(q, PKTPRIO((q)->tail)) : _pktq_pri(q, 0))
++
++/* externs */
++/* packet */
++extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf);
++extern uint pkttotlen(osl_t *osh, void *);
++extern void pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]);
++extern void pktenq(struct pktq *q, void *p, bool lifo);
++extern void *pktdeq(struct pktq *q);
++extern void *pktdeqtail(struct pktq *q);
++
++#endif
++#endif /* _pktq_h_ */
+diff -Naur linux.old/drivers/net/wl/sbhnddma.h linux.dev/drivers/net/wl/sbhnddma.h
+--- linux.old/drivers/net/wl/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl/sbhnddma.h 2006-04-06 15:34:14.000000000 +0200
+@@ -0,0 +1,312 @@
++/*
++ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface
++ * This supports the following chips: BCM42xx, 44xx, 47xx .
++ *
++ * Copyright 2005, 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 _sbhnddma_h_
++#define _sbhnddma_h_
++
++
++/* 2byte-wide pio register set per channel(xmt or rcv) */
++typedef volatile struct {
++ uint16 fifocontrol;
++ uint16 fifodata;
++ uint16 fifofree; /* only valid in xmt channel, not in rcv channel */
++ uint16 PAD;
++} pio2regs_t;
++
++/* a pair of pio channels(tx and rx) */
++typedef volatile struct {
++ pio2regs_t tx;
++ pio2regs_t rx;
++} pio2regp_t;
++
++/* 4byte-wide pio register set per channel(xmt or rcv) */
++typedef volatile struct {
++ uint32 fifocontrol;
++ uint32 fifodata;
++} pio4regs_t;
++
++/* a pair of pio channels(tx and rx) */
++typedef volatile struct {
++ pio4regs_t tx;
++ pio4regs_t rx;
++} pio4regp_t;
++
++
++
++/* DMA structure:
++ * support two DMA engines: 32 bits address or 64 bit addressing
++ * basic DMA register set is per channel(transmit or receive)
++ * a pair of channels is defined for convenience
++ */
++
++
++/*** 32 bits addressing ***/
++
++/* dma registers per channel(xmt or rcv) */
++typedef volatile struct {
++ uint32 control; /* enable, et al */
++ uint32 addr; /* descriptor ring base address (4K aligned) */
++ uint32 ptr; /* last descriptor posted to chip */
++ uint32 status; /* current active descriptor, et al */
++} dma32regs_t;
++
++typedef volatile struct {
++ dma32regs_t xmt; /* dma tx channel */
++ dma32regs_t rcv; /* dma rx channel */
++} dma32regp_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 */
++} dma32diag_t;
++
++/*
++ * 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 */
++} dma32dd_t;
++
++/*
++ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page.
++ */
++#define D32MAXRINGSZ 4096
++#define D32RINGALIGN 4096
++#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_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 */
++#define XC_AE ((uint32)3 << 16) /* address extension bits */
++#define XC_AE_SHIFT 16
++
++/* 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 */
++#define RC_AE ((uint32)3 << 16) /* address extension bits */
++#define RC_AE_SHIFT 16
++
++/* 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 */
++#define FA_SEL_RSD 0xe0000 /* receive frame status data */
++#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */
++
++/* descriptor control flags */
++#define CTRL_BC_MASK 0x1fff /* buffer byte count */
++#define CTRL_AE ((uint32)3 << 16) /* address extension bits */
++#define CTRL_AE_SHIFT 16
++#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
++
++/*** 64 bits addressing ***/
++
++/* dma registers per channel(xmt or rcv) */
++typedef volatile struct {
++ uint32 control; /* enable, et al */
++ uint32 ptr; /* last descriptor posted to chip */
++ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */
++ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */
++ uint32 status0; /* current descriptor, xmt state */
++ uint32 status1; /* active descriptor, xmt error */
++} dma64regs_t;
++
++typedef volatile struct {
++ dma64regs_t tx; /* dma64 tx channel */
++ dma64regs_t rx; /* dma64 rx channel */
++} dma64regp_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 */
++} dma64diag_t;
++
++/*
++ * DMA Descriptor
++ * Descriptors are only read by the hardware, never written back.
++ */
++typedef volatile struct {
++ uint32 ctrl1; /* misc control bits & bufcount */
++ uint32 ctrl2; /* buffer count and address extension */
++ uint32 addrlow; /* memory address of the first byte of the date buffer, bits 31:0 */
++ uint32 addrhigh; /* memory address of the first byte of the date buffer, bits 63:32 */
++} dma64dd_t;
++
++/*
++ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss.
++ */
++#define D64MAXRINGSZ 8192
++#define D64RINGALIGN 8192
++#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t))
++
++/* transmit channel control */
++#define D64_XC_XE 0x00000001 /* transmit enable */
++#define D64_XC_SE 0x00000002 /* transmit suspend request */
++#define D64_XC_LE 0x00000004 /* loopback enable */
++#define D64_XC_FL 0x00000010 /* flush request */
++#define D64_XC_AE 0x00110000 /* address extension bits */
++#define D64_XC_AE_SHIFT 16
++
++/* transmit descriptor table pointer */
++#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */
++
++/* transmit channel status */
++#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */
++#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */
++#define D64_XS0_XS_SHIFT 28
++#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */
++#define D64_XS0_XS_ACTIVE 0x10000000 /* active */
++#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */
++#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */
++#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */
++
++#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */
++#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */
++#define D64_XS1_XE_SHIFT 28
++#define D64_XS1_XE_NOERR 0x00000000 /* no error */
++#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */
++#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */
++#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */
++#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */
++#define D64_XS1_XE_COREE 0x50000000 /* core error */
++
++/* receive channel control */
++#define D64_RC_RE 0x00000001 /* receive enable */
++#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */
++#define D64_RC_RO_SHIFT 1
++#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */
++#define D64_RC_AE 0x00110000 /* address extension bits */
++#define D64_RC_AE_SHIFT 16
++
++/* receive descriptor table pointer */
++#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */
++
++/* receive channel status */
++#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */
++#define D64_RS0_RS_MASK 0xf0000000 /* receive state */
++#define D64_RS0_RS_SHIFT 28
++#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */
++#define D64_RS0_RS_ACTIVE 0x10000000 /* active */
++#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */
++#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */
++#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */
++
++#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */
++#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */
++#define D64_RS1_RE_SHIFT 28
++#define D64_RS1_RE_NOERR 0x00000000 /* no error */
++#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */
++#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */
++#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */
++#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */
++#define D64_RS1_RE_COREE 0x50000000 /* core error */
++
++/* fifoaddr */
++#define D64_FA_OFF_MASK 0xffff /* offset */
++#define D64_FA_SEL_MASK 0xf0000 /* select */
++#define D64_FA_SEL_SHIFT 16
++#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */
++#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */
++#define D64_FA_SEL_RDD 0x40000 /* receive dma data */
++#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */
++#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */
++#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */
++#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */
++#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */
++#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */
++#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */
++
++/* descriptor control flags 1 */
++#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */
++#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */
++#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */
++#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */
++
++/* descriptor control flags 2 */
++#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */
++#define D64_CTRL2_AE 0x00110000 /* address extension bits */
++#define D64_CTRL2_AE_SHIFT 16
++
++/* control flags in the range [27:20] are core-specific and not defined here */
++#define D64_CTRL_CORE_MASK 0x0ff00000
++
++
++#endif /* _sbhnddma_h_ */
+diff -Naur linux.old/drivers/net/wl2/Makefile linux.dev/drivers/net/wl2/Makefile
+--- linux.old/drivers/net/wl2/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl2/Makefile 2006-04-06 16:56:27.000000000 +0200
+@@ -0,0 +1,23 @@
++#
++# 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: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $
++
++EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER
++
++O_TARGET := wl.o
++
++obj-y := wl_apsta.o
++obj-y += compat.o hnddma.o
+
+obj-m := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
-diff -Nur linux-2.4.32/drivers/parport/Config.in linux-2.4.32-brcm/drivers/parport/Config.in
---- linux-2.4.32/drivers/parport/Config.in 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/parport/Config.in 2005-12-16 23:39:11.364863000 +0100
+diff -Naur linux.old/drivers/net/wl2/compat.c linux.dev/drivers/net/wl2/compat.c
+--- linux.old/drivers/net/wl2/compat.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl2/compat.c 2006-04-06 17:08:21.000000000 +0200
+@@ -0,0 +1,376 @@
++/*
++ * Misc useful OS-independent routines.
++ *
++ * Copyright 2005, 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>
++#ifdef BCMDRIVER
++#include <osl.h>
++#include <sbutils.h>
++#include <bcmnvram.h>
++#else
++#include <stdio.h>
++#include <string.h>
++#endif
++#include "pktq.h"
++#include <bcmutils.h>
++#include <bcmendian.h>
++#include <bcmdevs.h>
++
++#ifdef BCMDRIVER
++/* copy a pkt buffer chain into a buffer */
++uint
++pktcopy(osl_t *osh, 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(osh, p)) {
++ if (offset < (uint)PKTLEN(osh, p))
++ break;
++ offset -= PKTLEN(osh, p);
++ }
++
++ if (!p)
++ return 0;
++
++ /* copy the data */
++ for (; p && len; p = PKTNEXT(osh, p)) {
++ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len);
++ bcopy(PKTDATA(osh, p) + offset, buf, n);
++ buf += n;
++ len -= n;
++ ret += n;
++ offset = 0;
++ }
++
++ return ret;
++}
++
++/* return total length of buffer chain */
++uint
++pkttotlen(osl_t *osh, void *p)
++{
++ uint total;
++
++ total = 0;
++ for (; p; p = PKTNEXT(osh, p))
++ total += PKTLEN(osh, p);
++ return (total);
++}
++
++/*
++ * osl multiple-precedence packet queue
++ * hi_prec is always >= the number of the highest non-empty queue
++ */
++
++void *
++pktq_penq(struct pktq *pq, int prec, void *p)
++{
++ struct pktq_prec *q;
++
++ ASSERT(prec >= 0 && prec < pq->num_prec);
++ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */
++
++ ASSERT(!pktq_full(pq));
++ ASSERT(!pktq_pfull(pq, prec));
++
++ q = &pq->q[prec];
++
++ if (q->head)
++ PKTSETLINK(q->tail, p);
++ else
++ q->head = p;
++
++ q->tail = p;
++ q->len++;
++
++ if (pq->hi_prec < prec)
++ pq->hi_prec = (uint8)prec;
++
++ pq->len++;
++
++ return p;
++}
++
++void *
++pktq_penq_head(struct pktq *pq, int prec, void *p)
++{
++ struct pktq_prec *q;
++
++ ASSERT(prec >= 0 && prec < pq->num_prec);
++ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */
++
++ ASSERT(!pktq_full(pq));
++ ASSERT(!pktq_pfull(pq, prec));
++
++ q = &pq->q[prec];
++
++ if (q->head)
++ PKTSETLINK(p, q->head);
++ else
++ q->tail = p;
++
++ q->head = p;
++ q->len++;
++
++ if (pq->hi_prec < prec)
++ pq->hi_prec = (uint8)prec;
++
++ pq->len++;
++
++ return p;
++}
++
++void *
++pktq_pdeq(struct pktq *pq, int prec)
++{
++ struct pktq_prec *q;
++ void *p;
++
++ ASSERT(prec >= 0 && prec < pq->num_prec);
++
++ q = &pq->q[prec];
++
++ if ((p = q->head) == NULL)
++ return NULL;
++
++ if ((q->head = PKTLINK(p)) == NULL)
++ q->tail = NULL;
++
++ q->len--;
++
++ pq->len--;
++
++ PKTSETLINK(p, NULL);
++
++ return p;
++}
++
++void *
++pktq_pdeq_tail(struct pktq *pq, int prec)
++{
++ struct pktq_prec *q;
++ void *p, *prev;
++
++ ASSERT(prec >= 0 && prec < pq->num_prec);
++
++ q = &pq->q[prec];
++
++ if ((p = q->head) == NULL)
++ return NULL;
++
++ for (prev = NULL; p != q->tail; p = PKTLINK(p))
++ prev = p;
++
++ if (prev)
++ PKTSETLINK(prev, NULL);
++ else
++ q->head = NULL;
++
++ q->tail = prev;
++ q->len--;
++
++ pq->len--;
++
++ return p;
++}
++
++void
++pktq_init(struct pktq *pq, int num_prec, int max)
++{
++ int prec;
++
++ ASSERT(num_prec >= 0 && num_prec <= PKTQ_MAX_PREC);
++
++ bzero(pq, sizeof (*pq));
++
++ pq->num_prec = (uint16)num_prec;
++
++ pq->max = (uint16)max;
++
++ for (prec = 0; prec < num_prec; prec++)
++ pq->q[prec].max = pq->max;
++}
++
++void *
++pktq_deq(struct pktq *pq, int *prec_out)
++{
++ struct pktq_prec *q;
++ void *p;
++ int prec;
++
++ if (pq->len == 0)
++ return NULL;
++
++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
++ pq->hi_prec--;
++
++ q = &pq->q[prec];
++
++ if ((p = q->head) == NULL)
++ return NULL;
++
++ if ((q->head = PKTLINK(p)) == NULL)
++ q->tail = NULL;
++
++ q->len--;
++
++ if (prec_out)
++ *prec_out = prec;
++
++ pq->len--;
++
++ PKTSETLINK(p, NULL);
++
++ return p;
++}
++
++void *
++pktq_deq_tail(struct pktq *pq, int *prec_out)
++{
++ struct pktq_prec *q;
++ void *p, *prev;
++ int prec;
++
++ if (pq->len == 0)
++ return NULL;
++
++ for (prec = 0; prec < pq->hi_prec; prec++)
++ if (pq->q[prec].head)
++ break;
++
++ q = &pq->q[prec];
++
++ if ((p = q->head) == NULL)
++ return NULL;
++
++ for (prev = NULL; p != q->tail; p = PKTLINK(p))
++ prev = p;
++
++ if (prev)
++ PKTSETLINK(prev, NULL);
++ else
++ q->head = NULL;
++
++ q->tail = prev;
++ q->len--;
++
++ if (prec_out)
++ *prec_out = prec;
++
++ pq->len--;
++
++ PKTSETLINK(p, NULL);
++
++ return p;
++}
++
++void *
++pktq_peek(struct pktq *pq, int *prec_out)
++{
++ void *p;
++ int prec;
++
++ if (pq->len == 0)
++ return NULL;
++
++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
++ pq->hi_prec--;
++
++ if ((p = pq->q[prec].head) == NULL)
++ return NULL;
++
++ if (prec_out)
++ *prec_out = prec;
++
++ return p;
++}
++
++void *
++pktq_peek_tail(struct pktq *pq, int *prec_out)
++{
++ void *p;
++ int prec;
++
++ if (pq->len == 0)
++ return NULL;
++
++ for (prec = 0; prec < pq->hi_prec; prec++)
++ if (pq->q[prec].head)
++ break;
++
++ if ((p = pq->q[prec].tail) == NULL)
++ return NULL;
++
++ if (prec_out)
++ *prec_out = prec;
++
++ return p;
++}
++
++int
++pktq_mlen(struct pktq *pq, uint prec_bmp)
++{
++ int prec, len;
++
++ len = 0;
++
++ for (prec = 0; prec <= pq->hi_prec; prec++)
++ if (prec_bmp & (1 << prec))
++ len += pq->q[prec].len;
++
++ return len;
++}
++
++void *
++pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out)
++{
++ struct pktq_prec *q;
++ void *p;
++ int prec;
++
++ if (pq->len == 0)
++ return NULL;
++
++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL)
++ pq->hi_prec--;
++
++ while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL)
++ if (prec-- == 0)
++ return NULL;
++
++ q = &pq->q[prec];
++
++ if ((p = q->head) == NULL)
++ return NULL;
++
++ if ((q->head = PKTLINK(p)) == NULL)
++ q->tail = NULL;
++
++ q->len--;
++
++ if (prec_out)
++ *prec_out = prec;
++
++ pq->len--;
++
++ PKTSETLINK(p, NULL);
++
++ return p;
++}
++
++#endif
++
++
+diff -Naur linux.old/drivers/net/wl2/hnddma.c linux.dev/drivers/net/wl2/hnddma.c
+--- linux.old/drivers/net/wl2/hnddma.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl2/hnddma.c 2006-04-06 16:32:33.000000000 +0200
+@@ -0,0 +1,1487 @@
++/*
++ * Generic Broadcom Home Networking Division (HND) DMA module.
++ * This supports the following chips: BCM42xx, 44xx, 47xx .
++ *
++ * Copyright 2005, 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 <sbconfig.h>
++#include <bcmutils.h>
++#include <bcmdevs.h>
++#include <sbutils.h>
++
++struct dma_info; /* forward declaration */
++#define di_t struct dma_info
++
++#include "sbhnddma.h"
++#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
++
++/* 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 *osh; /* os handle */
++ sb_t *sbh; /* sb handle */
++
++ bool dma64; /* dma64 enabled */
++ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
++
++ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */
++ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */
++ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */
++ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */
++
++ uint32 dma64align; /* either 8k or 4k depends on number of dd */
++ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */
++ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */
++ uint ntxd; /* # tx descriptors tunable */
++ uint txin; /* index of next descriptor to reclaim */
++ uint txout; /* index of next descriptor to post */
++ uint txavail; /* # free tx descriptors */
++ void **txp; /* pointer to parallel array of pointers to packets */
++ ulong txdpa; /* physical address of descriptor ring */
++ uint txdalign; /* #bytes added to alloc'd mem to align txd */
++ uint txdalloc; /* #bytes allocated for the ring */
++
++ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */
++ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */
++ uint nrxd; /* # rx descriptors tunable */
++ uint rxin; /* index of next descriptor to reclaim */
++ uint rxout; /* index of next descriptor to post */
++ void **rxp; /* pointer to parallel array of pointers to packets */
++ ulong rxdpa; /* physical address of descriptor ring */
++ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */
++ uint rxdalloc; /* #bytes allocated for the ring */
++
++ /* tunables */
++ uint rxbufsize; /* rx buffer size in bytes */
++ uint nrxpost; /* # rx buffers to keep posted */
++ uint rxoffset; /* rxcontrol offset */
++ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */
++ uint ddoffsethigh; /* add to get dma address of descriptor ring, high 32 bits */
++ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */
++ uint dataoffsethigh; /* add to get dma address of data buffer, high 32 bits */
++} dma_info_t;
++
++#ifdef BCMDMA64
++#define DMA64_ENAB(di) ((di)->dma64)
++#else
++#define DMA64_ENAB(di) (0)
++#endif
++
++/* descriptor bumping macros */
++#define XXD(x, n) ((x) & ((n) - 1))
++#define TXD(x) XXD((x), di->ntxd)
++#define RXD(x) XXD((x), di->nrxd)
++#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, type) ((bytes) / sizeof(type))
++#define I2B(index, type) ((index) * sizeof(type))
++
++#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */
++#define PCI32ADDR_HIGH_SHIFT 30
++
++
++/* prototypes */
++static bool dma_isaddrext(dma_info_t *di);
++static bool dma_alloc(dma_info_t *di, uint direction);
++
++static bool dma32_alloc(dma_info_t *di, uint direction);
++static void dma32_txreset(dma_info_t *di);
++static void dma32_rxreset(dma_info_t *di);
++static bool dma32_txsuspendedidle(dma_info_t *di);
++static int dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags);
++static void* dma32_getnexttxp(dma_info_t *di, bool forceall);
++static void* dma32_getnextrxp(dma_info_t *di, bool forceall);
++static void dma32_txrotate(di_t *di);
++
++/* prototype or stubs */
++#ifdef BCMDMA64
++static bool dma64_alloc(dma_info_t *di, uint direction);
++static void dma64_txreset(dma_info_t *di);
++static void dma64_rxreset(dma_info_t *di);
++static bool dma64_txsuspendedidle(dma_info_t *di);
++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags);
++static void* dma64_getnexttxp(dma_info_t *di, bool forceall);
++static void* dma64_getnextrxp(dma_info_t *di, bool forceall);
++static void dma64_txrotate(di_t *di);
++#else
++static bool dma64_alloc(dma_info_t *di, uint direction) { return TRUE; }
++static void dma64_txreset(dma_info_t *di) {}
++static void dma64_rxreset(dma_info_t *di) {}
++static bool dma64_txsuspendedidle(dma_info_t *di) { return TRUE;}
++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) { return 0; }
++static void* dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; }
++static void* dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; }
++static void dma64_txrotate(di_t *di) { return; }
++#endif
++
++
++
++void*
++dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx,
++ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level)
++{
++ dma_info_t *di;
++ uint size;
++
++ /* allocate private info structure */
++ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) {
++ return (NULL);
++ }
++ bzero((char*)di, sizeof (dma_info_t));
++
++ di->msg_level = msg_level ? msg_level : &dma_msg_level;
++
++ if (sbh != NULL)
++ di->dma64 = ((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64);
++
++#ifndef BCMDMA64
++ if (di->dma64) {
++ DMA_ERROR(("dma_attach: driver doesn't have the capability to support 64 bits DMA\n"));
++ goto fail;
++ }
++#endif
++
++ /* check arguments */
++ ASSERT(ISPOWEROF2(ntxd));
++ ASSERT(ISPOWEROF2(nrxd));
++ if (nrxd == 0)
++ ASSERT(dmaregsrx == NULL);
++ if (ntxd == 0)
++ ASSERT(dmaregstx == NULL);
++
++
++ /* init dma reg pointer */
++ if (di->dma64) {
++ ASSERT(ntxd <= D64MAXDD);
++ ASSERT(nrxd <= D64MAXDD);
++ di->d64txregs = (dma64regs_t *)dmaregstx;
++ di->d64rxregs = (dma64regs_t *)dmaregsrx;
++
++ di->dma64align = D64RINGALIGN;
++ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
++ /* for smaller dd table, HW relax the alignment requirement */
++ di->dma64align = D64RINGALIGN / 2;
++ }
++ } else {
++ ASSERT(ntxd <= D32MAXDD);
++ ASSERT(nrxd <= D32MAXDD);
++ di->d32txregs = (dma32regs_t *)dmaregstx;
++ di->d32rxregs = (dma32regs_t *)dmaregsrx;
++ }
++
++
++ /* make a private copy of our callers name */
++ strncpy(di->name, name, MAXNAMEL);
++ di->name[MAXNAMEL-1] = '\0';
++
++ di->osh = osh;
++ di->sbh = sbh;
++
++ /* save tunables */
++ di->ntxd = ntxd;
++ di->nrxd = nrxd;
++ di->rxbufsize = rxbufsize;
++ di->nrxpost = nrxpost;
++ di->rxoffset = rxoffset;
++
++ /*
++ * figure out the DMA physical address offset for dd and data
++ * for old chips w/o sb, use zero
++ * for new chips w sb,
++ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset
++ * Other bus: use zero
++ * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
++ */
++ di->ddoffsetlow = 0;
++ di->dataoffsetlow = 0;
++ if (sbh != NULL) {
++ if (sbh->bustype == PCI_BUS) { /* for pci bus, add offset */
++ if ((sbh->buscoretype == SB_PCIE) && di->dma64){
++ di->ddoffsetlow = 0;
++ di->ddoffsethigh = SB_PCIE_DMA_H32;
++ } else {
++ di->ddoffsetlow = SB_PCI_DMA;
++ di->ddoffsethigh = 0;
++ }
++ di->dataoffsetlow = di->ddoffsetlow;
++ di->dataoffsethigh = di->ddoffsethigh;
++ }
++#if defined(__mips__) && defined(IL_BIGENDIAN)
++ /* use sdram swapped region for data buffers but not dma descriptors */
++ di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED;
++#endif
++ }
++
++ di->addrext = dma_isaddrext(di);
++
++ DMA_TRACE(("%s: dma_attach: osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n",
++ name, osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, di->ddoffsetlow, di->dataoffsetlow));
++
++ /* allocate tx packet pointer vector */
++ if (ntxd) {
++ size = ntxd * sizeof (void*);
++ if ((di->txp = MALLOC(osh, size)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh)));
++ goto fail;
++ }
++ bzero((char*)di->txp, size);
++ }
++
++ /* allocate rx packet pointer vector */
++ if (nrxd) {
++ size = nrxd * sizeof (void*);
++ if ((di->rxp = MALLOC(osh, size)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh)));
++ goto fail;
++ }
++ bzero((char*)di->rxp, size);
++ }
++
++ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
++ if (ntxd) {
++ if (!dma_alloc(di, DMA_TX))
++ goto fail;
++ }
++
++ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
++ if (nrxd) {
++ if (!dma_alloc(di, DMA_RX))
++ goto fail;
++ }
++
++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) {
++ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", di->name, di->txdpa));
++ goto fail;
++ }
++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) {
++ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", di->name, di->rxdpa));
++ goto fail;
++ }
++
++ return ((void*)di);
++
++fail:
++ dma_detach((void*)di);
++ return (NULL);
++}
++
++static bool
++dma_alloc(dma_info_t *di, uint direction)
++{
++ if (DMA64_ENAB(di)) {
++ return dma64_alloc(di, direction);
++ } else {
++ return dma32_alloc(di, direction);
++ }
++}
++
++/* 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->txd32)
++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), di->txdalloc, (di->txdpa - di->txdalign));
++ if (di->rxd32)
++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), di->rxdalloc, (di->rxdpa - di->rxdalign));
++
++ /* free packet pointer vectors */
++ if (di->txp)
++ MFREE(di->osh, (void*)di->txp, (di->ntxd * sizeof (void*)));
++ if (di->rxp)
++ MFREE(di->osh, (void*)di->rxp, (di->nrxd * sizeof (void*)));
++
++ /* free our private info structure */
++ MFREE(di->osh, (void*)di, sizeof (dma_info_t));
++}
++
++/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */
++static bool
++dma_isaddrext(dma_info_t *di)
++{
++ uint32 w;
++
++ if (DMA64_ENAB(di)) {
++ OR_REG(&di->d64txregs->control, D64_XC_AE);
++ w = R_REG(&di->d32txregs->control);
++ AND_REG(&di->d32txregs->control, ~D64_XC_AE);
++ return ((w & XC_AE) == D64_XC_AE);
++ } else {
++ OR_REG(&di->d32txregs->control, XC_AE);
++ w = R_REG(&di->d32txregs->control);
++ AND_REG(&di->d32txregs->control, ~XC_AE);
++ return ((w & XC_AE) == XC_AE);
++ }
++}
++
++void
++dma_txreset(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_txreset\n", di->name));
++
++ if (DMA64_ENAB(di))
++ dma64_txreset(di);
++ else
++ dma32_txreset(di);
++}
++
++void
++dma_rxreset(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_rxreset\n", di->name));
++
++ if (DMA64_ENAB(di))
++ dma64_rxreset(di);
++ else
++ dma32_rxreset(di);
++}
++
++/* initialize descriptor table base address */
++static void
++dma_ddtable_init(dma_info_t *di, uint direction, ulong pa)
++{
++ if (DMA64_ENAB(di)) {
++ if (direction == DMA_TX) {
++ W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow);
++ W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh);
++ } else {
++ W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow);
++ W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh);
++ }
++ } else {
++ uint32 offset = di->ddoffsetlow;
++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
++ if (direction == DMA_TX)
++ W_REG(&di->d32txregs->addr, (pa + offset));
++ else
++ W_REG(&di->d32rxregs->addr, (pa + offset));
++ } else {
++ /* dma32 address extension */
++ uint32 ae;
++ ASSERT(di->addrext);
++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
++
++ if (direction == DMA_TX) {
++ W_REG(&di->d32txregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset));
++ SET_REG(&di->d32txregs->control, XC_AE, (ae << XC_AE_SHIFT));
++ } else {
++ W_REG(&di->d32rxregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset));
++ SET_REG(&di->d32rxregs->control, RC_AE, (ae << RC_AE_SHIFT));
++ }
++ }
++ }
++}
++
++/* init the tx or rx descriptor */
++static INLINE void
++dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *ctrl)
++{
++ uint offset = di->dataoffsetlow;
++
++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) {
++ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + offset));
++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl));
++ } else {
++ /* address extension */
++ uint32 ae;
++ ASSERT(di->addrext);
++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
++
++ *ctrl |= (ae << CTRL_AE_SHIFT);
++ W_SM(&ddring[outidx].addr, BUS_SWAP32((pa & ~PCI32ADDR_HIGH) + offset));
++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl));
++ }
++}
++
++/* init the tx or rx descriptor */
++static INLINE void
++dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, uint32 bufcount)
++{
++ uint32 bufaddr_low = pa + di->dataoffsetlow;
++ uint32 bufaddr_high = 0 + di->dataoffsethigh;
++
++ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
++
++ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(bufaddr_low));
++ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(bufaddr_high));
++ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
++ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
++}
++
++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 */
++ if (DMA64_ENAB(di)) {
++ BZERO_SM((void*)di->txd64, (di->ntxd * sizeof (dma64dd_t)));
++ W_REG(&di->d64txregs->control, XC_XE);
++ dma_ddtable_init(di, DMA_TX, di->txdpa);
++ } else {
++ BZERO_SM((void*)di->txd32, (di->ntxd * sizeof (dma32dd_t)));
++ W_REG(&di->d32txregs->control, XC_XE);
++ dma_ddtable_init(di, DMA_TX, di->txdpa);
++ }
++}
++
++bool
++dma_txenabled(dma_info_t *di)
++{
++ uint32 xc;
++
++ /* If the chip is dead, it is not enabled :-) */
++ if (DMA64_ENAB(di)) {
++ xc = R_REG(&di->d64txregs->control);
++ return ((xc != 0xffffffff) && (xc & D64_XC_XE));
++ } else {
++ xc = R_REG(&di->d32txregs->control);
++ return ((xc != 0xffffffff) && (xc & XC_XE));
++ }
++}
++
++void
++dma_txsuspend(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_txsuspend\n", di->name));
++ if (DMA64_ENAB(di))
++ OR_REG(&di->d64txregs->control, D64_XC_SE);
++ else
++ OR_REG(&di->d32txregs->control, XC_SE);
++}
++
++void
++dma_txresume(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_txresume\n", di->name));
++ if (DMA64_ENAB(di))
++ AND_REG(&di->d64txregs->control, ~D64_XC_SE);
++ else
++ AND_REG(&di->d32txregs->control, ~XC_SE);
++}
++
++bool
++dma_txsuspendedidle(dma_info_t *di)
++{
++ if (DMA64_ENAB(di))
++ return dma64_txsuspendedidle(di);
++ else
++ return dma32_txsuspendedidle(di);
++}
++
++bool
++dma_txsuspended(dma_info_t *di)
++{
++ if (DMA64_ENAB(di))
++ return ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE);
++ else
++ return ((R_REG(&di->d32txregs->control) & XC_SE) == XC_SE);
++}
++
++bool
++dma_txstopped(dma_info_t *di)
++{
++ if (DMA64_ENAB(di))
++ return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED);
++ else
++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED);
++}
++
++bool
++dma_rxstopped(dma_info_t *di)
++{
++ if (DMA64_ENAB(di))
++ return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED);
++ else
++ return ((R_REG(&di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED);
++}
++
++void
++dma_fifoloopbackenable(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
++ if (DMA64_ENAB(di))
++ OR_REG(&di->d64txregs->control, D64_XC_LE);
++ else
++ OR_REG(&di->d32txregs->control, 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 */
++ if (DMA64_ENAB(di)) {
++ BZERO_SM((void*)di->rxd64, (di->nrxd * sizeof (dma64dd_t)));
++ dma_rxenable(di);
++ dma_ddtable_init(di, DMA_RX, di->rxdpa);
++ } else {
++ BZERO_SM((void*)di->rxd32, (di->nrxd * sizeof (dma32dd_t)));
++ dma_rxenable(di);
++ dma_ddtable_init(di, DMA_RX, di->rxdpa);
++ }
++}
++
++void
++dma_rxenable(dma_info_t *di)
++{
++ DMA_TRACE(("%s: dma_rxenable\n", di->name));
++ if (DMA64_ENAB(di))
++ W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE));
++ else
++ W_REG(&di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE));
++}
++
++bool
++dma_rxenabled(dma_info_t *di)
++{
++ uint32 rc;
++
++ if (DMA64_ENAB(di)) {
++ rc = R_REG(&di->d64rxregs->control);
++ return ((rc != 0xffffffff) && (rc & D64_RC_RE));
++ } else {
++ rc = R_REG(&di->d32rxregs->control);
++ return ((rc != 0xffffffff) && (rc & RC_RE));
++ }
++}
++
++
++/* !! tx entry routine */
++int
++dma_txfast(dma_info_t *di, void *p0, uint32 coreflags)
++{
++ if (DMA64_ENAB(di)) {
++ return dma64_txfast(di, p0, coreflags);
++ } else {
++ return dma32_txfast(di, p0, coreflags);
++ }
++}
++
++/* !! rx entry routine, 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->osh, p, FALSE);
++ continue;
++ }
++
++ len = ltoh16(*(uint16*)(PKTDATA(di->osh, 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->osh, p, FALSE);
++ di->hnddma.rxgiants++;
++ continue;
++ }
++
++ /* set actual length */
++ PKTSETLEN(di->osh, p, (di->rxoffset + len));
++
++ break;
++ }
++
++ return (p);
++}
++
++/* post receive buffers */
++void
++dma_rxfill(dma_info_t *di)
++{
++ void *p;
++ uint rxin, rxout;
++ uint32 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->osh, rxbufsize, FALSE)) == NULL) {
++ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name));
++ di->hnddma.rxnobuf++;
++ break;
++ }
++
++ /* Do a cached write instead of uncached write since DMA_MAP
++ * will flush the cache. */
++ *(uint32*)(PKTDATA(di->osh, p)) = 0;
++
++ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p);
++ ASSERT(ISALIGNED(pa, 4));
++
++ /* save the free packet pointer */
++ ASSERT(di->rxp[rxout] == NULL);
++ di->rxp[rxout] = p;
++
++ if (DMA64_ENAB(di)) {
++ /* prep the descriptor control value */
++ if (rxout == (di->nrxd - 1))
++ ctrl = CTRL_EOT;
++
++ dma64_dd_upd(di, di->rxd64, pa, rxout, &ctrl, rxbufsize);
++ } else {
++ /* prep the descriptor control value */
++ ctrl = rxbufsize;
++ if (rxout == (di->nrxd - 1))
++ ctrl |= CTRL_EOT;
++ dma32_dd_upd(di, di->rxd32, pa, rxout, &ctrl);
++ }
++
++ rxout = NEXTRXD(rxout);
++ }
++
++ di->rxout = rxout;
++
++ /* update the chip lastdscr pointer */
++ if (DMA64_ENAB(di)) {
++ W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t));
++ } else {
++ W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t));
++ }
++}
++
++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->osh, 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)
++{
++ if (DMA64_ENAB(di)) {
++ return dma64_getnexttxp(di, forceall);
++ } else {
++ return dma32_getnexttxp(di, forceall);
++ }
++}
++
++/* like getnexttxp but no reclaim */
++void*
++dma_peeknexttxp(dma_info_t *di)
++{
++ uint end, i;
++
++ if (DMA64_ENAB(di)) {
++ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
++ } else {
++ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t);
++ }
++
++ for (i = di->txin; i != end; i = NEXTTXD(i))
++ if (di->txp[i])
++ return (di->txp[i]);
++
++ return (NULL);
++}
++
++/*
++ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
++ */
++void
++dma_txrotate(di_t *di)
++{
++ if (DMA64_ENAB(di)) {
++ dma64_txrotate(di);
++ } else {
++ dma32_txrotate(di);
++ }
++}
++
++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->osh, p, FALSE);
++}
++
++void *
++dma_getnextrxp(dma_info_t *di, bool forceall)
++{
++ if (DMA64_ENAB(di)) {
++ return dma64_getnextrxp(di, forceall);
++ } else {
++ return dma32_getnextrxp(di, forceall);
++ }
++}
++
++uintptr
++dma_getvar(dma_info_t *di, char *name)
++{
++ if (!strcmp(name, "&txavail"))
++ return ((uintptr) &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));
++}
++
++void
++dma_rxpiomode(dma32regs_t *regs)
++{
++ W_REG(&regs->control, RC_FM);
++}
++
++void
++dma_txpioloopback(dma32regs_t *regs)
++{
++ OR_REG(&regs->control, XC_LE);
++}
++
++
++
++
++/*** 32 bits DMA non-inline functions ***/
++static bool
++dma32_alloc(dma_info_t *di, uint direction)
++{
++ uint size;
++ uint ddlen;
++ void *va;
++
++ ddlen = sizeof (dma32dd_t);
++
++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
++
++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN))
++ size += D32RINGALIGN;
++
++
++ if (direction == DMA_TX) {
++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
++ return FALSE;
++ }
++
++ di->txd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN);
++ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va);
++ di->txdpa += di->txdalign;
++ di->txdalloc = size;
++ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN));
++ } else {
++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
++ return FALSE;
++ }
++ di->rxd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN);
++ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va);
++ di->rxdpa += di->rxdalign;
++ di->rxdalloc = size;
++ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN));
++ }
++
++ return TRUE;
++}
++
++static void
++dma32_txreset(dma_info_t *di)
++{
++ uint32 status;
++
++ /* suspend tx DMA first */
++ W_REG(&di->d32txregs->control, XC_SE);
++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED &&
++ status != XS_XS_IDLE &&
++ status != XS_XS_STOPPED,
++ 10000);
++
++ W_REG(&di->d32txregs->control, 0);
++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & 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);
++}
++
++static void
++dma32_rxreset(dma_info_t *di)
++{
++ uint32 status;
++
++ W_REG(&di->d32rxregs->control, 0);
++ SPINWAIT((status = (R_REG(&di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED,
++ 10000);
++
++ if (status != RS_RS_DISABLED) {
++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name));
++ }
++}
++
++static bool
++dma32_txsuspendedidle(dma_info_t *di)
++{
++ if (!(R_REG(&di->d32txregs->control) & XC_SE))
++ return 0;
++
++ if ((R_REG(&di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE)
++ return 0;
++
++ OSL_DELAY(2);
++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE);
++}
++
++/*
++ * supports full 32bit dma engine buffer addressing so
++ * dma buffers can cross 4 Kbyte page boundaries.
++ */
++static int
++dma32_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->osh, p);
++ len = PKTLEN(di->osh, p);
++ next = PKTNEXT(di->osh, 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->osh, 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;
++
++ if (DMA64_ENAB(di)) {
++ dma64_dd_upd(di, di->txd64, pa, txout, &ctrl, len);
++ } else {
++ dma32_dd_upd(di, di->txd32, pa, txout, &ctrl);
++ }
++
++ ASSERT(di->txp[txout] == NULL);
++
++ txout = NEXTTXD(txout);
++ }
++
++ /* if last txd eof not set, fix it */
++ if (!(ctrl & CTRL_EOF))
++ W_SM(&di->txd32[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 */
++ if (DMA64_ENAB(di)) {
++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t));
++ } else {
++ W_REG(&di->d32txregs->ptr, I2B(txout, dma32dd_t));
++ }
++
++ /* 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->osh, p0, TRUE);
++ di->txavail = 0;
++ di->hnddma.txnobuf++;
++ return (-1);
++}
++
++static void*
++dma32_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->d32txregs->status) & XS_CD_MASK, dma32dd_t);
++
++ if ((start == 0) && (end > di->txout))
++ goto bogus;
++
++ for (i = start; i != end && !txp; i = NEXTTXD(i)) {
++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow),
++ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]);
++
++ W_SM(&di->txd32[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);
++}
++
++static void *
++dma32_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->d32rxregs->status) & RS_CD_MASK, dma32dd_t)))
++ 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->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow),
++ di->rxbufsize, DMA_RX, rxp);
++ W_SM(&di->rxd32[i].addr, 0xdeadbeef);
++
++ di->rxin = NEXTRXD(i);
++
++ return (rxp);
++}
++
++static void
++dma32_txrotate(di_t *di)
++{
++ uint ad;
++ uint nactive;
++ uint rot;
++ uint old, new;
++ uint32 w;
++ uint first, last;
++
++ ASSERT(dma_txsuspendedidle(di));
++
++ nactive = dma_txactive(di);
++ ad = B2I(((R_REG(&di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t);
++ 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->txd32[old].ctrl) & ~CTRL_EOT;
++ if (new == (di->ntxd - 1))
++ w |= CTRL_EOT;
++ W_SM(&di->txd32[new].ctrl, w);
++ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr));
++
++ /* zap the old tx dma descriptor address field */
++ W_SM(&di->txd32[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->d32txregs->ptr, I2B(di->txout, dma32dd_t));
++}
++
++/*** 64 bits DMA non-inline functions ***/
++
++#ifdef BCMDMA64
++
++static bool
++dma64_alloc(dma_info_t *di, uint direction)
++{
++ uint size;
++ uint ddlen;
++ uint32 alignbytes;
++ void *va;
++
++ ddlen = sizeof (dma64dd_t);
++
++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
++
++ alignbytes = di->dma64align;
++
++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes))
++ size += alignbytes;
++
++
++ if (direction == DMA_TX) {
++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
++ return FALSE;
++ }
++
++ di->txd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes);
++ di->txdalign = (uint)((int8*)di->txd64 - (int8*)va);
++ di->txdpa += di->txdalign;
++ di->txdalloc = size;
++ ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes));
++ } else {
++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) {
++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
++ return FALSE;
++ }
++ di->rxd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes);
++ di->rxdalign = (uint)((int8*)di->rxd64 - (int8*)va);
++ di->rxdpa += di->rxdalign;
++ di->rxdalloc = size;
++ ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes));
++ }
++
++ return TRUE;
++}
++
++static void
++dma64_txreset(dma_info_t *di)
++{
++ uint32 status;
++
++ /* suspend tx DMA first */
++ W_REG(&di->d64txregs->control, D64_XC_SE);
++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED &&
++ status != D64_XS0_XS_IDLE &&
++ status != D64_XS0_XS_STOPPED,
++ 10000);
++
++ W_REG(&di->d64txregs->control, 0);
++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED,
++ 10000);
++
++ if (status != D64_XS0_XS_DISABLED) {
++ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name));
++ }
++
++ /* wait for the last transaction to complete */
++ OSL_DELAY(300);
++}
++
++static void
++dma64_rxreset(dma_info_t *di)
++{
++ uint32 status;
++
++ W_REG(&di->d64rxregs->control, 0);
++ SPINWAIT((status = (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED,
++ 10000);
++
++ if (status != D64_RS0_RS_DISABLED) {
++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name));
++ }
++}
++
++static bool
++dma64_txsuspendedidle(dma_info_t *di)
++{
++
++ if (!(R_REG(&di->d64txregs->control) & D64_XC_SE))
++ return 0;
++
++ if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE)
++ return 1;
++
++ return 0;
++}
++
++/*
++ * supports full 32bit dma engine buffer addressing so
++ * dma buffers can cross 4 Kbyte page boundaries.
++ */
++static int
++dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags)
++{
++ void *p, *next;
++ uchar *data;
++ uint len;
++ uint txout;
++ uint32 flags;
++ uint32 pa;
++
++ DMA_TRACE(("%s: dma_txfast\n", di->name));
++
++ txout = di->txout;
++ flags = 0;
++
++ /*
++ * Walk the chain of packet buffers
++ * allocating and initializing transmit descriptor entries.
++ */
++ for (p = p0; p; p = next) {
++ data = PKTDATA(di->osh, p);
++ len = PKTLEN(di->osh, p);
++ next = PKTNEXT(di->osh, 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->osh, data, len, DMA_TX, p);
++
++ flags = coreflags;
++
++ if (p == p0)
++ flags |= D64_CTRL1_SOF;
++ if (next == NULL)
++ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
++ if (txout == (di->ntxd - 1))
++ flags |= D64_CTRL1_EOT;
++
++ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
++
++ ASSERT(di->txp[txout] == NULL);
++
++ txout = NEXTTXD(txout);
++ }
++
++ /* if last txd eof not set, fix it */
++ if (!(flags & D64_CTRL1_EOF))
++ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
++
++ /* save the packet */
++ di->txp[PREVTXD(txout)] = p0;
++
++ /* bump the tx descriptor index */
++ di->txout = txout;
++
++ /* kick the chip */
++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t));
++
++ /* 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->osh, p0, TRUE);
++ di->txavail = 0;
++ di->hnddma.txnobuf++;
++ return (-1);
++}
++
++static void*
++dma64_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->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t);
++
++ if ((start == 0) && (end > di->txout))
++ goto bogus;
++
++ for (i = start; i != end && !txp; i = NEXTTXD(i)) {
++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow),
++ (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK), DMA_TX, di->txp[i]);
++
++ W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
++ W_SM(&di->txd64[i].addrhigh, 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);
++}
++
++static void *
++dma64_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->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t)))
++ 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->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow),
++ di->rxbufsize, DMA_RX, rxp);
++
++ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
++ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
++
++ di->rxin = NEXTRXD(i);
++
++ return (rxp);
++}
++
++static void
++dma64_txrotate(di_t *di)
++{
++ uint ad;
++ uint nactive;
++ uint rot;
++ uint old, new;
++ uint32 w;
++ uint first, last;
++
++ ASSERT(dma_txsuspendedidle(di));
++
++ nactive = dma_txactive(di);
++ ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t);
++ 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->txd64[old].ctrl1) & ~D64_CTRL1_EOT;
++ if (new == (di->ntxd - 1))
++ w |= D64_CTRL1_EOT;
++ W_SM(&di->txd64[new].ctrl1, w);
++
++ w = R_SM(&di->txd64[old].ctrl2);
++ W_SM(&di->txd64[new].ctrl2, w);
++
++ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
++ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
++
++ /* zap the old tx dma descriptor address field */
++ W_SM(&di->txd64[old].addrlow, 0xdeadbeef);
++ W_SM(&di->txd64[old].addrhigh, 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->d64txregs->ptr, I2B(di->txout, dma64dd_t));
++}
++
++#endif
++
+diff -Naur linux.old/drivers/net/wl2/hnddma.h linux.dev/drivers/net/wl2/hnddma.h
+--- linux.old/drivers/net/wl2/hnddma.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl2/hnddma.h 2006-04-06 16:32:44.000000000 +0200
+@@ -0,0 +1,71 @@
++/*
++ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface
++ * This supports the following chips: BCM42xx, 44xx, 47xx .
++ *
++ * Copyright 2005, 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_
++
++/* 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
++
++#ifndef osl_t
++#define osl_t void
++#endif
++
++/* externs */
++extern void * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx,
++ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, 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_txsuspendedidle(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 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 uintptr 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);
++
++extern void dma_rxpiomode(dma32regs_t *);
++extern void dma_txpioloopback(dma32regs_t *);
++
++
++#endif /* _hnddma_h_ */
+diff -Naur linux.old/drivers/net/wl2/pktq.h linux.dev/drivers/net/wl2/pktq.h
+--- linux.old/drivers/net/wl2/pktq.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl2/pktq.h 2006-04-06 17:33:02.000000000 +0200
+@@ -0,0 +1,83 @@
++/*
++ * Misc useful os-independent macros and functions.
++ *
++ * Copyright 2005, 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 _pktq_h_
++#define _pktq_h_
++
++/*** driver-only section ***/
++#ifdef BCMDRIVER
++
++/* osl packet chain functions */
++extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf);
++extern uint pkttotlen(osl_t *osh, void *);
++
++#define pktenq(pq, p) pktq_penq((pq), 0, (p)) /* legacy */
++#define pktdeq(pq) pktq_pdeq((pq), 0) /* legacy */
++
++/* osl multi-precedence packet queue */
++
++#define PKTQ_LEN_DEFAULT 128
++#define PKTQ_MAX_PREC 8
++struct pktq_prec {
++ void *head; /* first packet to dequeue */
++ void *tail; /* last packet to dequeue */
++ uint16 len; /* number of queued packets */
++ uint16 max; /* maximum number of queued packets */
++};
++
++struct pktq {
++ struct pktq_prec q[PKTQ_MAX_PREC];
++ uint16 num_prec; /* number of precedences in use */
++ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */
++ uint16 max; /* total max packets */
++ uint16 len; /* total number of packets */
++};
++
++/* operations on a specific precedence in packet queue */
++
++#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max))
++#define pktq_plen(pq, prec) ((pq)->q[prec].len)
++#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len)
++#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max)
++#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0)
++
++#define pktq_ppeek(pq, prec) ((pq)->q[prec].head)
++#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail)
++
++extern void *pktq_penq(struct pktq *pq, int prec, void *p);
++extern void *pktq_penq_head(struct pktq *pq, int prec, void *p);
++extern void *pktq_pdeq(struct pktq *pq, int prec);
++extern void *pktq_pdeq_tail(struct pktq *pq, int prec);
++
++/* operations on packet queue as a whole */
++
++extern void pktq_init(struct pktq *pq, int num_prec, int max);
++
++#define pktq_len(pq) ((int)(pq)->len)
++#define pktq_max(pq) ((int)(pq)->max)
++#define pktq_avail(pq) ((int)((pq)->max - (pq)->len))
++#define pktq_full(pq) ((pq)->len >= (pq)->max)
++#define pktq_empty(pq) ((pq)->len == 0)
++
++extern void *pktq_deq(struct pktq *pq, int *prec_out);
++extern void *pktq_deq_tail(struct pktq *pq, int *prec_out);
++extern void *pktq_peek(struct pktq *pq, int *prec_out);
++extern void *pktq_peek_tail(struct pktq *pq, int *prec_out);
++
++extern int pktq_mlen(struct pktq *pq, uint prec_bmp);
++extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out);
++
++#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--)
++
++#endif
++#endif /* _pktq_h_ */
+diff -Naur linux.old/drivers/net/wl2/sbhnddma.h linux.dev/drivers/net/wl2/sbhnddma.h
+--- linux.old/drivers/net/wl2/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/net/wl2/sbhnddma.h 2006-04-06 16:32:44.000000000 +0200
+@@ -0,0 +1,312 @@
++/*
++ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface
++ * This supports the following chips: BCM42xx, 44xx, 47xx .
++ *
++ * Copyright 2005, 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 _sbhnddma_h_
++#define _sbhnddma_h_
++
++
++/* 2byte-wide pio register set per channel(xmt or rcv) */
++typedef volatile struct {
++ uint16 fifocontrol;
++ uint16 fifodata;
++ uint16 fifofree; /* only valid in xmt channel, not in rcv channel */
++ uint16 PAD;
++} pio2regs_t;
++
++/* a pair of pio channels(tx and rx) */
++typedef volatile struct {
++ pio2regs_t tx;
++ pio2regs_t rx;
++} pio2regp_t;
++
++/* 4byte-wide pio register set per channel(xmt or rcv) */
++typedef volatile struct {
++ uint32 fifocontrol;
++ uint32 fifodata;
++} pio4regs_t;
++
++/* a pair of pio channels(tx and rx) */
++typedef volatile struct {
++ pio4regs_t tx;
++ pio4regs_t rx;
++} pio4regp_t;
++
++
++
++/* DMA structure:
++ * support two DMA engines: 32 bits address or 64 bit addressing
++ * basic DMA register set is per channel(transmit or receive)
++ * a pair of channels is defined for convenience
++ */
++
++
++/*** 32 bits addressing ***/
++
++/* dma registers per channel(xmt or rcv) */
++typedef volatile struct {
++ uint32 control; /* enable, et al */
++ uint32 addr; /* descriptor ring base address (4K aligned) */
++ uint32 ptr; /* last descriptor posted to chip */
++ uint32 status; /* current active descriptor, et al */
++} dma32regs_t;
++
++typedef volatile struct {
++ dma32regs_t xmt; /* dma tx channel */
++ dma32regs_t rcv; /* dma rx channel */
++} dma32regp_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 */
++} dma32diag_t;
++
++/*
++ * 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 */
++} dma32dd_t;
++
++/*
++ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page.
++ */
++#define D32MAXRINGSZ 4096
++#define D32RINGALIGN 4096
++#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_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 */
++#define XC_AE ((uint32)3 << 16) /* address extension bits */
++#define XC_AE_SHIFT 16
++
++/* 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 */
++#define RC_AE ((uint32)3 << 16) /* address extension bits */
++#define RC_AE_SHIFT 16
++
++/* 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 */
++#define FA_SEL_RSD 0xe0000 /* receive frame status data */
++#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */
++
++/* descriptor control flags */
++#define CTRL_BC_MASK 0x1fff /* buffer byte count */
++#define CTRL_AE ((uint32)3 << 16) /* address extension bits */
++#define CTRL_AE_SHIFT 16
++#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
++
++/*** 64 bits addressing ***/
++
++/* dma registers per channel(xmt or rcv) */
++typedef volatile struct {
++ uint32 control; /* enable, et al */
++ uint32 ptr; /* last descriptor posted to chip */
++ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */
++ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */
++ uint32 status0; /* current descriptor, xmt state */
++ uint32 status1; /* active descriptor, xmt error */
++} dma64regs_t;
++
++typedef volatile struct {
++ dma64regs_t tx; /* dma64 tx channel */
++ dma64regs_t rx; /* dma64 rx channel */
++} dma64regp_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 */
++} dma64diag_t;
++
++/*
++ * DMA Descriptor
++ * Descriptors are only read by the hardware, never written back.
++ */
++typedef volatile struct {
++ uint32 ctrl1; /* misc control bits & bufcount */
++ uint32 ctrl2; /* buffer count and address extension */
++ uint32 addrlow; /* memory address of the first byte of the date buffer, bits 31:0 */
++ uint32 addrhigh; /* memory address of the first byte of the date buffer, bits 63:32 */
++} dma64dd_t;
++
++/*
++ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss.
++ */
++#define D64MAXRINGSZ 8192
++#define D64RINGALIGN 8192
++#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t))
++
++/* transmit channel control */
++#define D64_XC_XE 0x00000001 /* transmit enable */
++#define D64_XC_SE 0x00000002 /* transmit suspend request */
++#define D64_XC_LE 0x00000004 /* loopback enable */
++#define D64_XC_FL 0x00000010 /* flush request */
++#define D64_XC_AE 0x00110000 /* address extension bits */
++#define D64_XC_AE_SHIFT 16
++
++/* transmit descriptor table pointer */
++#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */
++
++/* transmit channel status */
++#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */
++#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */
++#define D64_XS0_XS_SHIFT 28
++#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */
++#define D64_XS0_XS_ACTIVE 0x10000000 /* active */
++#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */
++#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */
++#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */
++
++#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */
++#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */
++#define D64_XS1_XE_SHIFT 28
++#define D64_XS1_XE_NOERR 0x00000000 /* no error */
++#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */
++#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */
++#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */
++#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */
++#define D64_XS1_XE_COREE 0x50000000 /* core error */
++
++/* receive channel control */
++#define D64_RC_RE 0x00000001 /* receive enable */
++#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */
++#define D64_RC_RO_SHIFT 1
++#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */
++#define D64_RC_AE 0x00110000 /* address extension bits */
++#define D64_RC_AE_SHIFT 16
++
++/* receive descriptor table pointer */
++#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */
++
++/* receive channel status */
++#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */
++#define D64_RS0_RS_MASK 0xf0000000 /* receive state */
++#define D64_RS0_RS_SHIFT 28
++#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */
++#define D64_RS0_RS_ACTIVE 0x10000000 /* active */
++#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */
++#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */
++#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */
++
++#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */
++#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */
++#define D64_RS1_RE_SHIFT 28
++#define D64_RS1_RE_NOERR 0x00000000 /* no error */
++#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */
++#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */
++#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */
++#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */
++#define D64_RS1_RE_COREE 0x50000000 /* core error */
++
++/* fifoaddr */
++#define D64_FA_OFF_MASK 0xffff /* offset */
++#define D64_FA_SEL_MASK 0xf0000 /* select */
++#define D64_FA_SEL_SHIFT 16
++#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */
++#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */
++#define D64_FA_SEL_RDD 0x40000 /* receive dma data */
++#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */
++#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */
++#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */
++#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */
++#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */
++#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */
++#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */
++
++/* descriptor control flags 1 */
++#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */
++#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */
++#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */
++#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */
++
++/* descriptor control flags 2 */
++#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */
++#define D64_CTRL2_AE 0x00110000 /* address extension bits */
++#define D64_CTRL2_AE_SHIFT 16
++
++/* control flags in the range [27:20] are core-specific and not defined here */
++#define D64_CTRL_CORE_MASK 0x0ff00000
++
++
++#endif /* _sbhnddma_h_ */
+diff -Naur linux.old/drivers/parport/Config.in linux.dev/drivers/parport/Config.in
+--- linux.old/drivers/parport/Config.in 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/drivers/parport/Config.in 2006-04-06 15:34:15.000000000 +0200
@@ -11,6 +11,7 @@
tristate 'Parallel port support' CONFIG_PARPORT
if [ "$CONFIG_PARPORT" != "n" ]; then
@@ -17863,9 +20224,9 @@ diff -Nur linux-2.4.32/drivers/parport/Config.in linux-2.4.32-brcm/drivers/parpo
if [ "$CONFIG_PARPORT_PC" != "n" -a "$CONFIG_SERIAL" != "n" ]; then
if [ "$CONFIG_SERIAL" = "m" ]; then
define_tristate CONFIG_PARPORT_PC_CML1 m
-diff -Nur linux-2.4.32/drivers/parport/Makefile linux-2.4.32-brcm/drivers/parport/Makefile
---- linux-2.4.32/drivers/parport/Makefile 2004-08-08 01:26:05.000000000 +0200
-+++ linux-2.4.32-brcm/drivers/parport/Makefile 2005-12-16 23:39:11.364863000 +0100
+diff -Naur linux.old/drivers/parport/Makefile linux.dev/drivers/parport/Makefile
+--- linux.old/drivers/parport/Makefile 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/drivers/parport/Makefile 2006-04-06 15:34:15.000000000 +0200
@@ -22,6 +22,7 @@
obj-$(CONFIG_PARPORT) += parport.o
@@ -17874,9 +20235,9 @@ diff -Nur linux-2.4.32/drivers/parport/Makefile linux-2.4.32-brcm/drivers/parpor
obj-$(CONFIG_PARPORT_PC_PCMCIA) += parport_cs.o
obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o
obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o
-diff -Nur linux-2.4.32/drivers/parport/parport_splink.c linux-2.4.32-brcm/drivers/parport/parport_splink.c
---- linux-2.4.32/drivers/parport/parport_splink.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/parport/parport_splink.c 2005-12-16 23:39:11.364863000 +0100
+diff -Naur linux.old/drivers/parport/parport_splink.c linux.dev/drivers/parport/parport_splink.c
+--- linux.old/drivers/parport/parport_splink.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/parport/parport_splink.c 2006-04-06 15:34:15.000000000 +0200
@@ -0,0 +1,345 @@
+/* Low-level parallel port routines for the ASUS WL-500g built-in port
+ *
@@ -18223,9 +20584,32 @@ diff -Nur linux-2.4.32/drivers/parport/parport_splink.c linux-2.4.32-brcm/driver
+module_init(parport_splink_init)
+module_exit(parport_splink_cleanup)
+
-diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_generic.c linux-2.4.32-brcm/drivers/pcmcia/bcm4710_generic.c
---- linux-2.4.32/drivers/pcmcia/bcm4710_generic.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710_generic.c 2005-12-16 23:39:11.368863250 +0100
+diff -Naur linux.old/drivers/pcmcia/Makefile linux.dev/drivers/pcmcia/Makefile
+--- linux.old/drivers/pcmcia/Makefile 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/drivers/pcmcia/Makefile 2006-04-06 15:34:15.000000000 +0200
+@@ -74,6 +74,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
+@@ -112,5 +116,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)
+diff -Naur linux.old/drivers/pcmcia/bcm4710_generic.c linux.dev/drivers/pcmcia/bcm4710_generic.c
+--- linux.old/drivers/pcmcia/bcm4710_generic.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/pcmcia/bcm4710_generic.c 2006-04-06 15:34:15.000000000 +0200
@@ -0,0 +1,912 @@
+/*
+ *
@@ -19139,9 +21523,9 @@ diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_generic.c linux-2.4.32-brcm/driver
+
+
+#endif /* defined(CONFIG_PROC_FS) */
-diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c linux-2.4.32-brcm/drivers/pcmcia/bcm4710_pcmcia.c
---- linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710_pcmcia.c 2005-12-16 23:39:11.368863250 +0100
+diff -Naur linux.old/drivers/pcmcia/bcm4710_pcmcia.c linux.dev/drivers/pcmcia/bcm4710_pcmcia.c
+--- linux.old/drivers/pcmcia/bcm4710_pcmcia.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/pcmcia/bcm4710_pcmcia.c 2006-04-06 15:34:15.000000000 +0200
@@ -0,0 +1,266 @@
+/*
+ * BCM4710 specific pcmcia routines.
@@ -19409,9 +21793,9 @@ diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c linux-2.4.32-brcm/drivers
+ bcm4710_pcmcia_configure_socket
+};
+
-diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h linux-2.4.32-brcm/drivers/pcmcia/bcm4710pcmcia.h
---- linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710pcmcia.h 2005-12-16 23:39:11.368863250 +0100
+diff -Naur linux.old/drivers/pcmcia/bcm4710pcmcia.h linux.dev/drivers/pcmcia/bcm4710pcmcia.h
+--- linux.old/drivers/pcmcia/bcm4710pcmcia.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/drivers/pcmcia/bcm4710pcmcia.h 2006-04-06 15:34:15.000000000 +0200
@@ -0,0 +1,118 @@
+/*
+ *
@@ -19531,32 +21915,9 @@ diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h linux-2.4.32-brcm/drivers/
+extern struct pcmcia_low_level bcm4710_pcmcia_ops;
+
+#endif /* !defined(_BCM4710PCMCIA_H) */
-diff -Nur linux-2.4.32/drivers/pcmcia/Makefile linux-2.4.32-brcm/drivers/pcmcia/Makefile
---- linux-2.4.32/drivers/pcmcia/Makefile 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.32-brcm/drivers/pcmcia/Makefile 2005-12-16 23:39:11.364863000 +0100
-@@ -65,6 +65,10 @@
- au1000_ss-objs-$(CONFIG_PCMCIA_DB1X00) += au1000_db1x00.o
- au1000_ss-objs-$(CONFIG_PCMCIA_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
-@@ -102,5 +106,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)
-diff -Nur linux-2.4.32/include/asm-mips/bootinfo.h linux-2.4.32-brcm/include/asm-mips/bootinfo.h
---- linux-2.4.32/include/asm-mips/bootinfo.h 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.32-brcm/include/asm-mips/bootinfo.h 2005-12-16 23:39:11.400865250 +0100
+diff -Naur linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/bootinfo.h
+--- linux.old/include/asm-mips/bootinfo.h 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/include/asm-mips/bootinfo.h 2006-04-06 15:34:15.000000000 +0200
@@ -37,6 +37,7 @@
#define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */
#define MACH_GROUP_LASAT 21
@@ -19565,7 +21926,7 @@ diff -Nur linux-2.4.32/include/asm-mips/bootinfo.h linux-2.4.32-brcm/include/asm
/*
* Valid machtype values for group unknown (low order halfword of mips_machtype)
-@@ -194,6 +195,15 @@
+@@ -197,6 +198,15 @@
#define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */
/*
@@ -19581,9 +21942,9 @@ diff -Nur linux-2.4.32/include/asm-mips/bootinfo.h linux-2.4.32-brcm/include/asm
* Valid machtype for group TITAN
*/
#define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */
-diff -Nur linux-2.4.32/include/asm-mips/cpu.h linux-2.4.32-brcm/include/asm-mips/cpu.h
---- linux-2.4.32/include/asm-mips/cpu.h 2005-01-19 15:10:11.000000000 +0100
-+++ linux-2.4.32-brcm/include/asm-mips/cpu.h 2005-12-16 23:39:11.412866000 +0100
+diff -Naur linux.old/include/asm-mips/cpu.h linux.dev/include/asm-mips/cpu.h
+--- linux.old/include/asm-mips/cpu.h 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/include/asm-mips/cpu.h 2006-04-06 15:34:15.000000000 +0200
@@ -22,6 +22,11 @@
spec.
*/
@@ -19632,10 +21993,10 @@ diff -Nur linux-2.4.32/include/asm-mips/cpu.h linux-2.4.32-brcm/include/asm-mips
/*
* ISA Level encodings
-diff -Nur linux-2.4.32/include/asm-mips/r4kcache.h linux-2.4.32-brcm/include/asm-mips/r4kcache.h
---- linux-2.4.32/include/asm-mips/r4kcache.h 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.32-brcm/include/asm-mips/r4kcache.h 2005-12-16 23:39:11.416866250 +0100
-@@ -567,4 +567,17 @@
+diff -Naur linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kcache.h
+--- linux.old/include/asm-mips/r4kcache.h 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/include/asm-mips/r4kcache.h 2006-04-06 15:34:15.000000000 +0200
+@@ -658,4 +658,17 @@
cache128_unroll32(addr|ws,Index_Writeback_Inv_SD);
}
@@ -19653,9 +22014,9 @@ diff -Nur linux-2.4.32/include/asm-mips/r4kcache.h linux-2.4.32-brcm/include/asm
+}
+
#endif /* __ASM_R4KCACHE_H */
-diff -Nur linux-2.4.32/include/asm-mips/serial.h linux-2.4.32-brcm/include/asm-mips/serial.h
---- linux-2.4.32/include/asm-mips/serial.h 2005-01-19 15:10:12.000000000 +0100
-+++ linux-2.4.32-brcm/include/asm-mips/serial.h 2005-12-16 23:39:11.428867000 +0100
+diff -Naur linux.old/include/asm-mips/serial.h linux.dev/include/asm-mips/serial.h
+--- linux.old/include/asm-mips/serial.h 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/include/asm-mips/serial.h 2006-04-06 15:34:15.000000000 +0200
@@ -223,6 +223,13 @@
#define TXX927_SERIAL_PORT_DEFNS
#endif
@@ -19678,10 +22039,10 @@ diff -Nur linux-2.4.32/include/asm-mips/serial.h linux-2.4.32-brcm/include/asm-m
COBALT_SERIAL_PORT_DEFNS \
DDB5477_SERIAL_PORT_DEFNS \
EV96100_SERIAL_PORT_DEFNS \
-diff -Nur linux-2.4.32/init/do_mounts.c linux-2.4.32-brcm/init/do_mounts.c
---- linux-2.4.32/init/do_mounts.c 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.32-brcm/init/do_mounts.c 2005-12-16 23:39:11.504871750 +0100
-@@ -253,7 +253,13 @@
+diff -Naur linux.old/init/do_mounts.c linux.dev/init/do_mounts.c
+--- linux.old/init/do_mounts.c 2006-04-06 15:38:09.000000000 +0200
++++ linux.dev/init/do_mounts.c 2006-04-06 15:34:15.000000000 +0200
+@@ -254,7 +254,13 @@
{ "ftlb", 0x2c08 },
{ "ftlc", 0x2c10 },
{ "ftld", 0x2c18 },