add my 2.6.15-rc5 port (yay) with devfs. The PCI subsystem is broken on Broadcom...
authorImre Kaloz <kaloz@openwrt.org>
Thu, 15 Dec 2005 09:05:57 +0000 (09:05 +0000)
committerImre Kaloz <kaloz@openwrt.org>
Thu, 15 Dec 2005 09:05:57 +0000 (09:05 +0000)
SVN-Revision: 2683

openwrt/package/iptables/Makefile
openwrt/target/linux/linux-2.6/Makefile
openwrt/target/linux/linux-2.6/config/brcm
openwrt/target/linux/linux-2.6/patches/brcm/001-bcm947xx.patch
openwrt/target/linux/linux-2.6/patches/generic/000-reenable_devfs.patch [new file with mode: 0644]
openwrt/target/linux/linux-2.6/patches/generic/003-net-b44-1.patch [new file with mode: 0644]
openwrt/target/linux/linux-2.6/patches/generic/003-net-b44-2.patch [new file with mode: 0644]
openwrt/target/linux/linux-2.6/patches/generic/003-net-b44.patch [deleted file]
openwrt/target/linux/linux-2.6/patches/generic/100-netfilter_layer7.patch
openwrt/target/linux/linux-2.6/patches/generic/101-mppe-mppc-1.3.patch [deleted file]
openwrt/target/linux/linux-2.6/patches/generic/104-pf_ring.patch [deleted file]

index 2715c31444a45d041f500c7623fa3b8e5d2bd6ab..777d4647286ea47c9a6de43578fc5ec566d2282f 100644 (file)
@@ -3,11 +3,11 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=iptables
-PKG_VERSION:=1.3.3
-PKG_RELEASE:=2
-PKG_MD5SUM:=86d88455520cfdc56fd7ae27897a80a4
+PKG_VERSION:=1.3.4
+PKG_RELEASE:=1
+PKG_MD5SUM:=fdff8abe890807968226b0c374335305
 
-PKG_SOURCE_URL:=http://www.netfilter.org/files \
+PKG_SOURCE_URL:=http://www.netfilter.org/projects/iptables/files \
        ftp://ftp.be.netfilter.org/pub/netfilter/iptables/ \
        ftp://ftp.de.netfilter.org/pub/netfilter/iptables/ \
        ftp://ftp.no.netfilter.org/pub/netfilter/iptables/
index 55d7b0f07689bd03bd4fd71e181cb3a7ddfc5e46..30b2d79814394f32219db77544a5649166f64016 100644 (file)
@@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk
 include ../rules.mk
 
 KERNEL:=2.6
-LINUX_VERSION:=2.6.12.5
-LINUX_KERNEL_MD5SUM:=076f0dc714112c764c790fbaef19e228
-LINUX_SITE=http://www.fi.kernel.org/pub/linux/kernel/v2.6 \
-           http://www.fr.kernel.org/pub/linux/kernel/v2.6 \
-           http://www.kernel.org/pub/linux/kernel/v2.6 \
-           http://www.de.kernel.org/pub/linux/kernel/v2.6 
+LINUX_VERSION:=2.6.15-rc5
+LINUX_KERNEL_MD5SUM:=1b430bfd22f4094bf1bdc1a5ceb6b6a2
+LINUX_SITE=http://www.fi.kernel.org/pub/linux/kernel/v2.6/testing \
+           http://www.fr.kernel.org/pub/linux/kernel/v2.6/testing \
+           http://www.kernel.org/pub/linux/kernel/v2.6/testing \
+           http://www.de.kernel.org/pub/linux/kernel/v2.6/testing 
 MODULES_SUBDIR:=lib/modules/$(LINUX_VERSION)
 LINUX_KCONFIG:=./config/$(BOARD)
 LINUX_BUILD_DIR:=$(BUILD_DIR)/linux-2.6-$(BOARD)
@@ -79,9 +79,9 @@ $(eval $(call KMOD_template,PPP,ppp,\
        $(MODULES_DIR)/kernel/drivers/net/slhc.ko \
 ,CONFIG_PPP))
 
-$(eval $(call KMOD_template,MPPE,mppe,\
-       $(MODULES_DIR)/kernel/drivers/net/ppp_mppe_mppc.ko \
-,CONFIG_PPP_MPPE_MPPC))
+#$(eval $(call KMOD_template,MPPE,mppe,\
+#      $(MODULES_DIR)/kernel/drivers/net/ppp_mppe_mppc.ko \
+#,CONFIG_PPP_MPPE_MPPC))
 
 $(eval $(call KMOD_template,PPPOATM,pppoatm,\
        $(MODULES_DIR)/kernel/net/atm/pppoatm.ko \
@@ -338,9 +338,9 @@ $(eval $(call KMOD_template,USB_ACM,usb-acm,\
        $(MODULES_DIR)/kernel/drivers/usb/class/cdc-acm.ko \
 ,CONFIG_USB_ACM))
 
-$(eval $(call KMOD_template,USB_AUDIO,usb-audio,\
-       $(MODULES_DIR)/kernel/drivers/usb/class/audio.ko \
-,CONFIG_USB_AUDIO,kmod-soundcore kmod-usb-core,61,audio))
+#$(eval $(call KMOD_template,USB_AUDIO,usb-audio,\
+#      $(MODULES_DIR)/kernel/drivers/usb/class/audio.ko \
+#,CONFIG_USB_AUDIO,kmod-soundcore kmod-usb-core,61,audio))
 
 $(eval $(call KMOD_template,USB_PRINTER,usb-printer,\
        $(MODULES_DIR)/kernel/drivers/usb/class/usblp.ko \
index 675c3f5c085891a9db751a54b645e7d649304549..af99c279f6d94656181f68a0851d838c3ec1b67c 100644 (file)
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12.5
-# Tue Nov 29 01:40:21 2005
+# Linux kernel version: 2.6.15-rc5
+# Thu Dec 15 08:44:06 2005
 #
 CONFIG_MIPS=y
-# CONFIG_MIPS64 is not set
-# CONFIG_64BIT is not set
-CONFIG_MIPS32=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_EMBEDDED=y
-# CONFIG_KALLSYMS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD is not set
 
 #
 # Machine selection
 #
-# CONFIG_MACH_JAZZ is not set
-CONFIG_BCM947XX=y
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_MIRAGE is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MIPS_EV64120 is not set
 # CONFIG_MIPS_EV96100 is not set
 # CONFIG_MIPS_IVR is not set
-# CONFIG_LASAT is not set
 # CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MACH_JAZZ is not set
+CONFIG_BCM947XX=y
+# CONFIG_LASAT is not set
 # CONFIG_MIPS_ATLAS is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SEAD is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
 # CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_OCELOT_3 is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_PNX8550_V2PCI is not set
+# CONFIG_PNX8550_JBS is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_QEMU is not set
 # CONFIG_SGI_IP22 is not set
-# CONFIG_SOC_AU1X00 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
 # CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
 # CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_TOSHIBA_RBTX4938 is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+# CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
 CONFIG_IRQ_CPU=y
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_FB is not set
 
 #
 # CPU selection
 #
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
 # CONFIG_CPU_R3000 is not set
 # CONFIG_CPU_TX39XX is not set
 # CONFIG_CPU_VR41XX is not set
@@ -117,171 +96,96 @@ CONFIG_CPU_MIPS32=y
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
+# CONFIG_MIPS_MT is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 
 #
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_HW_HAS_PCI=y
-CONFIG_PCI=y
-# CONFIG_PCI_LEGACY_PROC is not set
-CONFIG_PCI_NAMES=y
-CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=m
-CONFIG_CARDBUS=y
-
-#
-# PC-card bridges
-#
-CONFIG_YENTA=m
-# CONFIG_PD6729 is not set
-# CONFIG_I82092 is not set
-# CONFIG_TCIC is not set
-CONFIG_PCCARD_NONSTATIC=m
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_TRAD_SIGNALS=y
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=0
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_XIP is not set
-
-#
-# Mapping drivers for chip access
-#
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_BCM47XX=y
-# CONFIG_MTD_PCI is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
+# Code maturity level options
 #
-# CONFIG_MTD_NAND is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
-# Parallel port support
+# General setup
 #
-# CONFIG_PARPORT is not set
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
-# Plug and Play support
+# Loadable module support
 #
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
 
 #
-# Block devices
+# Block layer
 #
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
-# CONFIG_CDROM_PKTCDVD is not set
 
 #
 # IO Schedulers
@@ -290,111 +194,52 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
 
 #
-# SCSI device support
-#
-CONFIG_SCSI=m
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
+CONFIG_MMU=y
 
 #
-# Multi-device support (RAID and LVM)
+# PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_MD is not set
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+# CONFIG_PCMCIA_LOAD_CIS is not set
+# CONFIG_PCMCIA_IOCTL is not set
+CONFIG_CARDBUS=y
 
 #
-# Fusion MPT device support
+# PC-card bridges
 #
-# CONFIG_FUSION is not set
+CONFIG_YENTA=m
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_PCCARD_NONSTATIC=m
 
 #
-# IEEE 1394 (FireWire) support
+# PCI Hotplug Support
 #
-# CONFIG_IEEE1394 is not set
+# CONFIG_HOTPLUG_PCI is not set
 
 #
-# I2O device support
+# Executable file formats
 #
-# CONFIG_I2O is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
 
 #
-# Networking support
+# Networking
 #
 CONFIG_NET=y
 
@@ -404,11 +249,15 @@ CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
 # CONFIG_NET_KEY is not set
-CONFIG_RING=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
 CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_ROUTE_FWMARK=y
 CONFIG_IP_ROUTE_MULTIPATH=y
@@ -421,13 +270,25 @@ CONFIG_NET_IPGRE=m
 # CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
 # CONFIG_SYN_COOKIES is not set
+CONFIG_IPSEC_NAT_TRAVERSAL=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 CONFIG_INET_TUNNEL=m
-CONFIG_IPSEC_NAT_TRAVERSAL=y
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=m
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=y
+CONFIG_TCP_CONG_SCALABLE=m
 
 #
 # IP: Virtual Server Configuration
@@ -444,17 +305,25 @@ CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 # CONFIG_BRIDGE_NETFILTER is not set
 
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+
 #
 # IP: Netfilter Configuration
 #
 CONFIG_IP_NF_CONNTRACK=y
 CONFIG_IP_NF_CT_ACCT=y
 CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
 # CONFIG_IP_NF_CT_PROTO_SCTP is not set
 CONFIG_IP_NF_FTP=y
 CONFIG_IP_NF_IRC=y
+# CONFIG_IP_NF_NETBIOS_NS is not set
 CONFIG_IP_NF_TFTP=m
 CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_PPTP=m
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=y
 CONFIG_IP_NF_MATCH_LIMIT=m
@@ -462,7 +331,6 @@ CONFIG_IP_NF_MATCH_IPRANGE=m
 CONFIG_IP_NF_MATCH_MAC=m
 CONFIG_IP_NF_MATCH_LAYER7=m
 # CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set
-CONFIG_IP_NF_MATCH_LAYER7_MAXDATALEN=2048
 CONFIG_IP_NF_MATCH_PKTTYPE=m
 CONFIG_IP_NF_MATCH_MARK=y
 CONFIG_IP_NF_MATCH_MULTIPORT=y
@@ -481,14 +349,18 @@ CONFIG_IP_NF_MATCH_OWNER=m
 # CONFIG_IP_NF_MATCH_ADDRTYPE is not set
 # CONFIG_IP_NF_MATCH_REALM is not set
 # CONFIG_IP_NF_MATCH_SCTP is not set
+# CONFIG_IP_NF_MATCH_DCCP is not set
 # CONFIG_IP_NF_MATCH_COMMENT is not set
 CONFIG_IP_NF_MATCH_CONNMARK=m
+# CONFIG_IP_NF_MATCH_CONNBYTES is not set
 # CONFIG_IP_NF_MATCH_HASHLIMIT is not set
+CONFIG_IP_NF_MATCH_STRING=m
 CONFIG_IP_NF_FILTER=y
 CONFIG_IP_NF_TARGET_REJECT=y
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=y
+# CONFIG_IP_NF_TARGET_NFQUEUE is not set
 CONFIG_IP_NF_NAT=y
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=y
@@ -500,12 +372,14 @@ CONFIG_IP_NF_NAT_IRC=y
 CONFIG_IP_NF_NAT_FTP=y
 CONFIG_IP_NF_NAT_TFTP=m
 CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_PPTP=m
 CONFIG_IP_NF_MANGLE=y
 CONFIG_IP_NF_TARGET_TOS=m
 CONFIG_IP_NF_TARGET_ECN=m
 CONFIG_IP_NF_TARGET_DSCP=m
 CONFIG_IP_NF_TARGET_MARK=y
 # CONFIG_IP_NF_TARGET_CLASSIFY is not set
+CONFIG_IP_NF_TARGET_TTL=m
 CONFIG_IP_NF_TARGET_CONNMARK=m
 # CONFIG_IP_NF_TARGET_CLUSTERIP is not set
 # CONFIG_IP_NF_RAW is not set
@@ -544,8 +418,11 @@ CONFIG_IP6_NF_MATCH_LENGTH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
 CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_TARGET_MARK=m
+# CONFIG_IP6_NF_TARGET_HL is not set
 # CONFIG_IP6_NF_RAW is not set
 
 #
@@ -571,8 +448,11 @@ CONFIG_BRIDGE_EBT_REDIRECT=m
 CONFIG_BRIDGE_EBT_SNAT=m
 CONFIG_BRIDGE_EBT_LOG=m
 CONFIG_BRIDGE_EBT_ULOG=m
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
 
 #
 # SCTP Configuration (EXPERIMENTAL)
@@ -598,6 +478,10 @@ CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_CLK_JIFFIES=y
 # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
 # CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
 CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_HFSC=m
@@ -610,8 +494,10 @@ CONFIG_NET_SCH_GRED=m
 CONFIG_NET_SCH_DSMARK=m
 # CONFIG_NET_SCH_NETEM is not set
 CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
+
+#
+# Classification
+#
 CONFIG_NET_CLS=y
 CONFIG_NET_CLS_BASIC=m
 CONFIG_NET_CLS_TCINDEX=m
@@ -620,20 +506,19 @@ CONFIG_NET_CLS_ROUTE=y
 CONFIG_NET_CLS_FW=m
 CONFIG_NET_CLS_U32=m
 # CONFIG_CLS_U32_PERF is not set
-# CONFIG_NET_CLS_IND is not set
 # CONFIG_CLS_U32_MARK is not set
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
 # CONFIG_NET_EMATCH is not set
 # CONFIG_NET_CLS_ACT is not set
 CONFIG_NET_CLS_POLICE=y
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_ESTIMATOR=y
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
 CONFIG_HAMRADIO=y
 
 #
@@ -671,7 +556,6 @@ CONFIG_BT_HIDP=m
 CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_BCSP_TXCRC=y
 # CONFIG_BT_HCIBCM203X is not set
 # CONFIG_BT_HCIBPA10X is not set
 # CONFIG_BT_HCIBFUSB is not set
@@ -680,6 +564,247 @@ CONFIG_BT_HCIUART_BCSP_TXCRC=y
 # CONFIG_BT_HCIBLUECARD is not set
 # CONFIG_BT_HCIBTUART is not set
 # CONFIG_BT_HCIVHCI is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+CONFIG_CONNECTOR=m
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_BCM47XX=y
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=m
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Network device support
+#
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -691,6 +816,11 @@ CONFIG_TUN=m
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -698,6 +828,7 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 
 #
@@ -736,6 +867,8 @@ CONFIG_B44=m
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -744,6 +877,7 @@ CONFIG_B44=m
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 
@@ -772,6 +906,10 @@ CONFIG_NET_RADIO=y
 #
 # Wireless 802.11b ISA/PCI cards support
 #
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+# CONFIG_IPW_DEBUG is not set
+CONFIG_IPW2200=m
 # CONFIG_HERMES is not set
 # CONFIG_ATMEL is not set
 
@@ -785,6 +923,11 @@ CONFIG_NET_RADIO=y
 # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
 #
 # CONFIG_PRISM54 is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
 CONFIG_NET_WIRELESS=y
 
 #
@@ -805,12 +948,14 @@ CONFIG_PPP_ASYNC=m
 # CONFIG_PPP_SYNC_TTY is not set
 CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE_MPPC=m
+CONFIG_PPP_MPPE=m
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -899,12 +1044,15 @@ CONFIG_UNIX98_PTYS=y
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -916,10 +1064,20 @@ CONFIG_UNIX98_PTYS=y
 #
 # CONFIG_W1 is not set
 
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
 #
 # Misc devices
 #
 
+#
+# Multimedia Capabilities Port drivers
+#
+
 #
 # Multimedia devices
 #
@@ -954,6 +1112,7 @@ CONFIG_VIDEO_DEV=m
 #
 # Graphics support
 #
+# CONFIG_FB is not set
 
 #
 # Sound
@@ -966,6 +1125,7 @@ CONFIG_SOUND=m
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
 CONFIG_SND_RAWMIDI=m
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
@@ -1004,9 +1164,10 @@ CONFIG_SND_RAWMIDI=m
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
 # CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
 # CONFIG_SND_TRIDENT is not set
 # CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_AD1889 is not set
 # CONFIG_SND_CMIPCI is not set
 # CONFIG_SND_ENS1370 is not set
 # CONFIG_SND_ENS1371 is not set
@@ -1064,6 +1225,7 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=m
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -1073,17 +1235,16 @@ CONFIG_USB_UHCI_HCD=m
 #
 # USB Device Class drivers
 #
-CONFIG_USB_AUDIO=m
+# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
 
 #
-# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
-# CONFIG_USB_MIDI is not set
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# may also be needed; see USB_STORAGE Help for more information
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1094,6 +1255,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
 
 #
 # USB Input Devices
@@ -1107,12 +1269,17 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_MOUSE is not set
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
 
 #
 # USB Imaging devices
@@ -1155,6 +1322,7 @@ CONFIG_USB_STORAGE=m
 CONFIG_USB_SERIAL=m
 # CONFIG_USB_SERIAL_GENERIC is not set
 # CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ANYDATA is not set
 CONFIG_USB_SERIAL_BELKIN=m
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
@@ -1198,10 +1366,11 @@ CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -1219,11 +1388,16 @@ CONFIG_USB_SERIAL_PL2303=m
 #
 # CONFIG_INFINIBAND is not set
 
+#
+# SN Devices
+#
+
 #
 # File systems
 #
 CONFIG_EXT2_FS=m
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=m
 # CONFIG_EXT3_FS_XATTR is not set
 CONFIG_JBD=m
@@ -1237,21 +1411,20 @@ CONFIG_JFS_FS=m
 # CONFIG_JFS_SECURITY is not set
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
 CONFIG_XFS_FS=m
-# CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1274,15 +1447,14 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
-CONFIG_SYSFS=y
 CONFIG_DEVFS_FS=y
 CONFIG_DEVFS_MOUNT=y
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -1297,8 +1469,8 @@ CONFIG_RAMFS=y
 # CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
 CONFIG_JFFS2_COMPRESSION_OPTIONS=y
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -1327,6 +1499,7 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -1392,6 +1565,11 @@ CONFIG_NLS_ISO8859_15=m
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
 
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
 #
 # Kernel hacking
 #
@@ -1444,10 +1622,12 @@ CONFIG_CRYPTO_MICHAEL_MIC=m
 # Library routines
 #
 CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ISA_DMA_API=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
index 923356f616444edd24224c71c2e085e6150118c9..32a4ed54cadc925a03d1a03f6b6dfd483663eefd 100644 (file)
@@ -1,6 +1,6 @@
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmsrom.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmsrom.c  2005-11-07 01:12:51.811809000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/bcmsrom.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/bcmsrom.c     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/bcmsrom.c     2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,685 @@
 +/*
 + *  Misc useful routines to access NIC SROM
@@ -687,9 +687,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.12.5-br
 +      return (rc);
 +}
 +
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmutils.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmutils.c 2005-11-07 01:12:51.815809250 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/bcmutils.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/bcmutils.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/bcmutils.c    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/bcmutils.c    2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,691 @@
 +/*
 + * Misc useful OS-independent routines.
@@ -1382,9 +1382,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c linux-2.6.12.5-b
 +
 +
 +
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/hnddma.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/hnddma.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/hnddma.c        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/hnddma.c   2005-11-07 01:12:51.815809250 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/hnddma.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/hnddma.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/hnddma.c      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/hnddma.c      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,763 @@
 +/*
 + * Generic Broadcom Home Networking Division (HND) DMA module.
@@ -2149,9 +2149,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/hnddma.c linux-2.6.12.5-brc
 +{
 +      return (NTXDACTIVE(di->txin, di->txout));
 +}
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/linux_osl.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/linux_osl.c        2005-11-07 01:12:51.815809250 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/linux_osl.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/linux_osl.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/linux_osl.c   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/linux_osl.c   2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,420 @@
 +/*
 + * Linux OS Independent Layer
@@ -2573,9 +2573,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c linux-2.6.12.5-
 +}
 +
 +#endif
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/Makefile linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/Makefile
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/Makefile        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/Makefile   2005-11-19 14:16:38.941631500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/Makefile linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/Makefile
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/Makefile      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/Makefile      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,7 @@
 +#
 +# Makefile for the BCM47xx specific kernel interface routines
@@ -2584,9 +2584,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/Makefile linux-2.6.12.5-brc
 +
 +obj-y   := sbutils.o linux_osl.o bcmsrom.o bcmutils.o sbmips.o sbpci.o hnddma.o
 +#obj-y   := nvram.o nvram_linux.o
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/nvram.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/nvram.c    2005-11-19 02:28:26.438059500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/nvram.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/nvram.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/nvram.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/nvram.c       2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,321 @@
 +/*
 + * NVRAM variable manipulation (common)
@@ -2909,9 +2909,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram.c linux-2.6.12.5-brcm
 +{
 +      BCMINIT(nvram_free)();
 +}
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram_linux.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/nvram_linux.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram_linux.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/nvram_linux.c      2005-11-19 02:28:26.438059500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/nvram_linux.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/nvram_linux.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/nvram_linux.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/nvram_linux.c 2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,633 @@
 +/*
 + * NVRAM variable manipulation (Linux kernel half)
@@ -3546,9 +3546,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram_linux.c linux-2.6.12.
 +
 +module_init(dev_nvram_init);
 +module_exit(dev_nvram_exit);
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbmips.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbmips.c   2005-11-07 01:12:51.819809500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/sbmips.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/sbmips.c      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/sbmips.c      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,950 @@
 +/*
 + * BCM47XX Sonics SiliconBackplane MIPS core routines
@@ -4500,9 +4500,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +
 +      return ret;
 +}
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbpci.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbpci.c    2005-11-07 01:12:51.819809500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/sbpci.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/sbpci.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/sbpci.c       2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,530 @@
 +/*
 + * Low-Level PCI and SB support for BCM47xx
@@ -5034,9 +5034,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +
 +      sb_setcoreidx(sbh, coreidx);
 +}
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbutils.c
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbutils.c  2005-11-07 01:12:51.823809750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/sbutils.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/broadcom/sbutils.c     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/broadcom/sbutils.c     2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,1895 @@
 +/*
 + * Misc utility routines for accessing chip-specific features
@@ -6933,9 +6933,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +}
 +
 +
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcm4710.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcm4710.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/bcm4710.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcm4710.h   2005-11-07 01:12:51.823809750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcm4710.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcm4710.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcm4710.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcm4710.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,90 @@
 +/*
 + * BCM4710 address space map and definitions
@@ -7027,9 +7027,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcm4710.h linux-2.6.12.5-brc
 +    }
 +
 +#endif /* _bcm4710_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmdevs.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmdevs.h   2005-11-07 01:12:51.823809750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmdevs.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmdevs.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmdevs.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,238 @@
 +/*
 + * Broadcom device-specific manifest constants.
@@ -7269,9 +7269,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.12.5-brc
 +#define CT4702AP_BOARD                0x0447
 +
 +#endif /* _BCMDEVS_H */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmendian.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmendian.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmendian.h      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmendian.h 2005-11-07 01:12:51.823809750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmendian.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmendian.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmendian.h    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmendian.h    2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,125 @@
 +/*******************************************************************************
 + * $Id$
@@ -7398,9 +7398,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmendian.h linux-2.6.12.5-b
 +}
 +
 +#endif /* _BCMENDIAN_H_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenet47xx.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenet47xx.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h       2005-11-07 01:12:51.823809750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmenet47xx.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmenet47xx.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmenet47xx.h  1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmenet47xx.h  2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,229 @@
 +/*
 + * Hardware-specific definitions for
@@ -7631,9 +7631,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenet47xx.h linux-2.6.12.5
 +#include <bcmenetrxh.h>
 +
 +#endif        /* _bcmenet_47xx_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetmib.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetmib.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetmib.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetmib.h        2005-11-07 01:12:51.823809750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmenetmib.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmenetmib.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmenetmib.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmenetmib.h   2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,81 @@
 +/*
 + * Hardware-specific MIB definition for
@@ -7716,9 +7716,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetmib.h linux-2.6.12.5-
 +} bcmenetmib_t;
 +
 +#endif        /* _bcmenetmib_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetrxh.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetrxh.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h        2005-11-07 01:12:51.827810000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmenetrxh.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmenetrxh.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmenetrxh.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmenetrxh.h   2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,43 @@
 +/*
 + * Hardware-specific Receive Data Header for the
@@ -7763,9 +7763,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetrxh.h linux-2.6.12.5-
 +#define       RXF_OV          ((uint16)1 << 0)        /* fifo overflow */
 +
 +#endif        /* _bcmenetrxh_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmnvram.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmnvram.h  2005-11-07 01:12:51.827810000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmnvram.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmnvram.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmnvram.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmnvram.h     2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,131 @@
 +/*
 + * NVRAM variable manipulation
@@ -7898,9 +7898,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h linux-2.6.12.5-br
 +#define NVRAM_LAST_LOC                (0xc0000000 - NVRAM_SPACE)
 +
 +#endif /* _bcmnvram_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmsrom.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmsrom.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmsrom.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmsrom.h   2005-11-07 01:12:51.827810000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmsrom.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmsrom.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmsrom.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmsrom.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,24 @@
 +/*
 + * Misc useful routines to access NIC srom
@@ -7926,9 +7926,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmsrom.h linux-2.6.12.5-brc
 +extern int srom_parsecis(uint8 *cis, char **vars, int *count);
 +         
 +#endif        /* _bcmsrom_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmutils.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmutils.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmutils.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmutils.h  2005-11-07 01:12:51.827810000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmutils.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmutils.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/bcmutils.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bcmutils.h     2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,136 @@
 +/*
 + * Misc useful os-independent macros and functions.
@@ -8066,9 +8066,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmutils.h linux-2.6.12.5-br
 +#define       bcmdumplog(buf, size)   *buf = '\0'
 +
 +#endif        /* _bcmutils_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bitfuncs.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bitfuncs.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/bitfuncs.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bitfuncs.h  2005-11-07 01:12:51.827810000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/bitfuncs.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bitfuncs.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/bitfuncs.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/bitfuncs.h     2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,85 @@
 +/*
 + * bit manipulation utility functions
@@ -8155,9 +8155,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bitfuncs.h linux-2.6.12.5-br
 +#endif
 +
 +#endif /* _BITFUNCS_H */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h   2005-11-07 01:12:51.827810000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/epivers.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/epivers.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/epivers.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/epivers.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,69 @@
 +/*
 + * Copyright 2001-2003, Broadcom Corporation
@@ -8228,9 +8228,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h linux-2.6.12.5-brc
 +#define       EPI_ROUTER_VERSION_STR  "1.1.2.0"
 +
 +#endif /* _epivers_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h.in linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h.in
---- linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h.in     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h.in        2005-11-07 01:12:51.827810000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/epivers.h.in linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/epivers.h.in
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/epivers.h.in   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/epivers.h.in   2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,69 @@
 +/*
 + * Copyright 2001-2003, Broadcom Corporation
@@ -8301,9 +8301,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h.in linux-2.6.12.5-
 +#define       EPI_ROUTER_VERSION_STR  "@EPI_ROUTER_VERSION_STR@"
 +
 +#endif /* _epivers_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/etsockio.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/etsockio.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/etsockio.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/etsockio.h  2005-11-07 01:12:51.827810000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/etsockio.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/etsockio.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/etsockio.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/etsockio.h     2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,60 @@
 +/*
 + * Driver-specific socket ioctls
@@ -8365,9 +8365,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/etsockio.h linux-2.6.12.5-br
 +};
 +
 +#endif
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flash.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flash.h     2005-11-07 01:12:51.827810000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/flash.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/flash.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/flash.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/flash.h        2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,184 @@
 +/*
 + * flash.h: Common definitions for flash access.
@@ -8553,9 +8553,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h linux-2.6.12.5-brcm/
 +extern flash_desc_t flashes[];
 +
 +#endif
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flashutl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flashutl.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/flashutl.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flashutl.h  2005-11-07 01:12:51.831810250 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/flashutl.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/flashutl.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/flashutl.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/flashutl.h     2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,34 @@
 +/*
 + * BCM47XX FLASH driver interface
@@ -8591,9 +8591,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flashutl.h linux-2.6.12.5-br
 +extern flash_cmds_t*  flashutl_cmd;
 +
 +#endif /* _flashutl_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/hnddma.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hnddma.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/hnddma.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hnddma.h    2005-11-07 01:12:51.831810250 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/hnddma.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/hnddma.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/hnddma.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/hnddma.h       2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,181 @@
 +/*
 + * Generic Broadcom Home Networking Division (HND) DMA engine definitions.
@@ -8776,9 +8776,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/hnddma.h linux-2.6.12.5-brcm
 +extern uint dma_txactive(di_t *di);
 +
 +#endif        /* _hnddma_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/hndmips.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hndmips.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/hndmips.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hndmips.h   2005-11-07 01:12:51.831810250 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/hndmips.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/hndmips.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/hndmips.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/hndmips.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,16 @@
 +/*
 + * Alternate include file for HND sbmips.h since CFE also ships with
@@ -8796,9 +8796,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/hndmips.h linux-2.6.12.5-brc
 + */
 +
 +#include "sbmips.h"
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linux_osl.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linux_osl.h 2005-11-07 01:12:51.831810250 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/linux_osl.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/linux_osl.h    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/linux_osl.h    2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,313 @@
 +/*
 + * Linux OS Independent Layer
@@ -9113,9 +9113,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-b
 +#endif        /* BINOSL */
 +
 +#endif        /* _linux_osl_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linuxver.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linuxver.h  2005-11-07 01:12:51.831810250 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/linuxver.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/linuxver.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/linuxver.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/linuxver.h     2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,326 @@
 +/*
 + * Linux-specific abstractions to gain some independence from linux kernel versions.
@@ -9443,9 +9443,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h linux-2.6.12.5-br
 +#endif
 +
 +#endif /* _linuxver_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/nvports.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/nvports.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/nvports.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/nvports.h   2005-11-07 01:12:51.831810250 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/nvports.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/nvports.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/nvports.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/nvports.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,62 @@
 +/*
 + * Broadcom Home Gateway Reference Design
@@ -9509,9 +9509,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/nvports.h linux-2.6.12.5-brc
 +
 +
 +
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/osl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/osl.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/osl.h    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/osl.h       2005-11-07 01:12:51.835810500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/osl.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/osl.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/osl.h  1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/osl.h  2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,38 @@
 +/*
 + * OS Independent Layer
@@ -9551,9 +9551,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/osl.h linux-2.6.12.5-brcm/ar
 +#define       SET_REG(r, mask, val)   W_REG((r), ((R_REG(r) & ~(mask)) | (val)))
 +
 +#endif        /* _osl_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/pcicfg.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/pcicfg.h    2005-11-07 01:12:51.835810500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/pcicfg.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/pcicfg.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/pcicfg.h       2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,362 @@
 +/*
 + * pcicfg.h: PCI configuration  constants and structures.
@@ -9917,9 +9917,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm
 +#define SPROM_CRC_RANGE               64      /* crc cover range in 16-bit */
 +
 +#endif
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/proto/802.11.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/802.11.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/proto/802.11.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/802.11.h      2005-11-07 01:12:51.835810500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/proto/802.11.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/proto/802.11.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/proto/802.11.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/proto/802.11.h 2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,679 @@
 +/*
 + * Copyright 2001-2003, Broadcom Corporation   
@@ -10600,9 +10600,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/proto/802.11.h linux-2.6.12.
 +#endif
 +
 +#endif /* _802_11_H_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/proto/ethernet.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/ethernet.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/proto/ethernet.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/ethernet.h    2005-11-07 01:12:51.835810500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/proto/ethernet.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/proto/ethernet.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/proto/ethernet.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/proto/ethernet.h       2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,145 @@
 +/*******************************************************************************
 + * $Id$
@@ -10749,9 +10749,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/proto/ethernet.h linux-2.6.1
 +#undef PACKED
 +
 +#endif /* _NET_ETHERNET_H_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/rts/crc.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/rts/crc.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/rts/crc.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/rts/crc.h   2005-11-07 01:12:51.835810500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/rts/crc.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/rts/crc.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/rts/crc.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/rts/crc.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,69 @@
 +/*******************************************************************************
 + * $Id$
@@ -10822,9 +10822,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/rts/crc.h linux-2.6.12.5-brc
 +#endif
 +
 +#endif /* _RTS_CRC_H_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/s5.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/s5.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/s5.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/s5.h        2005-11-07 01:12:51.835810500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/s5.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/s5.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/s5.h   1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/s5.h   2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,103 @@
 +#ifndef _S5_H_
 +#define _S5_H_
@@ -10929,9 +10929,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/s5.h linux-2.6.12.5-brcm/arc
 +
 +
 +#endif /*!_S5_H_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbchipc.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbchipc.h   2005-11-07 01:12:51.839810750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbchipc.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbchipc.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbchipc.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,281 @@
 +/*
 + * SiliconBackplane Chipcommon core hardware definitions.
@@ -11214,9 +11214,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +#define SFLASH_AT_ID_SHIFT                    3
 +
 +#endif        /* _SBCHIPC_H */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbconfig.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbconfig.h  2005-11-07 01:12:51.839810750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbconfig.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbconfig.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbconfig.h     2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,296 @@
 +/*
 + * Broadcom SiliconBackplane hardware register definitions.
@@ -11514,9 +11514,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-br
 +#define SB_ROBO                 0x81C           /* robo switch core */
 +
 +#endif        /* _SBCONFIG_H */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbextif.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbextif.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/sbextif.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbextif.h   2005-11-07 01:12:51.839810750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbextif.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbextif.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbextif.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbextif.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,242 @@
 +/*
 + * Hardware-specific External Interface I/O core definitions
@@ -11760,9 +11760,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbextif.h linux-2.6.12.5-brc
 +#define       CC_CLOCK_BASE   24000000        /* Half the clock freq. in the 4710 */
 +
 +#endif        /* _SBEXTIF_H */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmemc.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmemc.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmemc.h    2005-11-07 01:12:51.839810750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbmemc.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbmemc.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbmemc.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbmemc.h       2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,144 @@
 +/*
 + * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions.
@@ -11908,9 +11908,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmemc.h linux-2.6.12.5-brcm
 +#define MEMC_CONFIG_DDR               0x00000001
 +
 +#endif        /* _SBMEMC_H */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmips.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmips.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmips.h    2005-11-07 01:12:51.839810750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbmips.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbmips.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbmips.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbmips.h       2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,56 @@
 +/*
 + * Broadcom SiliconBackplane MIPS definitions
@@ -11968,9 +11968,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmips.h linux-2.6.12.5-brcm
 +#endif /* _LANGUAGE_ASSEMBLY */
 +
 +#endif        /* _SBMIPS_H */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpci.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpci.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/sbpci.h  1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpci.h     2005-11-07 01:12:51.839810750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbpci.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbpci.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbpci.h        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbpci.h        2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,113 @@
 +/*
 + * BCM47XX Sonics SiliconBackplane PCI core hardware definitions.
@@ -12085,9 +12085,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpci.h linux-2.6.12.5-brcm/
 +#endif /* !_LANGUAGE_ASSEMBLY */
 +
 +#endif        /* _SBPCI_H */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpcmcia.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/sbpcmcia.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpcmcia.h  2005-11-07 01:12:51.839810750 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbpcmcia.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbpcmcia.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbpcmcia.h     2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,131 @@
 +/*
 + * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions.
@@ -12220,9 +12220,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.6.12.5-br
 +#define HNBU_LED              0x09            /* LED set */
 +
 +#endif        /* _SBPCMCIA_H */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbsdram.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbsdram.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/sbsdram.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbsdram.h   2005-11-07 01:12:51.843811000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbsdram.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbsdram.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbsdram.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbsdram.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,75 @@
 +/*
 + * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions.
@@ -12299,9 +12299,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbsdram.h linux-2.6.12.5-brc
 +#define MEM8MX16X2    0xc29   /* 32 MB */
 +
 +#endif        /* _SBSDRAM_H */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbutils.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbutils.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/sbutils.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbutils.h   2005-11-07 01:12:51.843811000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbutils.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbutils.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/sbutils.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/sbutils.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,90 @@
 +/*
 + * Misc utility routines for accessing chip-specific features
@@ -12393,9 +12393,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbutils.h linux-2.6.12.5-brc
 +#define       CLK_DYNAMIC     2                       /* enable dynamic power control */
 +
 +#endif        /* _sbutils_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/trxhdr.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/trxhdr.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/trxhdr.h    2005-11-07 01:12:51.843811000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/trxhdr.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/trxhdr.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/trxhdr.h       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/trxhdr.h       2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,31 @@
 +/*
 + * TRX image file header format.
@@ -12428,9 +12428,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/trxhdr.h linux-2.6.12.5-brcm
 +
 +/* Compatibility */
 +typedef struct trx_header TRXHDR, *PTRXHDR;
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/typedefs.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/typedefs.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/typedefs.h       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/typedefs.h  2005-11-07 01:12:51.843811000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/typedefs.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/typedefs.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/typedefs.h     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/typedefs.h     2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,162 @@
 +/*
 + * Copyright 2001-2003, Broadcom Corporation   
@@ -12594,9 +12594,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/typedefs.h linux-2.6.12.5-br
 +#endif /* INLINE */
 +
 +#endif /* _TYPEDEFS_H_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/wlioctl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/wlioctl.h
---- linux-2.6.12.5/arch/mips/bcm947xx/include/wlioctl.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/wlioctl.h   2005-11-07 01:12:51.843811000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/include/wlioctl.h linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/wlioctl.h
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/include/wlioctl.h      1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/include/wlioctl.h      2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,690 @@
 +/*
 + * Custom OID/ioctl definitions for
@@ -13288,9 +13288,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/wlioctl.h linux-2.6.12.5-brc
 +#undef PACKED
 +
 +#endif /* _wlioctl_h_ */
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/int-handler.S linux-2.6.12.5-brcm/arch/mips/bcm947xx/int-handler.S
---- linux-2.6.12.5/arch/mips/bcm947xx/int-handler.S    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/int-handler.S       2005-11-07 01:12:51.843811000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/int-handler.S linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/int-handler.S
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/int-handler.S  1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/int-handler.S  2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,48 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
@@ -13340,9 +13340,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/int-handler.S linux-2.6.12.5-brcm/ar
 +      nop
 +              
 +      END(bcm47xx_irq_handler)
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/irq.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/irq.c
---- linux-2.6.12.5/arch/mips/bcm947xx/irq.c    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/irq.c       2005-11-19 02:16:15.531125500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/irq.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/irq.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/irq.c  1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/irq.c  2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,67 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
@@ -13411,9 +13411,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/irq.c linux-2.6.12.5-brcm/arch/mips/
 +      set_except_vector(0, bcm47xx_irq_handler);
 +      mips_cpu_irq_init(0);
 +}
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/Makefile linux-2.6.12.5-brcm/arch/mips/bcm947xx/Makefile
---- linux-2.6.12.5/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/Makefile    2005-11-07 01:12:51.811809000 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/Makefile linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/Makefile
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/Makefile       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/Makefile       2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,6 @@
 +#
 +# Makefile for the BCM47xx specific kernel interface routines
@@ -13421,9 +13421,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/Makefile linux-2.6.12.5-brcm/arch/mi
 +#
 +
 +obj-y := irq.o int-handler.o prom.o setup.o time.o
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/prom.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/prom.c
---- linux-2.6.12.5/arch/mips/bcm947xx/prom.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/prom.c      2005-11-07 01:12:51.847811250 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/prom.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/prom.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/prom.c 2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,59 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
@@ -13484,10 +13484,10 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/prom.c linux-2.6.12.5-brcm/arch/mips
 +{
 +      return 0;
 +}
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/setup.c
---- linux-2.6.12.5/arch/mips/bcm947xx/setup.c  1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/setup.c     2005-11-29 01:23:30.667381000 +0100
-@@ -0,0 +1,112 @@
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/setup.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/setup.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/setup.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/setup.c        2005-12-13 15:47:49.000000000 +0100
+@@ -0,0 +1,108 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
 + *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
@@ -13580,7 +13580,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mip
 +      while (1);
 +}
 +
-+static int __init bcm47xx_init(void)
++void __init plat_setup(void)
 +{
 +
 +      sbh = sb_kattach();
@@ -13595,14 +13595,10 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mip
 +      
 +      board_time_init = bcm47xx_time_init;
 +      board_timer_setup = bcm47xx_timer_setup;
-+      
-+      return 0;
 +}
-+
-+early_initcall(bcm47xx_init);
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/time.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/time.c
---- linux-2.6.12.5/arch/mips/bcm947xx/time.c   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/time.c      2005-11-07 01:12:51.847811250 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/bcm947xx/time.c linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/time.c
+--- linux-2.6.15-rc5/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/bcm947xx/time.c 2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,59 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
@@ -13663,10 +13659,10 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/time.c linux-2.6.12.5-brcm/arch/mips
 +      /* Enable the timer interrupt */
 +      setup_irq(7, irq);
 +}
-diff -Nur linux-2.6.12.5/arch/mips/Kconfig linux-2.6.12.5-brcm/arch/mips/Kconfig
---- linux-2.6.12.5/arch/mips/Kconfig   2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/Kconfig      2005-11-07 01:12:51.811809000 +0100
-@@ -40,6 +40,15 @@
+diff -Nur linux-2.6.15-rc5/arch/mips/Kconfig linux-2.6.15-rc5-openwrt/arch/mips/Kconfig
+--- linux-2.6.15-rc5/arch/mips/Kconfig 2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/Kconfig 2005-12-13 14:59:52.000000000 +0100
+@@ -244,6 +244,17 @@
         Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
         Olivetti M700-10 workstations.
  
@@ -13675,29 +13671,22 @@ diff -Nur linux-2.6.12.5/arch/mips/Kconfig linux-2.6.12.5-brcm/arch/mips/Kconfig
 +      select DMA_NONCOHERENT
 +      select HW_HAS_PCI
 +      select IRQ_CPU
-+      select CPU_LITTLE_ENDIAN
++      select SYS_HAS_CPU_MIPS32_R1
++      select SYS_SUPPORTS_32BIT_KERNEL
++      select SYS_SUPPORTS_LITTLE_ENDIAN
 +      help
 +       Support for BCM947xx based boards
-+       
- config ACER_PICA_61
-       bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)"
-       depends on MACH_JAZZ && EXPERIMENTAL
-@@ -974,7 +983,7 @@
- config CPU_LITTLE_ENDIAN
-       bool "Generate little endian code"
--      default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || MACH_DECSTATION || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || SOC_AU1X00 || NEC_OSPREY || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA
-+      default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || MACH_DECSTATION || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || SOC_AU1X00 || NEC_OSPREY || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA || BCM947XX
-       default n if MIPS_EV64120 || MIPS_EV96100 || MOMENCO_OCELOT || MOMENCO_OCELOT_G || SGI_IP22 || SGI_IP27 || SGI_IP32 || TOSHIBA_JMR3927
-       help
-         Some MIPS machines can be configured for either little or big endian
-diff -Nur linux-2.6.12.5/arch/mips/kernel/cpu-probe.c linux-2.6.12.5-brcm/arch/mips/kernel/cpu-probe.c
---- linux-2.6.12.5/arch/mips/kernel/cpu-probe.c        2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/kernel/cpu-probe.c   2005-11-07 01:12:51.847811250 +0100
-@@ -555,6 +555,28 @@
-       }
++
+ config LASAT
+       bool "Support for LASAT Networks platforms"
+       select DMA_NONCOHERENT
+diff -Nur linux-2.6.15-rc5/arch/mips/kernel/cpu-probe.c linux-2.6.15-rc5-openwrt/arch/mips/kernel/cpu-probe.c
+--- linux-2.6.15-rc5/arch/mips/kernel/cpu-probe.c      2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/kernel/cpu-probe.c      2005-12-13 14:59:52.000000000 +0100
+@@ -656,6 +656,28 @@
  }
  
 +static inline void cpu_probe_broadcom(struct cpuinfo_mips *c)
 +{
 +      decode_config1(c);
@@ -13706,13 +13695,13 @@ diff -Nur linux-2.6.12.5/arch/mips/kernel/cpu-probe.c linux-2.6.12.5-brcm/arch/m
 +                      c->cputype = CPU_BCM3302;
 +                      c->isa_level = MIPS_CPU_ISA_M32;
 +                      c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
-+                                      MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
++                                      MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER;
 +              break;
 +              case PRID_IMP_BCM4710:
 +                      c->cputype = CPU_BCM4710;
 +                      c->isa_level = MIPS_CPU_ISA_M32;
 +                      c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
-+                                      MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
++                                      MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER;
 +              break;
 +      default:
 +              c->cputype = CPU_UNKNOWN;
@@ -13723,21 +13712,20 @@ diff -Nur linux-2.6.12.5/arch/mips/kernel/cpu-probe.c linux-2.6.12.5-brcm/arch/m
  __init void cpu_probe(void)
  {
        struct cpuinfo_mips *c = &current_cpu_data;
-@@ -577,7 +599,9 @@
+@@ -678,6 +700,9 @@
        case PRID_COMP_SIBYTE:
                cpu_probe_sibyte(c);
                break;
--
 +      case PRID_COMP_BROADCOM:
 +              cpu_probe_broadcom(c);
 +              break;
        case PRID_COMP_SANDCRAFT:
                cpu_probe_sandcraft(c);
                break;
-diff -Nur linux-2.6.12.5/arch/mips/kernel/head.S linux-2.6.12.5-brcm/arch/mips/kernel/head.S
---- linux-2.6.12.5/arch/mips/kernel/head.S     2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/kernel/head.S        2005-11-07 01:12:51.847811250 +0100
-@@ -122,6 +122,14 @@
+diff -Nur linux-2.6.15-rc5/arch/mips/kernel/head.S linux-2.6.15-rc5-openwrt/arch/mips/kernel/head.S
+--- linux-2.6.15-rc5/arch/mips/kernel/head.S   2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/kernel/head.S   2005-12-13 14:59:52.000000000 +0100
+@@ -107,6 +107,14 @@
  #endif
        .endm
  
@@ -13752,42 +13740,23 @@ diff -Nur linux-2.6.12.5/arch/mips/kernel/head.S linux-2.6.12.5-brcm/arch/mips/k
        /*
         * Reserved space for exception handlers.
         * Necessary for machines which link their kernels at KSEG0.
-diff -Nur linux-2.6.12.5/arch/mips/kernel/proc.c linux-2.6.12.5-brcm/arch/mips/kernel/proc.c
---- linux-2.6.12.5/arch/mips/kernel/proc.c     2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/kernel/proc.c        2005-11-07 01:12:51.847811250 +0100
-@@ -75,7 +75,9 @@
-       [CPU_VR4133]    "NEC VR4133",
-       [CPU_VR4181]    "NEC VR4181",
-       [CPU_VR4181A]   "NEC VR4181A",
--      [CPU_SR71000]   "Sandcraft SR71000"
-+      [CPU_SR71000]   "Sandcraft SR71000",
-+      [CPU_BCM3302]   "Broadcom BCM3302",
-+      [CPU_BCM4710]   "Broadcom BCM4710"
+diff -Nur linux-2.6.15-rc5/arch/mips/kernel/proc.c linux-2.6.15-rc5-openwrt/arch/mips/kernel/proc.c
+--- linux-2.6.15-rc5/arch/mips/kernel/proc.c   2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/kernel/proc.c   2005-12-13 14:59:52.000000000 +0100
+@@ -82,6 +82,8 @@
+       [CPU_VR4181]    = "NEC VR4181",
+       [CPU_VR4181A]   = "NEC VR4181A",
+       [CPU_SR71000]   = "Sandcraft SR71000",
++      [CPU_BCM3302]   = "Broadcom BCM3302",
++      [CPU_BCM4710]   = "Broadcom BCM4710",
+       [CPU_PR4450]    = "Philips PR4450",
  };
  
-diff -Nur linux-2.6.12.5/arch/mips/Makefile linux-2.6.12.5-brcm/arch/mips/Makefile
---- linux-2.6.12.5/arch/mips/Makefile  2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/Makefile     2005-11-07 01:12:51.811809000 +0100
-@@ -79,7 +79,7 @@
- cflags-y                      += -I $(TOPDIR)/include/asm/gcc
- cflags-y                      += -G 0 -mno-abicalls -fno-pic -pipe
- cflags-y                      += $(call cc-option, -finline-limit=100000)
--LDFLAGS_vmlinux                       += -G 0 -static -n
-+LDFLAGS_vmlinux                       += -G 0 -static -n -nostdlib
- MODFLAGS                      += -mlong-calls
- cflags-$(CONFIG_SB1XXX_CORELIS)       += -mno-sched-prolog -fno-omit-frame-pointer
-@@ -170,6 +170,7 @@
- cflags-$(CONFIG_CPU_MIPS32)   += \
-                       $(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
-                       -Wa,--trap
-+cflags-$(CONFIG_CPU_MIPS32)   += -Wa,--trap
- cflags-$(CONFIG_CPU_MIPS64)   += \
-                       $(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
-@@ -618,6 +619,14 @@
- load-$(CONFIG_SIBYTE_SWARM)   := 0xffffffff80100000
+diff -Nur linux-2.6.15-rc5/arch/mips/Makefile linux-2.6.15-rc5-openwrt/arch/mips/Makefile
+--- linux-2.6.15-rc5/arch/mips/Makefile        2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/Makefile        2005-12-13 14:59:52.000000000 +0100
+@@ -689,6 +689,13 @@
+ load-$(CONFIG_SIBYTE_BIGSUR)  := 0xffffffff80100000
  
  #
 +# Broadcom BCM47XX boards
@@ -13796,15 +13765,14 @@ diff -Nur linux-2.6.12.5/arch/mips/Makefile linux-2.6.12.5-brcm/arch/mips/Makefi
 +cflags-$(CONFIG_BCM947XX)     += -Iarch/mips/bcm947xx/include
 +load-$(CONFIG_BCM947XX)               := 0xffffffff80001000
 +
-+
 +#
  # SNI RM200 PCI
  #
  core-$(CONFIG_SNI_RM200_PCI)  += arch/mips/sni/
-diff -Nur linux-2.6.12.5/arch/mips/mm/tlbex.c linux-2.6.12.5-brcm/arch/mips/mm/tlbex.c
---- linux-2.6.12.5/arch/mips/mm/tlbex.c        2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/mm/tlbex.c   2005-11-07 01:12:51.851811500 +0100
-@@ -851,6 +851,8 @@
+diff -Nur linux-2.6.15-rc5/arch/mips/mm/tlbex.c linux-2.6.15-rc5-openwrt/arch/mips/mm/tlbex.c
+--- linux-2.6.15-rc5/arch/mips/mm/tlbex.c      2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/mm/tlbex.c      2005-12-13 14:59:52.000000000 +0100
+@@ -858,6 +858,8 @@
        case CPU_4KSC:
        case CPU_20KC:
        case CPU_25KF:
@@ -13813,9 +13781,9 @@ diff -Nur linux-2.6.12.5/arch/mips/mm/tlbex.c linux-2.6.12.5-brcm/arch/mips/mm/t
                tlbw(p);
                break;
  
-diff -Nur linux-2.6.12.5/arch/mips/pci/fixup-bcm47xx.c linux-2.6.12.5-brcm/arch/mips/pci/fixup-bcm47xx.c
---- linux-2.6.12.5/arch/mips/pci/fixup-bcm47xx.c       1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/pci/fixup-bcm47xx.c  2005-11-07 01:12:51.851811500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/pci/fixup-bcm47xx.c linux-2.6.15-rc5-openwrt/arch/mips/pci/fixup-bcm47xx.c
+--- linux-2.6.15-rc5/arch/mips/pci/fixup-bcm47xx.c     1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/pci/fixup-bcm47xx.c     2005-12-13 15:04:21.000000000 +0100
 @@ -0,0 +1,23 @@
 +#include <linux/init.h>
 +#include <linux/pci.h>
@@ -13837,23 +13805,23 @@ diff -Nur linux-2.6.12.5/arch/mips/pci/fixup-bcm47xx.c linux-2.6.12.5-brcm/arch/
 +      return irq + 2;
 +}
 +
-+struct pci_fixup pcibios_fixups[] __initdata = {
++struct pci_fixup pcibios_fixups[] = {
 +      { 0 }
 +};
-diff -Nur linux-2.6.12.5/arch/mips/pci/Makefile linux-2.6.12.5-brcm/arch/mips/pci/Makefile
---- linux-2.6.12.5/arch/mips/pci/Makefile      2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/pci/Makefile 2005-11-07 01:12:51.851811500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/pci/Makefile linux-2.6.15-rc5-openwrt/arch/mips/pci/Makefile
+--- linux-2.6.15-rc5/arch/mips/pci/Makefile    2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/pci/Makefile    2005-12-13 14:59:52.000000000 +0100
 @@ -18,6 +18,7 @@
- obj-$(CONFIG_MIPS_TX3927)     += ops-jmr3927.o
+ obj-$(CONFIG_MIPS_TX3927)     += ops-tx3927.o
  obj-$(CONFIG_PCI_VR41XX)      += ops-vr41xx.o pci-vr41xx.o
  obj-$(CONFIG_NEC_CMBVR4133)   += fixup-vr4133.o
 +obj-$(CONFIG_BCM947XX)                += ops-sb.o fixup-bcm47xx.o pci-bcm47xx.o
  
  #
  # These are still pretty much in the old state, watch, go blind.
-diff -Nur linux-2.6.12.5/arch/mips/pci/ops-sb.c linux-2.6.12.5-brcm/arch/mips/pci/ops-sb.c
---- linux-2.6.12.5/arch/mips/pci/ops-sb.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/pci/ops-sb.c 2005-11-07 01:12:51.851811500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/pci/ops-sb.c linux-2.6.15-rc5-openwrt/arch/mips/pci/ops-sb.c
+--- linux-2.6.15-rc5/arch/mips/pci/ops-sb.c    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/pci/ops-sb.c    2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,44 @@
 +#include <linux/kernel.h>
 +#include <linux/init.h>
@@ -13899,9 +13867,9 @@ diff -Nur linux-2.6.12.5/arch/mips/pci/ops-sb.c linux-2.6.12.5-brcm/arch/mips/pc
 +      .read = sb_pci_read_config,
 +      .write = sb_pci_write_config,
 +};
-diff -Nur linux-2.6.12.5/arch/mips/pci/pci-bcm47xx.c linux-2.6.12.5-brcm/arch/mips/pci/pci-bcm47xx.c
---- linux-2.6.12.5/arch/mips/pci/pci-bcm47xx.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/pci/pci-bcm47xx.c    2005-11-07 01:12:51.851811500 +0100
+diff -Nur linux-2.6.15-rc5/arch/mips/pci/pci-bcm47xx.c linux-2.6.15-rc5-openwrt/arch/mips/pci/pci-bcm47xx.c
+--- linux-2.6.15-rc5/arch/mips/pci/pci-bcm47xx.c       1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/pci/pci-bcm47xx.c       2005-12-13 14:59:52.000000000 +0100
 @@ -0,0 +1,61 @@
 +#include <linux/init.h>
 +#include <linux/pci.h>
@@ -13964,10 +13932,10 @@ diff -Nur linux-2.6.12.5/arch/mips/pci/pci-bcm47xx.c linux-2.6.12.5-brcm/arch/mi
 +}
 +
 +early_initcall(bcm47xx_pci_init);
-diff -Nur linux-2.6.12.5/arch/mips/pci/pci.c linux-2.6.12.5-brcm/arch/mips/pci/pci.c
---- linux-2.6.12.5/arch/mips/pci/pci.c 2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/pci/pci.c    2005-11-07 01:12:51.851811500 +0100
-@@ -238,7 +238,8 @@
+diff -Nur linux-2.6.15-rc5/arch/mips/pci/pci.c linux-2.6.15-rc5-openwrt/arch/mips/pci/pci.c
+--- linux-2.6.15-rc5/arch/mips/pci/pci.c       2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/arch/mips/pci/pci.c       2005-12-13 14:59:52.000000000 +0100
+@@ -243,7 +243,8 @@
                if (dev->resource[i].flags & IORESOURCE_IO)
                        offset = hose->io_offset;
                else if (dev->resource[i].flags & IORESOURCE_MEM)
@@ -13977,10 +13945,10 @@ diff -Nur linux-2.6.12.5/arch/mips/pci/pci.c linux-2.6.12.5-brcm/arch/mips/pci/p
  
                dev->resource[i].start += offset;
                dev->resource[i].end += offset;
-diff -Nur linux-2.6.12.5/include/asm-mips/bootinfo.h linux-2.6.12.5-brcm/include/asm-mips/bootinfo.h
---- linux-2.6.12.5/include/asm-mips/bootinfo.h 2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/include/asm-mips/bootinfo.h    2005-11-07 01:12:51.851811500 +0100
-@@ -213,6 +213,12 @@
+diff -Nur linux-2.6.15-rc5/include/asm-mips/bootinfo.h linux-2.6.15-rc5-openwrt/include/asm-mips/bootinfo.h
+--- linux-2.6.15-rc5/include/asm-mips/bootinfo.h       2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/include/asm-mips/bootinfo.h       2005-12-13 14:59:52.000000000 +0100
+@@ -218,6 +218,12 @@
  #define MACH_GROUP_TITAN       22     /* PMC-Sierra Titan             */
  #define  MACH_TITAN_YOSEMITE  1       /* PMC-Sierra Yosemite          */
  
@@ -13993,10 +13961,10 @@ diff -Nur linux-2.6.12.5/include/asm-mips/bootinfo.h linux-2.6.12.5-brcm/include
  #define CL_SIZE                       COMMAND_LINE_SIZE
  
  const char *get_system_type(void);
-diff -Nur linux-2.6.12.5/include/asm-mips/cpu.h linux-2.6.12.5-brcm/include/asm-mips/cpu.h
---- linux-2.6.12.5/include/asm-mips/cpu.h      2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/include/asm-mips/cpu.h 2005-11-07 01:12:51.851811500 +0100
-@@ -87,6 +87,13 @@
+diff -Nur linux-2.6.15-rc5/include/asm-mips/cpu.h linux-2.6.15-rc5-openwrt/include/asm-mips/cpu.h
+--- linux-2.6.15-rc5/include/asm-mips/cpu.h    2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/include/asm-mips/cpu.h    2005-12-13 14:59:52.000000000 +0100
+@@ -102,6 +102,13 @@
  #define PRID_IMP_SR71000        0x0400
  
  /*
@@ -14010,42 +13978,20 @@ diff -Nur linux-2.6.12.5/include/asm-mips/cpu.h linux-2.6.12.5-brcm/include/asm-
   * Definitions for 7:0 on legacy processors
   */
  
-@@ -177,7 +184,9 @@
- #define CPU_VR4133            56
- #define CPU_AU1550            57
- #define CPU_24K                       58
--#define CPU_LAST              58
-+#define CPU_BCM3302           59
-+#define CPU_BCM4710           60
-+#define CPU_LAST              60
+@@ -196,7 +203,9 @@
+ #define CPU_34K                       60
+ #define CPU_PR4450            61
+ #define CPU_SB1A              62
+-#define CPU_LAST              62
++#define CPU_BCM3302           63
++#define CPU_BCM4710           64
++#define CPU_LAST              64
  
  /*
   * ISA Level encodings
-diff -Nur linux-2.6.12.5/include/asm-mips/mipsregs.h linux-2.6.12.5-brcm/include/asm-mips/mipsregs.h
---- linux-2.6.12.5/include/asm-mips/mipsregs.h 2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/include/asm-mips/mipsregs.h    2005-11-07 01:12:51.855811750 +0100
-@@ -790,10 +790,18 @@
- #define read_c0_config1()     __read_32bit_c0_register($16, 1)
- #define read_c0_config2()     __read_32bit_c0_register($16, 2)
- #define read_c0_config3()     __read_32bit_c0_register($16, 3)
-+#define read_c0_config4()     __read_32bit_c0_register($16, 4)
-+#define read_c0_config5()     __read_32bit_c0_register($16, 5)
-+#define read_c0_config6()     __read_32bit_c0_register($16, 6)
-+#define read_c0_config7()     __read_32bit_c0_register($16, 7)
- #define write_c0_config(val)  __write_32bit_c0_register($16, 0, val)
- #define write_c0_config1(val) __write_32bit_c0_register($16, 1, val)
- #define write_c0_config2(val) __write_32bit_c0_register($16, 2, val)
- #define write_c0_config3(val) __write_32bit_c0_register($16, 3, val)
-+#define write_c0_config4(val) __write_32bit_c0_register($16, 4, val)
-+#define write_c0_config5(val) __write_32bit_c0_register($16, 5, val)
-+#define write_c0_config6(val) __write_32bit_c0_register($16, 6, val)
-+#define write_c0_config7(val) __write_32bit_c0_register($16, 7, val)
- /*
-  * The WatchLo register.  There may be upto 8 of them.
-diff -Nur linux-2.6.12.5/include/linux/init.h linux-2.6.12.5-brcm/include/linux/init.h
---- linux-2.6.12.5/include/linux/init.h        2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/include/linux/init.h   2005-11-07 01:12:51.855811750 +0100
+diff -Nur linux-2.6.15-rc5/include/linux/init.h linux-2.6.15-rc5-openwrt/include/linux/init.h
+--- linux-2.6.15-rc5/include/linux/init.h      2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/include/linux/init.h      2005-12-13 14:59:52.000000000 +0100
 @@ -86,6 +86,8 @@
        static initcall_t __initcall_##fn __attribute_used__ \
        __attribute__((__section__(".initcall" level ".init"))) = fn
@@ -14055,10 +14001,10 @@ diff -Nur linux-2.6.12.5/include/linux/init.h linux-2.6.12.5-brcm/include/linux/
  #define core_initcall(fn)             __define_initcall("1",fn)
  #define postcore_initcall(fn)         __define_initcall("2",fn)
  #define arch_initcall(fn)             __define_initcall("3",fn)
-diff -Nur linux-2.6.12.5/include/linux/pci_ids.h linux-2.6.12.5-brcm/include/linux/pci_ids.h
---- linux-2.6.12.5/include/linux/pci_ids.h     2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/include/linux/pci_ids.h        2005-11-07 01:12:51.855811750 +0100
-@@ -2110,6 +2110,7 @@
+diff -Nur linux-2.6.15-rc5/include/linux/pci_ids.h linux-2.6.15-rc5-openwrt/include/linux/pci_ids.h
+--- linux-2.6.15-rc5/include/linux/pci_ids.h   2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/include/linux/pci_ids.h   2005-12-13 14:59:52.000000000 +0100
+@@ -1835,6 +1835,7 @@
  #define PCI_DEVICE_ID_TIGON3_5901_2   0x170e
  #define PCI_DEVICE_ID_BCM4401         0x4401
  #define PCI_DEVICE_ID_BCM4401B0               0x4402
diff --git a/openwrt/target/linux/linux-2.6/patches/generic/000-reenable_devfs.patch b/openwrt/target/linux/linux-2.6/patches/generic/000-reenable_devfs.patch
new file mode 100644 (file)
index 0000000..ce98def
--- /dev/null
@@ -0,0 +1,219 @@
+diff -ur linux-2.6.15-rc5/drivers/mtd/mtd_blkdevs.c linux-2.6.15-rc5-openwrt/drivers/mtd/mtd_blkdevs.c
+--- linux-2.6.15-rc5/drivers/mtd/mtd_blkdevs.c 2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/drivers/mtd/mtd_blkdevs.c 2005-12-15 07:53:20.000000000 +0100
+@@ -21,6 +21,9 @@
+ #include <linux/init.h>
+ #include <asm/semaphore.h>
+ #include <asm/uaccess.h>
++#ifdef CONFIG_DEVFS_FS
++#include <linux/devfs_fs_kernel.h>
++#endif
+ static LIST_HEAD(blktrans_majors);
+@@ -302,6 +305,11 @@
+               snprintf(gd->disk_name, sizeof(gd->disk_name),
+                        "%s%d", tr->name, new->devnum);
++#ifdef CONFIG_DEVFS_FS
++              snprintf(gd->devfs_name, sizeof(gd->devfs_name),
++                       "%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum);
++#endif
++
+       /* 2.5 has capacity in units of 512 bytes while still
+          having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
+       set_capacity(gd, (new->size * new->blksize) >> 9);
+@@ -418,6 +426,10 @@
+               return ret;
+       }
++#ifdef CONFIG_DEVFS_FS
++      devfs_mk_dir(tr->name);
++#endif
++
+       INIT_LIST_HEAD(&tr->devs);
+       list_add(&tr->list, &blktrans_majors);
+@@ -450,6 +462,10 @@
+               tr->remove_dev(dev);
+       }
++#ifdef CONFIG_DEVFS_FS
++      devfs_remove(tr->name);
++#endif
++
+       blk_cleanup_queue(tr->blkcore_priv->rq);
+       unregister_blkdev(tr->major, tr->name);
+diff -ur linux-2.6.15-rc5/drivers/mtd/mtdchar.c linux-2.6.15-rc5-openwrt/drivers/mtd/mtdchar.c
+--- linux-2.6.15-rc5/drivers/mtd/mtdchar.c     2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/drivers/mtd/mtdchar.c     2005-12-15 07:49:15.000000000 +0100
+@@ -6,7 +6,6 @@
+  */
+ #include <linux/config.h>
+-#include <linux/device.h>
+ #include <linux/fs.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+@@ -19,19 +18,33 @@
+ #include <asm/uaccess.h>
++#ifdef CONFIG_DEVFS_FS
++#include <linux/devfs_fs_kernel.h>
++#else
++#include <linux/device.h>
++
+ static struct class *mtd_class;
++#endif
+ static void mtd_notify_add(struct mtd_info* mtd)
+ {
+       if (!mtd)
+               return;
++#ifdef CONFIG_DEVFS_FS
++      devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
++                      S_IFCHR | S_IRUGO | S_IWUGO, "mtd/%d", mtd->index);
++
++      devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
++                      S_IFCHR | S_IRUGO, "mtd/%dro", mtd->index);
++#else
+       class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
+                           NULL, "mtd%d", mtd->index);
+       class_device_create(mtd_class, NULL,
+                           MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
+                           NULL, "mtd%dro", mtd->index);
++#endif
+ }
+ static void mtd_notify_remove(struct mtd_info* mtd)
+@@ -39,8 +52,13 @@
+       if (!mtd)
+               return;
++#ifdef CONFIG_DEVFS_FS
++      devfs_remove("mtd/%d", mtd->index);
++      devfs_remove("mtd/%dro", mtd->index);
++#else
+       class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2));
+       class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1));
++#endif
+ }
+ static struct mtd_notifier notifier = {
+@@ -48,6 +66,22 @@
+       .remove = mtd_notify_remove,
+ };
++#ifdef CONFIG_DEVFS_FS
++      static inline void mtdchar_devfs_init(void)
++      {
++              devfs_mk_dir("mtd");
++              register_mtd_user(&notifier);
++      }
++      static inline void mtdchar_devfs_exit(void)
++      {
++              unregister_mtd_user(&notifier);
++              devfs_remove("mtd");
++      }
++      #else /* !DEVFS */
++      #define mtdchar_devfs_init() do { } while(0)
++      #define mtdchar_devfs_exit() do { } while(0)
++#endif
++
+ /*
+  * We use file->private_data to store a pointer to the MTDdevice.
+  * Since alighment is at least 32 bits, we have 2 bits free for OTP
+@@ -643,6 +677,9 @@
+               return -EAGAIN;
+       }
++#ifdef CONFIG_DEVFS_FS
++      mtdchar_devfs_init();
++#else
+       mtd_class = class_create(THIS_MODULE, "mtd");
+       if (IS_ERR(mtd_class)) {
+@@ -652,13 +689,19 @@
+       }
+       register_mtd_user(&notifier);
++#endif
+       return 0;
+ }
+ static void __exit cleanup_mtdchar(void)
+ {
++
++#ifdef CONFIG_DEVFS_FS
++      mtdchar_devfs_exit();
++#else
+       unregister_mtd_user(&notifier);
+       class_destroy(mtd_class);
++#endif
+       unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
+ }
+diff -ur linux-2.6.15-rc5/fs/Kconfig linux-2.6.15-rc5-openwrt/fs/Kconfig
+--- linux-2.6.15-rc5/fs/Kconfig        2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/fs/Kconfig        2005-12-15 07:44:01.000000000 +0100
+@@ -772,6 +772,56 @@
+         help
+         Exports the dump image of crashed kernel in ELF format.
++config DEVFS_FS
++      bool "/dev file system support (OBSOLETE)"
++      depends on EXPERIMENTAL
++      help
++        This is support for devfs, a virtual file system (like /proc) which
++        provides the file system interface to device drivers, normally found
++        in /dev. Devfs does not depend on major and minor number
++        allocations. Device drivers register entries in /dev which then
++        appear automatically, which means that the system administrator does
++        not have to create character and block special device files in the
++        /dev directory using the mknod command (or MAKEDEV script) anymore.
++
++        This is work in progress. If you want to use this, you *must* read
++        the material in <file:Documentation/filesystems/devfs/>, especially
++        the file README there.
++
++        Note that devfs no longer manages /dev/pts!  If you are using UNIX98
++        ptys, you will also need to mount the /dev/pts filesystem (devpts).
++
++        Note that devfs has been obsoleted by udev,
++        <http://www.kernel.org/pub/linux/utils/kernel/hotplug/>.
++        It has been stripped down to a bare minimum and is only provided for
++        legacy installations that use its naming scheme which is
++        unfortunately different from the names normal Linux installations
++        use.
++
++        If unsure, say N.
++
++config DEVFS_MOUNT
++      bool "Automatically mount at boot"
++      depends on DEVFS_FS
++      help
++        This option appears if you have CONFIG_DEVFS_FS enabled. Setting
++        this to 'Y' will make the kernel automatically mount devfs onto /dev
++        when the system is booted, before the init thread is started.
++        You can override this with the "devfs=nomount" boot option.
++
++        If unsure, say N.
++
++config DEVFS_DEBUG
++      bool "Debug devfs"
++      depends on DEVFS_FS
++      help
++        If you say Y here, then the /dev file system code will generate
++        debugging messages. See the file
++        <file:Documentation/filesystems/devfs/boot-options> for more
++        details.
++
++        If unsure, say N.
++
+ config SYSFS
+       bool "sysfs file system support" if EMBEDDED
+       default y
diff --git a/openwrt/target/linux/linux-2.6/patches/generic/003-net-b44-1.patch b/openwrt/target/linux/linux-2.6/patches/generic/003-net-b44-1.patch
new file mode 100644 (file)
index 0000000..726ea54
--- /dev/null
@@ -0,0 +1,807 @@
+diff -ur linux-2.6.15-rc5/drivers/net/b44.c linux-2.6.15-rc5-openwrt/drivers/net/b44.c
+--- linux-2.6.15-rc5/drivers/net/b44.c 2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/drivers/net/b44.c 2005-08-15 02:20:18.000000000 +0200
+@@ -18,7 +18,7 @@
+ #include <linux/pci.h>
+ #include <linux/delay.h>
+ #include <linux/init.h>
+-#include <linux/dma-mapping.h>
++#include <linux/version.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -28,8 +28,8 @@
+ #define DRV_MODULE_NAME               "b44"
+ #define PFX DRV_MODULE_NAME   ": "
+-#define DRV_MODULE_VERSION    "0.97"
+-#define DRV_MODULE_RELDATE    "Nov 30, 2005"
++#define DRV_MODULE_VERSION    "0.95"
++#define DRV_MODULE_RELDATE    "Aug 3, 2004"
+ #define B44_DEF_MSG_ENABLE      \
+       (NETIF_MSG_DRV          | \
+@@ -101,35 +101,10 @@
+ static void b44_halt(struct b44 *);
+ static void b44_init_rings(struct b44 *);
+ static void b44_init_hw(struct b44 *);
+-
+-static int dma_desc_align_mask;
+-static int dma_desc_sync_size;
+-
+-static const char b44_gstrings[][ETH_GSTRING_LEN] = {
+-#define _B44(x...)    # x,
+-B44_STAT_REG_DECLARE
+-#undef _B44
+-};
+-
+-static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
+-                                                dma_addr_t dma_base,
+-                                                unsigned long offset,
+-                                                enum dma_data_direction dir)
+-{
+-      dma_sync_single_range_for_device(&pdev->dev, dma_base,
+-                                       offset & dma_desc_align_mask,
+-                                       dma_desc_sync_size, dir);
+-}
+-
+-static inline void b44_sync_dma_desc_for_cpu(struct pci_dev *pdev,
+-                                             dma_addr_t dma_base,
+-                                             unsigned long offset,
+-                                             enum dma_data_direction dir)
+-{
+-      dma_sync_single_range_for_cpu(&pdev->dev, dma_base,
+-                                    offset & dma_desc_align_mask,
+-                                    dma_desc_sync_size, dir);
+-}
++static int b44_poll(struct net_device *dev, int *budget);
++#ifdef CONFIG_NET_POLL_CONTROLLER
++static void b44_poll_controller(struct net_device *dev);
++#endif
+ static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
+ {
+@@ -503,10 +478,7 @@
+       for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
+               *val++ += br32(bp, reg);
+       }
+-
+-      /* Pad */
+-      reg += 8*4UL;
+-
++      val = &bp->hw_stats.rx_good_octets;
+       for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
+               *val++ += br32(bp, reg);
+       }
+@@ -657,7 +629,7 @@
+       /* Hardware bug work-around, the chip is unable to do PCI DMA
+          to/from anything above 1GB :-( */
+-      if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
++      if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) {
+               /* Sigh... */
+               pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
+               dev_kfree_skb_any(skb);
+@@ -667,7 +639,7 @@
+               mapping = pci_map_single(bp->pdev, skb->data,
+                                        RX_PKT_BUF_SZ,
+                                        PCI_DMA_FROMDEVICE);
+-              if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
++              if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) {
+                       pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
+                       dev_kfree_skb_any(skb);
+                       return -ENOMEM;
+@@ -696,11 +668,6 @@
+       dp->ctrl = cpu_to_le32(ctrl);
+       dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset);
+-      if (bp->flags & B44_FLAG_RX_RING_HACK)
+-              b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
+-                                           dest_idx * sizeof(dp),
+-                                           DMA_BIDIRECTIONAL);
+-
+       return RX_PKT_BUF_SZ;
+ }
+@@ -725,11 +692,6 @@
+       pci_unmap_addr_set(dest_map, mapping,
+                          pci_unmap_addr(src_map, mapping));
+-      if (bp->flags & B44_FLAG_RX_RING_HACK)
+-              b44_sync_dma_desc_for_cpu(bp->pdev, bp->rx_ring_dma,
+-                                        src_idx * sizeof(src_desc),
+-                                        DMA_BIDIRECTIONAL);
+-
+       ctrl = src_desc->ctrl;
+       if (dest_idx == (B44_RX_RING_SIZE - 1))
+               ctrl |= cpu_to_le32(DESC_CTRL_EOT);
+@@ -738,14 +700,8 @@
+       dest_desc->ctrl = ctrl;
+       dest_desc->addr = src_desc->addr;
+-
+       src_map->skb = NULL;
+-      if (bp->flags & B44_FLAG_RX_RING_HACK)
+-              b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
+-                                           dest_idx * sizeof(dest_desc),
+-                                           DMA_BIDIRECTIONAL);
+-
+       pci_dma_sync_single_for_device(bp->pdev, src_desc->addr,
+                                      RX_PKT_BUF_SZ,
+                                      PCI_DMA_FROMDEVICE);
+@@ -894,10 +850,11 @@
+ {
+       struct net_device *dev = dev_id;
+       struct b44 *bp = netdev_priv(dev);
++      unsigned long flags;
+       u32 istat, imask;
+       int handled = 0;
+-      spin_lock(&bp->lock);
++      spin_lock_irqsave(&bp->lock, flags);
+       istat = br32(bp, B44_ISTAT);
+       imask = br32(bp, B44_IMASK);
+@@ -908,12 +865,6 @@
+       istat &= imask;
+       if (istat) {
+               handled = 1;
+-
+-              if (unlikely(!netif_running(dev))) {
+-                      printk(KERN_INFO "%s: late interrupt.\n", dev->name);
+-                      goto irq_ack;
+-              }
+-
+               if (netif_rx_schedule_prep(dev)) {
+                       /* NOTE: These writes are posted by the readback of
+                        *       the ISTAT register below.
+@@ -926,11 +877,10 @@
+                              dev->name);
+               }
+-irq_ack:
+               bw32(bp, B44_ISTAT, istat);
+               br32(bp, B44_ISTAT);
+       }
+-      spin_unlock(&bp->lock);
++      spin_unlock_irqrestore(&bp->lock, flags);
+       return IRQ_RETVAL(handled);
+ }
+@@ -958,7 +908,6 @@
+ {
+       struct b44 *bp = netdev_priv(dev);
+       struct sk_buff *bounce_skb;
+-      int rc = NETDEV_TX_OK;
+       dma_addr_t mapping;
+       u32 len, entry, ctrl;
+@@ -968,28 +917,29 @@
+       /* This is a hard error, log it. */
+       if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
+               netif_stop_queue(dev);
++              spin_unlock_irq(&bp->lock);
+               printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
+                      dev->name);
+-              goto err_out;
++              return 1;
+       }
+       mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+-      if (mapping + len > B44_DMA_MASK) {
++      if(mapping+len > B44_DMA_MASK) {
+               /* Chip can't handle DMA to/from >1GB, use bounce buffer */
+               pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
+               bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
+                                            GFP_ATOMIC|GFP_DMA);
+               if (!bounce_skb)
+-                      goto err_out;
++                      return NETDEV_TX_BUSY;
+               mapping = pci_map_single(bp->pdev, bounce_skb->data,
+                                        len, PCI_DMA_TODEVICE);
+-              if (mapping + len > B44_DMA_MASK) {
++              if(mapping+len > B44_DMA_MASK) {
+                       pci_unmap_single(bp->pdev, mapping,
+                                        len, PCI_DMA_TODEVICE);
+                       dev_kfree_skb_any(bounce_skb);
+-                      goto err_out;
++                      return NETDEV_TX_BUSY;
+               }
+               memcpy(skb_put(bounce_skb, len), skb->data, skb->len);
+@@ -1009,11 +959,6 @@
+       bp->tx_ring[entry].ctrl = cpu_to_le32(ctrl);
+       bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);
+-      if (bp->flags & B44_FLAG_TX_RING_HACK)
+-              b44_sync_dma_desc_for_device(bp->pdev, bp->tx_ring_dma,
+-                                           entry * sizeof(bp->tx_ring[0]),
+-                                           DMA_TO_DEVICE);
+-
+       entry = NEXT_TX(entry);
+       bp->tx_prod = entry;
+@@ -1029,16 +974,11 @@
+       if (TX_BUFFS_AVAIL(bp) < 1)
+               netif_stop_queue(dev);
+-      dev->trans_start = jiffies;
+-
+-out_unlock:
+       spin_unlock_irq(&bp->lock);
+-      return rc;
++      dev->trans_start = jiffies;
+-err_out:
+-      rc = NETDEV_TX_BUSY;
+-      goto out_unlock;
++      return 0;
+ }
+ static int b44_change_mtu(struct net_device *dev, int new_mtu)
+@@ -1112,7 +1052,8 @@
+  *
+  * The chip has been shut down and the driver detached from
+  * the networking, so no interrupts or new tx packets will
+- * end up in the driver.
++ * end up in the driver.  bp->lock is not held and we are not
++ * in an interrupt context and thus may sleep.
+  */
+ static void b44_init_rings(struct b44 *bp)
+ {
+@@ -1123,16 +1064,6 @@
+       memset(bp->rx_ring, 0, B44_RX_RING_BYTES);
+       memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
+-      if (bp->flags & B44_FLAG_RX_RING_HACK)
+-              dma_sync_single_for_device(&bp->pdev->dev, bp->rx_ring_dma,
+-                                         DMA_TABLE_BYTES,
+-                                         PCI_DMA_BIDIRECTIONAL);
+-
+-      if (bp->flags & B44_FLAG_TX_RING_HACK)
+-              dma_sync_single_for_device(&bp->pdev->dev, bp->tx_ring_dma,
+-                                         DMA_TABLE_BYTES,
+-                                         PCI_DMA_TODEVICE);
+-
+       for (i = 0; i < bp->rx_pending; i++) {
+               if (b44_alloc_rx_skb(bp, -1, i) < 0)
+                       break;
+@@ -1145,33 +1076,23 @@
+  */
+ static void b44_free_consistent(struct b44 *bp)
+ {
+-      kfree(bp->rx_buffers);
+-      bp->rx_buffers = NULL;
+-      kfree(bp->tx_buffers);
+-      bp->tx_buffers = NULL;
++      if (bp->rx_buffers) {
++              kfree(bp->rx_buffers);
++              bp->rx_buffers = NULL;
++      }
++      if (bp->tx_buffers) {
++              kfree(bp->tx_buffers);
++              bp->tx_buffers = NULL;
++      }
+       if (bp->rx_ring) {
+-              if (bp->flags & B44_FLAG_RX_RING_HACK) {
+-                      dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
+-                                       DMA_TABLE_BYTES,
+-                                       DMA_BIDIRECTIONAL);
+-                      kfree(bp->rx_ring);
+-              } else
+-                      pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
+-                                          bp->rx_ring, bp->rx_ring_dma);
++              pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
++                                  bp->rx_ring, bp->rx_ring_dma);
+               bp->rx_ring = NULL;
+-              bp->flags &= ~B44_FLAG_RX_RING_HACK;
+       }
+       if (bp->tx_ring) {
+-              if (bp->flags & B44_FLAG_TX_RING_HACK) {
+-                      dma_unmap_single(&bp->pdev->dev, bp->tx_ring_dma,
+-                                       DMA_TABLE_BYTES,
+-                                       DMA_TO_DEVICE);
+-                      kfree(bp->tx_ring);
+-              } else
+-                      pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
+-                                          bp->tx_ring, bp->tx_ring_dma);
++              pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
++                                  bp->tx_ring, bp->tx_ring_dma);
+               bp->tx_ring = NULL;
+-              bp->flags &= ~B44_FLAG_TX_RING_HACK;
+       }
+ }
+@@ -1184,67 +1105,25 @@
+       int size;
+       size  = B44_RX_RING_SIZE * sizeof(struct ring_info);
+-      bp->rx_buffers = kzalloc(size, GFP_KERNEL);
++      bp->rx_buffers = kmalloc(size, GFP_KERNEL);
+       if (!bp->rx_buffers)
+               goto out_err;
++      memset(bp->rx_buffers, 0, size);
+       size = B44_TX_RING_SIZE * sizeof(struct ring_info);
+-      bp->tx_buffers = kzalloc(size, GFP_KERNEL);
++      bp->tx_buffers = kmalloc(size, GFP_KERNEL);
+       if (!bp->tx_buffers)
+               goto out_err;
++      memset(bp->tx_buffers, 0, size);
+       size = DMA_TABLE_BYTES;
+       bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
+-      if (!bp->rx_ring) {
+-              /* Allocation may have failed due to pci_alloc_consistent
+-                 insisting on use of GFP_DMA, which is more restrictive
+-                 than necessary...  */
+-              struct dma_desc *rx_ring;
+-              dma_addr_t rx_ring_dma;
+-
+-              rx_ring = kzalloc(size, GFP_KERNEL);
+-              if (!rx_ring)
+-                      goto out_err;
+-
+-              rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
+-                                           DMA_TABLE_BYTES,
+-                                           DMA_BIDIRECTIONAL);
+-
+-              if (rx_ring_dma + size > B44_DMA_MASK) {
+-                      kfree(rx_ring);
+-                      goto out_err;
+-              }
+-
+-              bp->rx_ring = rx_ring;
+-              bp->rx_ring_dma = rx_ring_dma;
+-              bp->flags |= B44_FLAG_RX_RING_HACK;
+-      }
++      if (!bp->rx_ring)
++              goto out_err;
+       bp->tx_ring = pci_alloc_consistent(bp->pdev, size, &bp->tx_ring_dma);
+-      if (!bp->tx_ring) {
+-              /* Allocation may have failed due to pci_alloc_consistent
+-                 insisting on use of GFP_DMA, which is more restrictive
+-                 than necessary...  */
+-              struct dma_desc *tx_ring;
+-              dma_addr_t tx_ring_dma;
+-
+-              tx_ring = kzalloc(size, GFP_KERNEL);
+-              if (!tx_ring)
+-                      goto out_err;
+-
+-              tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
+-                                           DMA_TABLE_BYTES,
+-                                           DMA_TO_DEVICE);
+-
+-              if (tx_ring_dma + size > B44_DMA_MASK) {
+-                      kfree(tx_ring);
+-                      goto out_err;
+-              }
+-
+-              bp->tx_ring = tx_ring;
+-              bp->tx_ring_dma = tx_ring_dma;
+-              bp->flags |= B44_FLAG_TX_RING_HACK;
+-      }
++      if (!bp->tx_ring)
++              goto out_err;
+       return 0;
+@@ -1394,21 +1273,19 @@
+       err = b44_alloc_consistent(bp);
+       if (err)
+-              goto out;
++              return err;
++
++      err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
++      if (err)
++              goto err_out_free;
++
++      spin_lock_irq(&bp->lock);
+       b44_init_rings(bp);
+       b44_init_hw(bp);
++      bp->flags |= B44_FLAG_INIT_COMPLETE;
+-      netif_carrier_off(dev);
+-      b44_check_phy(bp);
+-
+-      err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
+-      if (unlikely(err < 0)) {
+-              b44_chip_reset(bp);
+-              b44_free_rings(bp);
+-              b44_free_consistent(bp);
+-              goto out;
+-      }
++      spin_unlock_irq(&bp->lock);
+       init_timer(&bp->timer);
+       bp->timer.expires = jiffies + HZ;
+@@ -1417,8 +1294,11 @@
+       add_timer(&bp->timer);
+       b44_enable_ints(bp);
+-      netif_start_queue(dev);
+-out:
++
++      return 0;
++
++err_out_free:
++      b44_free_consistent(bp);
+       return err;
+ }
+@@ -1453,8 +1333,6 @@
+       netif_stop_queue(dev);
+-      netif_poll_disable(dev);
+-
+       del_timer_sync(&bp->timer);
+       spin_lock_irq(&bp->lock);
+@@ -1464,14 +1342,13 @@
+ #endif
+       b44_halt(bp);
+       b44_free_rings(bp);
++      bp->flags &= ~B44_FLAG_INIT_COMPLETE;
+       netif_carrier_off(bp->dev);
+       spin_unlock_irq(&bp->lock);
+       free_irq(dev->irq, dev);
+-      netif_poll_enable(dev);
+-
+       b44_free_consistent(bp);
+       return 0;
+@@ -1536,6 +1413,8 @@
+ {
+       struct b44 *bp = netdev_priv(dev);
+       u32 val;
++      int i=0;
++      unsigned char zero[6] = {0,0,0,0,0,0};
+       val = br32(bp, B44_RXCONFIG);
+       val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
+@@ -1543,17 +1422,14 @@
+               val |= RXCONFIG_PROMISC;
+               bw32(bp, B44_RXCONFIG, val);
+       } else {
+-              unsigned char zero[6] = {0, 0, 0, 0, 0, 0};
+-              int i = 0;
+-
+               __b44_set_mac_addr(bp);
+               if (dev->flags & IFF_ALLMULTI)
+                       val |= RXCONFIG_ALLMULTI;
+               else
+-                      i = __b44_load_mcast(bp, dev);
++                      i=__b44_load_mcast(bp, dev);
+               
+-              for (; i < 64; i++) {
++              for(;i<64;i++) {
+                       __b44_cam_write(bp, zero, i);                   
+               }
+               bw32(bp, B44_RXCONFIG, val);
+@@ -1617,7 +1493,7 @@
+ {
+       struct b44 *bp = netdev_priv(dev);
+-      if (!netif_running(dev))
++      if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
+               return -EAGAIN;
+       cmd->supported = (SUPPORTED_Autoneg);
+       cmd->supported |= (SUPPORTED_100baseT_Half |
+@@ -1628,14 +1504,14 @@
+       cmd->advertising = 0;
+       if (bp->flags & B44_FLAG_ADV_10HALF)
+-              cmd->advertising |= ADVERTISED_10baseT_Half;
++              cmd->advertising |= ADVERTISE_10HALF;
+       if (bp->flags & B44_FLAG_ADV_10FULL)
+-              cmd->advertising |= ADVERTISED_10baseT_Full;
++              cmd->advertising |= ADVERTISE_10FULL;
+       if (bp->flags & B44_FLAG_ADV_100HALF)
+-              cmd->advertising |= ADVERTISED_100baseT_Half;
++              cmd->advertising |= ADVERTISE_100HALF;
+       if (bp->flags & B44_FLAG_ADV_100FULL)
+-              cmd->advertising |= ADVERTISED_100baseT_Full;
+-      cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
++              cmd->advertising |= ADVERTISE_100FULL;
++      cmd->advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+       cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
+               SPEED_100 : SPEED_10;
+       cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
+@@ -1655,7 +1531,7 @@
+ {
+       struct b44 *bp = netdev_priv(dev);
+-      if (!netif_running(dev))
++      if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
+               return -EAGAIN;
+       /* We do not support gigabit. */
+@@ -1785,37 +1661,6 @@
+       return 0;
+ }
+-static void b44_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+-{
+-      switch(stringset) {
+-      case ETH_SS_STATS:
+-              memcpy(data, *b44_gstrings, sizeof(b44_gstrings));
+-              break;
+-      }
+-}
+-
+-static int b44_get_stats_count(struct net_device *dev)
+-{
+-      return ARRAY_SIZE(b44_gstrings);
+-}
+-
+-static void b44_get_ethtool_stats(struct net_device *dev,
+-                                struct ethtool_stats *stats, u64 *data)
+-{
+-      struct b44 *bp = netdev_priv(dev);
+-      u32 *val = &bp->hw_stats.tx_good_octets;
+-      u32 i;
+-
+-      spin_lock_irq(&bp->lock);
+-
+-      b44_stats_update(bp);
+-
+-      for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++)
+-              *data++ = *val++;
+-
+-      spin_unlock_irq(&bp->lock);
+-}
+-
+ static struct ethtool_ops b44_ethtool_ops = {
+       .get_drvinfo            = b44_get_drvinfo,
+       .get_settings           = b44_get_settings,
+@@ -1828,25 +1673,18 @@
+       .set_pauseparam         = b44_set_pauseparam,
+       .get_msglevel           = b44_get_msglevel,
+       .set_msglevel           = b44_set_msglevel,
+-      .get_strings            = b44_get_strings,
+-      .get_stats_count        = b44_get_stats_count,
+-      .get_ethtool_stats      = b44_get_ethtool_stats,
+-      .get_perm_addr          = ethtool_op_get_perm_addr,
+ };
+ static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ {
+       struct mii_ioctl_data *data = if_mii(ifr);
+       struct b44 *bp = netdev_priv(dev);
+-      int err = -EINVAL;
+-
+-      if (!netif_running(dev))
+-              goto out;
++      int err;
+       spin_lock_irq(&bp->lock);
+       err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL);
+       spin_unlock_irq(&bp->lock);
+-out:
++
+       return err;
+ }
+@@ -1877,7 +1715,6 @@
+       bp->dev->dev_addr[3] = eeprom[80];
+       bp->dev->dev_addr[4] = eeprom[83];
+       bp->dev->dev_addr[5] = eeprom[82];
+-      memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
+       bp->phy_addr = eeprom[90] & 0x1f;
+@@ -1942,9 +1779,9 @@
+       
+       err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
+       if (err) {
+-              printk(KERN_ERR PFX "No usable DMA configuration, "
+-                     "aborting.\n");
+-              goto err_out_free_res;
++        printk(KERN_ERR PFX "No usable DMA configuration, "
++               "aborting.\n");
++        goto err_out_free_res;
+       }
+       b44reg_base = pci_resource_start(pdev, 0);
+@@ -1966,8 +1803,10 @@
+       bp = netdev_priv(dev);
+       bp->pdev = pdev;
+       bp->dev = dev;
+-
+-      bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
++      if (b44_debug >= 0)
++              bp->msg_enable = (1 << b44_debug) - 1;
++      else
++              bp->msg_enable = B44_DEF_MSG_ENABLE;
+       spin_lock_init(&bp->lock);
+@@ -2057,14 +1896,17 @@
+ static void __devexit b44_remove_one(struct pci_dev *pdev)
+ {
+       struct net_device *dev = pci_get_drvdata(pdev);
+-      struct b44 *bp = netdev_priv(dev);
+-      unregister_netdev(dev);
+-      iounmap(bp->regs);
+-      free_netdev(dev);
+-      pci_release_regions(pdev);
+-      pci_disable_device(pdev);
+-      pci_set_drvdata(pdev, NULL);
++      if (dev) {
++              struct b44 *bp = netdev_priv(dev);
++
++              unregister_netdev(dev);
++              iounmap(bp->regs);
++              free_netdev(dev);
++              pci_release_regions(pdev);
++              pci_disable_device(pdev);
++              pci_set_drvdata(pdev, NULL);
++      }
+ }
+ static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
+@@ -2085,9 +1927,6 @@
+       b44_free_rings(bp);
+       spin_unlock_irq(&bp->lock);
+-
+-      free_irq(dev->irq, dev);
+-      pci_disable_device(pdev);
+       return 0;
+ }
+@@ -2097,15 +1936,10 @@
+       struct b44 *bp = netdev_priv(dev);
+       pci_restore_state(pdev);
+-      pci_enable_device(pdev);
+-      pci_set_master(pdev);
+       if (!netif_running(dev))
+               return 0;
+-      if (request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev))
+-              printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name);
+-
+       spin_lock_irq(&bp->lock);
+       b44_init_rings(bp);
+@@ -2117,7 +1951,6 @@
+       add_timer(&bp->timer);
+       b44_enable_ints(bp);
+-      netif_wake_queue(dev);
+       return 0;
+ }
+@@ -2132,12 +1965,6 @@
+ static int __init b44_init(void)
+ {
+-      unsigned int dma_desc_align_size = dma_get_cache_alignment();
+-
+-      /* Setup paramaters for syncing RX/TX DMA descriptors */
+-      dma_desc_align_mask = ~(dma_desc_align_size - 1);
+-      dma_desc_sync_size = max(dma_desc_align_size, sizeof(struct dma_desc));
+-
+       return pci_module_init(&b44_driver);
+ }
+diff -ur linux-2.6.15-rc5/drivers/net/b44.h linux-2.6.15-rc5-openwrt/drivers/net/b44.h
+--- linux-2.6.15-rc5/drivers/net/b44.h 2005-12-04 06:10:42.000000000 +0100
++++ linux-2.6.15-rc5-openwrt/drivers/net/b44.h 2005-08-15 02:20:18.000000000 +0200
+@@ -346,63 +346,29 @@
+ #define B44_MCAST_TABLE_SIZE  32
+-#define       B44_STAT_REG_DECLARE            \
+-      _B44(tx_good_octets)            \
+-      _B44(tx_good_pkts)              \
+-      _B44(tx_octets)                 \
+-      _B44(tx_pkts)                   \
+-      _B44(tx_broadcast_pkts)         \
+-      _B44(tx_multicast_pkts)         \
+-      _B44(tx_len_64)                 \
+-      _B44(tx_len_65_to_127)          \
+-      _B44(tx_len_128_to_255)         \
+-      _B44(tx_len_256_to_511)         \
+-      _B44(tx_len_512_to_1023)        \
+-      _B44(tx_len_1024_to_max)        \
+-      _B44(tx_jabber_pkts)            \
+-      _B44(tx_oversize_pkts)          \
+-      _B44(tx_fragment_pkts)          \
+-      _B44(tx_underruns)              \
+-      _B44(tx_total_cols)             \
+-      _B44(tx_single_cols)            \
+-      _B44(tx_multiple_cols)          \
+-      _B44(tx_excessive_cols)         \
+-      _B44(tx_late_cols)              \
+-      _B44(tx_defered)                \
+-      _B44(tx_carrier_lost)           \
+-      _B44(tx_pause_pkts)             \
+-      _B44(rx_good_octets)            \
+-      _B44(rx_good_pkts)              \
+-      _B44(rx_octets)                 \
+-      _B44(rx_pkts)                   \
+-      _B44(rx_broadcast_pkts)         \
+-      _B44(rx_multicast_pkts)         \
+-      _B44(rx_len_64)                 \
+-      _B44(rx_len_65_to_127)          \
+-      _B44(rx_len_128_to_255)         \
+-      _B44(rx_len_256_to_511)         \
+-      _B44(rx_len_512_to_1023)        \
+-      _B44(rx_len_1024_to_max)        \
+-      _B44(rx_jabber_pkts)            \
+-      _B44(rx_oversize_pkts)          \
+-      _B44(rx_fragment_pkts)          \
+-      _B44(rx_missed_pkts)            \
+-      _B44(rx_crc_align_errs)         \
+-      _B44(rx_undersize)              \
+-      _B44(rx_crc_errs)               \
+-      _B44(rx_align_errs)             \
+-      _B44(rx_symbol_errs)            \
+-      _B44(rx_pause_pkts)             \
+-      _B44(rx_nonpause_pkts)
+-
+ /* SW copy of device statistics, kept up to date by periodic timer
+- * which probes HW values. Check b44_stats_update if you mess with
+- * the layout
++ * which probes HW values.  Must have same relative layout as HW
++ * register above, because b44_stats_update depends upon this.
+  */
+ struct b44_hw_stats {
+-#define _B44(x)       u32 x;
+-B44_STAT_REG_DECLARE
+-#undef _B44
++      u32 tx_good_octets, tx_good_pkts, tx_octets;
++      u32 tx_pkts, tx_broadcast_pkts, tx_multicast_pkts;
++      u32 tx_len_64, tx_len_65_to_127, tx_len_128_to_255;
++      u32 tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max;
++      u32 tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts;
++      u32 tx_underruns, tx_total_cols, tx_single_cols;
++      u32 tx_multiple_cols, tx_excessive_cols, tx_late_cols;
++      u32 tx_defered, tx_carrier_lost, tx_pause_pkts;
++      u32 __pad1[8];
++
++      u32 rx_good_octets, rx_good_pkts, rx_octets;
++      u32 rx_pkts, rx_broadcast_pkts, rx_multicast_pkts;
++      u32 rx_len_64, rx_len_65_to_127, rx_len_128_to_255;
++      u32 rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max;
++      u32 rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts;
++      u32 rx_missed_pkts, rx_crc_align_errs, rx_undersize;
++      u32 rx_crc_errs, rx_align_errs, rx_symbol_errs;
++      u32 rx_pause_pkts, rx_nonpause_pkts;
+ };
+ struct b44 {
+@@ -420,6 +386,7 @@
+       u32                     dma_offset;
+       u32                     flags;
++#define B44_FLAG_INIT_COMPLETE        0x00000001
+ #define B44_FLAG_BUGGY_TXPTR  0x00000002
+ #define B44_FLAG_REORDER_BUG  0x00000004
+ #define B44_FLAG_PAUSE_AUTO   0x00008000
+@@ -433,8 +400,6 @@
+ #define B44_FLAG_ADV_100HALF  0x04000000
+ #define B44_FLAG_ADV_100FULL  0x08000000
+ #define B44_FLAG_INTERNAL_PHY 0x10000000
+-#define B44_FLAG_RX_RING_HACK 0x20000000
+-#define B44_FLAG_TX_RING_HACK 0x40000000
+       u32                     rx_offset;
diff --git a/openwrt/target/linux/linux-2.6/patches/generic/003-net-b44-2.patch b/openwrt/target/linux/linux-2.6/patches/generic/003-net-b44-2.patch
new file mode 100644 (file)
index 0000000..8bfe429
--- /dev/null
@@ -0,0 +1,1089 @@
+diff -ur linux-2.6.14.3/drivers/net/b44.c linux-2.6.14.3-openwrt/drivers/net/b44.c
+--- linux-2.6.14.3/drivers/net/b44.c   2005-11-24 23:10:21.000000000 +0100
++++ linux-2.6.14.3-openwrt/drivers/net/b44.c   2005-12-08 13:24:35.000000000 +0100
+@@ -1,7 +1,8 @@
+-/* b44.c: Broadcom 4400 device driver.
++/* b44.c: Broadcom 4400/47xx device driver.
+  *
+  * Copyright (C) 2002 David S. Miller (davem@redhat.com)
+- * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
++ * Copyright (C) 2004 Pekka Pietikainen (pp@ee.oulu.fi)
++ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
+  *
+  * Distribute under GPL.
+  */
+@@ -78,7 +79,7 @@
+       DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+ MODULE_AUTHOR("Florian Schirmer, Pekka Pietikainen, David S. Miller");
+-MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver");
++MODULE_DESCRIPTION("Broadcom 4400/47xx 10/100 PCI ethernet driver");
+ MODULE_LICENSE("GPL");
+ MODULE_VERSION(DRV_MODULE_VERSION);
+@@ -93,6 +94,8 @@
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
++      { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4713,
++        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { }     /* terminate list with empty entry */
+ };
+@@ -106,24 +109,13 @@
+ static void b44_poll_controller(struct net_device *dev);
+ #endif
+-static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
+-{
+-      return readl(bp->regs + reg);
+-}
+-
+-static inline void bw32(const struct b44 *bp, 
+-                      unsigned long reg, unsigned long val)
+-{
+-      writel(val, bp->regs + reg);
+-}
+-
+ static int b44_wait_bit(struct b44 *bp, unsigned long reg,
+                       u32 bit, unsigned long timeout, const int clear)
+ {
+       unsigned long i;
+       for (i = 0; i < timeout; i++) {
+-              u32 val = br32(bp, reg);
++              u32 val = br32(reg);
+               if (clear && !(val & bit))
+                       break;
+@@ -154,7 +146,7 @@
+ static u32 ssb_get_core_rev(struct b44 *bp)
+ {
+-      return (br32(bp, B44_SBIDHIGH) & SBIDHIGH_RC_MASK);
++      return (br32(B44_SBIDHIGH) & SBIDHIGH_RC_MASK);
+ }
+ static u32 ssb_pci_setup(struct b44 *bp, u32 cores)
+@@ -165,13 +157,13 @@
+       pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, BCM4400_PCI_CORE_ADDR);
+       pci_rev = ssb_get_core_rev(bp);
+-      val = br32(bp, B44_SBINTVEC);
++      val = br32(B44_SBINTVEC);
+       val |= cores;
+-      bw32(bp, B44_SBINTVEC, val);
++      bw32(B44_SBINTVEC, val);
+-      val = br32(bp, SSB_PCI_TRANS_2);
++      val = br32(SSB_PCI_TRANS_2);
+       val |= SSB_PCI_PREF | SSB_PCI_BURST;
+-      bw32(bp, SSB_PCI_TRANS_2, val);
++      bw32(SSB_PCI_TRANS_2, val);
+       pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, bar_orig);
+@@ -180,18 +172,18 @@
+ static void ssb_core_disable(struct b44 *bp)
+ {
+-      if (br32(bp, B44_SBTMSLOW) & SBTMSLOW_RESET)
++      if (br32(B44_SBTMSLOW) & SBTMSLOW_RESET)
+               return;
+-      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_CLOCK));
++      bw32(B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_CLOCK));
+       b44_wait_bit(bp, B44_SBTMSLOW, SBTMSLOW_REJECT, 100000, 0);
+       b44_wait_bit(bp, B44_SBTMSHIGH, SBTMSHIGH_BUSY, 100000, 1);
+-      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_FGC | SBTMSLOW_CLOCK |
++      bw32(B44_SBTMSLOW, (SBTMSLOW_FGC | SBTMSLOW_CLOCK |
+                           SBTMSLOW_REJECT | SBTMSLOW_RESET));
+-      br32(bp, B44_SBTMSLOW);
++      br32(B44_SBTMSLOW);
+       udelay(1);
+-      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_RESET));
+-      br32(bp, B44_SBTMSLOW);
++      bw32(B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_RESET));
++      br32(B44_SBTMSLOW);
+       udelay(1);
+ }
+@@ -200,58 +192,65 @@
+       u32 val;
+       ssb_core_disable(bp);
+-      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_RESET | SBTMSLOW_CLOCK | SBTMSLOW_FGC));
+-      br32(bp, B44_SBTMSLOW);
++      bw32(B44_SBTMSLOW, (SBTMSLOW_RESET | SBTMSLOW_CLOCK | SBTMSLOW_FGC));
++      br32(B44_SBTMSLOW);
+       udelay(1);
+       /* Clear SERR if set, this is a hw bug workaround.  */
+-      if (br32(bp, B44_SBTMSHIGH) & SBTMSHIGH_SERR)
+-              bw32(bp, B44_SBTMSHIGH, 0);
++      if (br32(B44_SBTMSHIGH) & SBTMSHIGH_SERR)
++              bw32(B44_SBTMSHIGH, 0);
+-      val = br32(bp, B44_SBIMSTATE);
++      val = br32(B44_SBIMSTATE);
+       if (val & (SBIMSTATE_IBE | SBIMSTATE_TO))
+-              bw32(bp, B44_SBIMSTATE, val & ~(SBIMSTATE_IBE | SBIMSTATE_TO));
++              bw32(B44_SBIMSTATE, val & ~(SBIMSTATE_IBE | SBIMSTATE_TO));
+-      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK | SBTMSLOW_FGC));
+-      br32(bp, B44_SBTMSLOW);
++      bw32(B44_SBTMSLOW, (SBTMSLOW_CLOCK | SBTMSLOW_FGC));
++      br32(B44_SBTMSLOW);
+       udelay(1);
+-      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK));
+-      br32(bp, B44_SBTMSLOW);
++      bw32(B44_SBTMSLOW, (SBTMSLOW_CLOCK));
++      br32(B44_SBTMSLOW);
+       udelay(1);
+ }
++static int b44_4713_instance;
++
+ static int ssb_core_unit(struct b44 *bp)
+ {
+-#if 0
+-      u32 val = br32(bp, B44_SBADMATCH0);
+-      u32 base;
+-
+-      type = val & SBADMATCH0_TYPE_MASK;
+-      switch (type) {
+-      case 0:
+-              base = val & SBADMATCH0_BS0_MASK;
+-              break;
+-
+-      case 1:
+-              base = val & SBADMATCH0_BS1_MASK;
+-              break;
+-
+-      case 2:
+-      default:
+-              base = val & SBADMATCH0_BS2_MASK;
+-              break;
+-      };
+-#endif
+-      return 0;
++      if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
++              return b44_4713_instance++;
++      else
++              return 0;
+ }
+ static int ssb_is_core_up(struct b44 *bp)
+ {
+-      return ((br32(bp, B44_SBTMSLOW) & (SBTMSLOW_RESET | SBTMSLOW_REJECT | SBTMSLOW_CLOCK))
++      return ((br32(B44_SBTMSLOW) & (SBTMSLOW_RESET | SBTMSLOW_REJECT | SBTMSLOW_CLOCK))
+               == SBTMSLOW_CLOCK);
+ }
++static void __b44_cam_read(struct b44 *bp, unsigned char *data, int index)
++{
++      u32 val;
++
++      bw32(B44_CAM_CTRL, (CAM_CTRL_READ |
++                          (index << CAM_CTRL_INDEX_SHIFT)));
++
++      b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);  
++
++      val = br32(B44_CAM_DATA_LO);
++
++      data[2] = (val >> 24) & 0xFF;
++      data[3] = (val >> 16) & 0xFF;
++      data[4] = (val >> 8) & 0xFF;
++      data[5] = (val >> 0) & 0xFF;
++
++      val = br32(B44_CAM_DATA_HI);
++      
++      data[0] = (val >> 8) & 0xFF;
++      data[1] = (val >> 0) & 0xFF;
++}
++
+ static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
+ {
+       u32 val;
+@@ -260,19 +259,19 @@
+       val |= ((u32) data[3]) << 16;
+       val |= ((u32) data[4]) <<  8;
+       val |= ((u32) data[5]) <<  0;
+-      bw32(bp, B44_CAM_DATA_LO, val);
++      bw32(B44_CAM_DATA_LO, val);
+       val = (CAM_DATA_HI_VALID | 
+              (((u32) data[0]) << 8) |
+              (((u32) data[1]) << 0));
+-      bw32(bp, B44_CAM_DATA_HI, val);
+-      bw32(bp, B44_CAM_CTRL, (CAM_CTRL_WRITE |
++      bw32(B44_CAM_DATA_HI, val);
++      bw32(B44_CAM_CTRL, (CAM_CTRL_WRITE |
+                           (index << CAM_CTRL_INDEX_SHIFT)));
+       b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);  
+ }
+ static inline void __b44_disable_ints(struct b44 *bp)
+ {
+-      bw32(bp, B44_IMASK, 0);
++      bw32(B44_IMASK, 0);
+ }
+ static void b44_disable_ints(struct b44 *bp)
+@@ -280,42 +279,59 @@
+       __b44_disable_ints(bp);
+       /* Flush posted writes. */
+-      br32(bp, B44_IMASK);
++      br32(B44_IMASK);
+ }
+ static void b44_enable_ints(struct b44 *bp)
+ {
+-      bw32(bp, B44_IMASK, bp->imask);
++      bw32(B44_IMASK, bp->imask);
+ }
+-static int b44_readphy(struct b44 *bp, int reg, u32 *val)
++static int __b44_readphy(struct b44 *bp, int phy_addr, int reg, u32 *val)
+ {
+       int err;
+-      bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII);
+-      bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START |
++      bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
++      bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
+                            (MDIO_OP_READ << MDIO_DATA_OP_SHIFT) |
+-                           (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
++                           (phy_addr << MDIO_DATA_PMD_SHIFT) |
+                            (reg << MDIO_DATA_RA_SHIFT) |
+                            (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT)));
+       err = b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
+-      *val = br32(bp, B44_MDIO_DATA) & MDIO_DATA_DATA;
++      *val = br32(B44_MDIO_DATA) & MDIO_DATA_DATA;
+       return err;
+ }
+-static int b44_writephy(struct b44 *bp, int reg, u32 val)
++static int b44_readphy(struct b44 *bp, int reg, u32 *val)
++{
++      if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
++              return 0;
++
++      return __b44_readphy(bp, bp->phy_addr, reg, val);
++}
++
++static int __b44_writephy(struct b44 *bp, int phy_addr, int reg, u32 val)
+ {
+-      bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII);
+-      bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START |
++      bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
++      bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
+                            (MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT) |
+-                           (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
++                           (phy_addr << MDIO_DATA_PMD_SHIFT) |
+                            (reg << MDIO_DATA_RA_SHIFT) |
+                            (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT) |
+                            (val & MDIO_DATA_DATA)));
+       return b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
+ }
++static int b44_writephy(struct b44 *bp, int reg, u32 val)
++{
++      if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
++              return 0;
++              
++      return __b44_writephy(bp, bp->phy_addr, reg, val);
++}
++
++
+ /* miilib interface */
+ /* FIXME FIXME: phy_id is ignored, bp->phy_addr use is unconditional
+  * due to code existing before miilib use was added to this driver.
+@@ -344,6 +360,9 @@
+       u32 val;
+       int err;
++      if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
++              return 0;
++
+       err = b44_writephy(bp, MII_BMCR, BMCR_RESET);
+       if (err)
+               return err;
+@@ -367,20 +386,20 @@
+       bp->flags &= ~(B44_FLAG_TX_PAUSE | B44_FLAG_RX_PAUSE);
+       bp->flags |= pause_flags;
+-      val = br32(bp, B44_RXCONFIG);
++      val = br32(B44_RXCONFIG);
+       if (pause_flags & B44_FLAG_RX_PAUSE)
+               val |= RXCONFIG_FLOW;
+       else
+               val &= ~RXCONFIG_FLOW;
+-      bw32(bp, B44_RXCONFIG, val);
++      bw32(B44_RXCONFIG, val);
+-      val = br32(bp, B44_MAC_FLOW);
++      val = br32(B44_MAC_FLOW);
+       if (pause_flags & B44_FLAG_TX_PAUSE)
+               val |= (MAC_FLOW_PAUSE_ENAB |
+                       (0xc0 & MAC_FLOW_RX_HI_WATER));
+       else
+               val &= ~MAC_FLOW_PAUSE_ENAB;
+-      bw32(bp, B44_MAC_FLOW, val);
++      bw32(B44_MAC_FLOW, val);
+ }
+ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
+@@ -414,6 +433,9 @@
+       u32 val;
+       int err;
++      if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
++              return 0;
++
+       if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0)
+               goto out;
+       if ((err = b44_writephy(bp, B44_MII_ALEDCTRL,
+@@ -476,11 +498,11 @@
+       val = &bp->hw_stats.tx_good_octets;
+       for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
+-              *val++ += br32(bp, reg);
++              *val++ += br32(reg);
+       }
+       val = &bp->hw_stats.rx_good_octets;
+       for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
+-              *val++ += br32(bp, reg);
++              *val++ += br32(reg);
+       }
+ }
+@@ -506,6 +528,19 @@
+ {
+       u32 bmsr, aux;
++      if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) {
++              bp->flags |= B44_FLAG_100_BASE_T;
++              bp->flags |= B44_FLAG_FULL_DUPLEX;
++              if (!netif_carrier_ok(bp->dev)) {
++                      u32 val = br32(B44_TX_CTRL);
++                      val |= TX_CTRL_DUPLEX;
++                      bw32(B44_TX_CTRL, val);
++                      netif_carrier_on(bp->dev);
++                      b44_link_report(bp);
++              }
++              return;
++      }
++
+       if (!b44_readphy(bp, MII_BMSR, &bmsr) &&
+           !b44_readphy(bp, B44_MII_AUXCTRL, &aux) &&
+           (bmsr != 0xffff)) {
+@@ -520,14 +555,14 @@
+               if (!netif_carrier_ok(bp->dev) &&
+                   (bmsr & BMSR_LSTATUS)) {
+-                      u32 val = br32(bp, B44_TX_CTRL);
++                      u32 val = br32(B44_TX_CTRL);
+                       u32 local_adv, remote_adv;
+                       if (bp->flags & B44_FLAG_FULL_DUPLEX)
+                               val |= TX_CTRL_DUPLEX;
+                       else
+                               val &= ~TX_CTRL_DUPLEX;
+-                      bw32(bp, B44_TX_CTRL, val);
++                      bw32(B44_TX_CTRL, val);
+                       if (!(bp->flags & B44_FLAG_FORCE_LINK) &&
+                           !b44_readphy(bp, MII_ADVERTISE, &local_adv) &&
+@@ -572,7 +607,7 @@
+ {
+       u32 cur, cons;
+-      cur  = br32(bp, B44_DMATX_STAT) & DMATX_STAT_CDMASK;
++      cur  = br32(B44_DMATX_STAT) & DMATX_STAT_CDMASK;
+       cur /= sizeof(struct dma_desc);
+       /* XXX needs updating when NETIF_F_SG is supported */
+@@ -596,7 +631,7 @@
+           TX_BUFFS_AVAIL(bp) > B44_TX_WAKEUP_THRESH)
+               netif_wake_queue(bp->dev);
+-      bw32(bp, B44_GPTIMER, 0);
++      bw32(B44_GPTIMER, 0);
+ }
+ /* Works like this.  This chip writes a 'struct rx_header" 30 bytes
+@@ -713,7 +748,7 @@
+       u32 cons, prod;
+       received = 0;
+-      prod  = br32(bp, B44_DMARX_STAT) & DMARX_STAT_CDMASK;
++      prod  = br32(B44_DMARX_STAT) & DMARX_STAT_CDMASK;
+       prod /= sizeof(struct dma_desc);
+       cons = bp->rx_cons;
+@@ -792,7 +827,7 @@
+       }
+       bp->rx_cons = cons;
+-      bw32(bp, B44_DMARX_PTR, cons * sizeof(struct dma_desc));
++      bw32(B44_DMARX_PTR, cons * sizeof(struct dma_desc));
+       return received;
+ }
+@@ -856,8 +891,8 @@
+       spin_lock_irqsave(&bp->lock, flags);
+-      istat = br32(bp, B44_ISTAT);
+-      imask = br32(bp, B44_IMASK);
++      istat = br32(B44_ISTAT);
++      imask = br32(B44_IMASK);
+       /* ??? What the fuck is the purpose of the interrupt mask
+        * ??? register if we have to mask it out by hand anyways?
+@@ -877,8 +912,8 @@
+                              dev->name);
+               }
+-              bw32(bp, B44_ISTAT, istat);
+-              br32(bp, B44_ISTAT);
++              bw32(B44_ISTAT, istat);
++              br32(B44_ISTAT);
+       }
+       spin_unlock_irqrestore(&bp->lock, flags);
+       return IRQ_RETVAL(handled);
+@@ -965,11 +1000,11 @@
+       wmb();
+-      bw32(bp, B44_DMATX_PTR, entry * sizeof(struct dma_desc));
++      bw32(B44_DMATX_PTR, entry * sizeof(struct dma_desc));
+       if (bp->flags & B44_FLAG_BUGGY_TXPTR)
+-              bw32(bp, B44_DMATX_PTR, entry * sizeof(struct dma_desc));
++              bw32(B44_DMATX_PTR, entry * sizeof(struct dma_desc));
+       if (bp->flags & B44_FLAG_REORDER_BUG)
+-              br32(bp, B44_DMATX_PTR);
++              br32(B44_DMATX_PTR);
+       if (TX_BUFFS_AVAIL(bp) < 1)
+               netif_stop_queue(dev);
+@@ -1137,32 +1172,35 @@
+ {
+       unsigned long reg;
+-      bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
++      bw32(B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
+       for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL)
+-              br32(bp, reg);
++              br32(reg);
+       for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL)
+-              br32(bp, reg);
++              br32(reg);
+ }
+ /* bp->lock is held. */
+ static void b44_chip_reset(struct b44 *bp)
+ {
++      unsigned int sb_clock;
++
+       if (ssb_is_core_up(bp)) {
+-              bw32(bp, B44_RCV_LAZY, 0);
+-              bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE);
++              bw32(B44_RCV_LAZY, 0);
++              bw32(B44_ENET_CTRL, ENET_CTRL_DISABLE);
+               b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 100, 1);
+-              bw32(bp, B44_DMATX_CTRL, 0);
++              bw32(B44_DMATX_CTRL, 0);
+               bp->tx_prod = bp->tx_cons = 0;
+-              if (br32(bp, B44_DMARX_STAT) & DMARX_STAT_EMASK) {
++              if (br32(B44_DMARX_STAT) & DMARX_STAT_EMASK) {
+                       b44_wait_bit(bp, B44_DMARX_STAT, DMARX_STAT_SIDLE,
+                                    100, 0);
+               }
+-              bw32(bp, B44_DMARX_CTRL, 0);
++              bw32(B44_DMARX_CTRL, 0);
+               bp->rx_prod = bp->rx_cons = 0;
+       } else {
+-              ssb_pci_setup(bp, (bp->core_unit == 0 ?
+-                                 SBINTVEC_ENET0 :
+-                                 SBINTVEC_ENET1));
++              if (bp->pdev->device != PCI_DEVICE_ID_BCM4713)
++                      ssb_pci_setup(bp, (bp->core_unit == 0 ?
++                                         SBINTVEC_ENET0 :
++                                         SBINTVEC_ENET1));
+       }
+       ssb_core_reset(bp);
+@@ -1170,20 +1208,26 @@
+       b44_clear_stats(bp);
+       /* Make PHY accessible. */
+-      bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
+-                           (0x0d & MDIO_CTRL_MAXF_MASK)));
+-      br32(bp, B44_MDIO_CTRL);
+-
+-      if (!(br32(bp, B44_DEVCTRL) & DEVCTRL_IPP)) {
+-              bw32(bp, B44_ENET_CTRL, ENET_CTRL_EPSEL);
+-              br32(bp, B44_ENET_CTRL);
++      if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
++              sb_clock = 100000000; /* 100 MHz */
++      else
++              sb_clock = 62500000; /* 62.5 MHz */
++
++      bw32(B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
++                           (((sb_clock + (B44_MDC_RATIO / 2)) / B44_MDC_RATIO)
++                           & MDIO_CTRL_MAXF_MASK)));
++      br32(B44_MDIO_CTRL);
++
++      if (!(br32(B44_DEVCTRL) & DEVCTRL_IPP)) {
++              bw32(B44_ENET_CTRL, ENET_CTRL_EPSEL);
++              br32(B44_ENET_CTRL);
+               bp->flags &= ~B44_FLAG_INTERNAL_PHY;
+       } else {
+-              u32 val = br32(bp, B44_DEVCTRL);
++              u32 val = br32(B44_DEVCTRL);
+               if (val & DEVCTRL_EPR) {
+-                      bw32(bp, B44_DEVCTRL, (val & ~DEVCTRL_EPR));
+-                      br32(bp, B44_DEVCTRL);
++                      bw32(B44_DEVCTRL, (val & ~DEVCTRL_EPR));
++                      br32(B44_DEVCTRL);
+                       udelay(100);
+               }
+               bp->flags |= B44_FLAG_INTERNAL_PHY;
+@@ -1200,13 +1244,13 @@
+ /* bp->lock is held. */
+ static void __b44_set_mac_addr(struct b44 *bp)
+ {
+-      bw32(bp, B44_CAM_CTRL, 0);
++      bw32(B44_CAM_CTRL, 0);
+       if (!(bp->dev->flags & IFF_PROMISC)) {
+               u32 val;
+               __b44_cam_write(bp, bp->dev->dev_addr, 0);
+-              val = br32(bp, B44_CAM_CTRL);
+-              bw32(bp, B44_CAM_CTRL, val | CAM_CTRL_ENABLE);
++              val = br32(B44_CAM_CTRL);
++              bw32(B44_CAM_CTRL, val | CAM_CTRL_ENABLE);
+       }
+ }
+@@ -1240,30 +1284,30 @@
+       b44_setup_phy(bp);
+       /* Enable CRC32, set proper LED modes and power on PHY */
+-      bw32(bp, B44_MAC_CTRL, MAC_CTRL_CRC32_ENAB | MAC_CTRL_PHY_LEDCTRL);
+-      bw32(bp, B44_RCV_LAZY, (1 << RCV_LAZY_FC_SHIFT));
++      bw32(B44_MAC_CTRL, MAC_CTRL_CRC32_ENAB | MAC_CTRL_PHY_LEDCTRL);
++      bw32(B44_RCV_LAZY, (1 << RCV_LAZY_FC_SHIFT));
+       /* This sets the MAC address too.  */
+       __b44_set_rx_mode(bp->dev);
+       /* MTU + eth header + possible VLAN tag + struct rx_header */
+-      bw32(bp, B44_RXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
+-      bw32(bp, B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
++      bw32(B44_RXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
++      bw32(B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
+-      bw32(bp, B44_TX_WMARK, 56); /* XXX magic */
+-      bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE);
+-      bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset);
+-      bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
++      bw32(B44_TX_WMARK, 56); /* XXX magic */
++      bw32(B44_DMATX_CTRL, DMATX_CTRL_ENABLE);
++      bw32(B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset);
++      bw32(B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
+                             (bp->rx_offset << DMARX_CTRL_ROSHIFT)));
+-      bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
++      bw32(B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
+-      bw32(bp, B44_DMARX_PTR, bp->rx_pending);
++      bw32(B44_DMARX_PTR, bp->rx_pending);
+       bp->rx_prod = bp->rx_pending;   
+-      bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
++      bw32(B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
+-      val = br32(bp, B44_ENET_CTRL);
+-      bw32(bp, B44_ENET_CTRL, (val | ENET_CTRL_ENABLE));
++      val = br32(B44_ENET_CTRL);
++      bw32(B44_ENET_CTRL, (val | ENET_CTRL_ENABLE));
+ }
+ static int b44_open(struct net_device *dev)
+@@ -1419,11 +1463,11 @@
+       int i=0;
+       unsigned char zero[6] = {0,0,0,0,0,0};
+-      val = br32(bp, B44_RXCONFIG);
++      val = br32(B44_RXCONFIG);
+       val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
+       if (dev->flags & IFF_PROMISC) {
+               val |= RXCONFIG_PROMISC;
+-              bw32(bp, B44_RXCONFIG, val);
++              bw32(B44_RXCONFIG, val);
+       } else {
+               __b44_set_mac_addr(bp);
+@@ -1435,9 +1479,9 @@
+               for(;i<64;i++) {
+                       __b44_cam_write(bp, zero, i);                   
+               }
+-              bw32(bp, B44_RXCONFIG, val);
+-              val = br32(bp, B44_CAM_CTRL);
+-              bw32(bp, B44_CAM_CTRL, val | CAM_CTRL_ENABLE);
++              bw32(B44_RXCONFIG, val);
++              val = br32(B44_CAM_CTRL);
++              bw32(B44_CAM_CTRL, val | CAM_CTRL_ENABLE);
+       }
+ }
+@@ -1678,17 +1722,288 @@
+       .set_msglevel           = b44_set_msglevel,
+ };
++static int b44_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
++{
++      struct b44 *bp = dev->priv;
++      struct pci_dev *pci_dev = bp->pdev;
++      u32 ethcmd;
++
++      if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
++              return -EFAULT;
++
++      switch (ethcmd) {
++      case ETHTOOL_GDRVINFO: {
++              struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
++              strcpy (info.driver, DRV_MODULE_NAME);
++              strcpy (info.version, DRV_MODULE_VERSION);
++              memset(&info.fw_version, 0, sizeof(info.fw_version));
++              strcpy (info.bus_info, pci_name(pci_dev));
++              info.eedump_len = 0;
++              info.regdump_len = 0;
++              if (copy_to_user (useraddr, &info, sizeof (info)))
++                      return -EFAULT;
++              return 0;
++      }
++
++      case ETHTOOL_GSET: {
++              struct ethtool_cmd cmd = { ETHTOOL_GSET };
++
++              if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
++                      return -EAGAIN;
++              cmd.supported = (SUPPORTED_Autoneg);
++              cmd.supported |= (SUPPORTED_100baseT_Half |
++                                SUPPORTED_100baseT_Full |
++                                SUPPORTED_10baseT_Half |
++                                SUPPORTED_10baseT_Full |
++                                SUPPORTED_MII);
++
++              cmd.advertising = 0;
++              if (bp->flags & B44_FLAG_ADV_10HALF)
++                      cmd.advertising |= ADVERTISE_10HALF;
++              if (bp->flags & B44_FLAG_ADV_10FULL)
++                      cmd.advertising |= ADVERTISE_10FULL;
++              if (bp->flags & B44_FLAG_ADV_100HALF)
++                      cmd.advertising |= ADVERTISE_100HALF;
++              if (bp->flags & B44_FLAG_ADV_100FULL)
++                      cmd.advertising |= ADVERTISE_100FULL;
++              cmd.advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
++              cmd.speed = (bp->flags & B44_FLAG_100_BASE_T) ?
++                      SPEED_100 : SPEED_10;
++              cmd.duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
++                      DUPLEX_FULL : DUPLEX_HALF;
++              cmd.port = 0;
++              cmd.phy_address = bp->phy_addr;
++              cmd.transceiver = (bp->flags & B44_FLAG_INTERNAL_PHY) ?
++                      XCVR_INTERNAL : XCVR_EXTERNAL;
++              cmd.autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
++                      AUTONEG_DISABLE : AUTONEG_ENABLE;
++              cmd.maxtxpkt = 0;
++              cmd.maxrxpkt = 0;
++              if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
++                      return -EFAULT;
++              return 0;
++      }
++      case ETHTOOL_SSET: {
++              struct ethtool_cmd cmd;
++
++              if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
++                      return -EAGAIN;
++
++              if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
++                      return -EFAULT;
++
++              /* We do not support gigabit. */
++              if (cmd.autoneg == AUTONEG_ENABLE) {
++                      if (cmd.advertising &
++                          (ADVERTISED_1000baseT_Half |
++                           ADVERTISED_1000baseT_Full))
++                              return -EINVAL;
++              } else if ((cmd.speed != SPEED_100 &&
++                          cmd.speed != SPEED_10) ||
++                         (cmd.duplex != DUPLEX_HALF &&
++                          cmd.duplex != DUPLEX_FULL)) {
++                              return -EINVAL;
++              }
++
++              spin_lock_irq(&bp->lock);
++
++              if (cmd.autoneg == AUTONEG_ENABLE) {
++                      bp->flags &= ~B44_FLAG_FORCE_LINK;
++                      bp->flags &= ~(B44_FLAG_ADV_10HALF |
++                                     B44_FLAG_ADV_10FULL |
++                                     B44_FLAG_ADV_100HALF |
++                                     B44_FLAG_ADV_100FULL);
++                      if (cmd.advertising & ADVERTISE_10HALF)
++                              bp->flags |= B44_FLAG_ADV_10HALF;
++                      if (cmd.advertising & ADVERTISE_10FULL)
++                              bp->flags |= B44_FLAG_ADV_10FULL;
++                      if (cmd.advertising & ADVERTISE_100HALF)
++                              bp->flags |= B44_FLAG_ADV_100HALF;
++                      if (cmd.advertising & ADVERTISE_100FULL)
++                              bp->flags |= B44_FLAG_ADV_100FULL;
++              } else {
++                      bp->flags |= B44_FLAG_FORCE_LINK;
++                      if (cmd.speed == SPEED_100)
++                              bp->flags |= B44_FLAG_100_BASE_T;
++                      if (cmd.duplex == DUPLEX_FULL)
++                              bp->flags |= B44_FLAG_FULL_DUPLEX;
++              }
++
++              b44_setup_phy(bp);
++
++              spin_unlock_irq(&bp->lock);
++
++              return 0;
++      }
++
++      case ETHTOOL_GMSGLVL: {
++              struct ethtool_value edata = { ETHTOOL_GMSGLVL };
++              edata.data = bp->msg_enable;
++              if (copy_to_user(useraddr, &edata, sizeof(edata)))
++                      return -EFAULT;
++              return 0;
++      }
++      case ETHTOOL_SMSGLVL: {
++              struct ethtool_value edata;
++              if (copy_from_user(&edata, useraddr, sizeof(edata)))
++                      return -EFAULT;
++              bp->msg_enable = edata.data;
++              return 0;
++      }
++      case ETHTOOL_NWAY_RST: {
++              u32 bmcr;
++              int r;
++
++              spin_lock_irq(&bp->lock);
++              b44_readphy(bp, MII_BMCR, &bmcr);
++              b44_readphy(bp, MII_BMCR, &bmcr);
++              r = -EINVAL;
++              if (bmcr & BMCR_ANENABLE) {
++                      b44_writephy(bp, MII_BMCR,
++                                   bmcr | BMCR_ANRESTART);
++                      r = 0;
++              }
++              spin_unlock_irq(&bp->lock);
++
++              return r;
++      }
++      case ETHTOOL_GLINK: {
++              struct ethtool_value edata = { ETHTOOL_GLINK };
++              edata.data = netif_carrier_ok(bp->dev) ? 1 : 0;
++              if (copy_to_user(useraddr, &edata, sizeof(edata)))
++                      return -EFAULT;
++              return 0;
++      }
++      case ETHTOOL_GRINGPARAM: {
++              struct ethtool_ringparam ering = { ETHTOOL_GRINGPARAM };
++
++              ering.rx_max_pending = B44_RX_RING_SIZE - 1;
++              ering.rx_pending = bp->rx_pending;
++
++              /* XXX ethtool lacks a tx_max_pending, oops... */
++
++              if (copy_to_user(useraddr, &ering, sizeof(ering)))
++                      return -EFAULT;
++              return 0;
++      }
++      case ETHTOOL_SRINGPARAM: {
++              struct ethtool_ringparam ering;
++
++              if (copy_from_user(&ering, useraddr, sizeof(ering)))
++                      return -EFAULT;
++
++              if ((ering.rx_pending > B44_RX_RING_SIZE - 1) ||
++                  (ering.rx_mini_pending != 0) ||
++                  (ering.rx_jumbo_pending != 0) ||
++                  (ering.tx_pending > B44_TX_RING_SIZE - 1))
++                      return -EINVAL;
++
++              spin_lock_irq(&bp->lock);
++
++              bp->rx_pending = ering.rx_pending;
++              bp->tx_pending = ering.tx_pending;
++
++              b44_halt(bp);
++              b44_init_rings(bp);
++              b44_init_hw(bp);
++              netif_wake_queue(bp->dev);
++              spin_unlock_irq(&bp->lock);
++
++              b44_enable_ints(bp);
++              
++              return 0;
++      }
++      case ETHTOOL_GPAUSEPARAM: {
++              struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM };
++
++              epause.autoneg =
++                      (bp->flags & B44_FLAG_PAUSE_AUTO) != 0;
++              epause.rx_pause =
++                      (bp->flags & B44_FLAG_RX_PAUSE) != 0;
++              epause.tx_pause =
++                      (bp->flags & B44_FLAG_TX_PAUSE) != 0;
++              if (copy_to_user(useraddr, &epause, sizeof(epause)))
++                      return -EFAULT;
++              return 0;
++      }
++      case ETHTOOL_SPAUSEPARAM: {
++              struct ethtool_pauseparam epause;
++
++              if (copy_from_user(&epause, useraddr, sizeof(epause)))
++                      return -EFAULT;
++
++              spin_lock_irq(&bp->lock);
++              if (epause.autoneg)
++                      bp->flags |= B44_FLAG_PAUSE_AUTO;
++              else
++                      bp->flags &= ~B44_FLAG_PAUSE_AUTO;
++              if (epause.rx_pause)
++                      bp->flags |= B44_FLAG_RX_PAUSE;
++              else
++                      bp->flags &= ~B44_FLAG_RX_PAUSE;
++              if (epause.tx_pause)
++                      bp->flags |= B44_FLAG_TX_PAUSE;
++              else
++                      bp->flags &= ~B44_FLAG_TX_PAUSE;
++              if (bp->flags & B44_FLAG_PAUSE_AUTO) {
++                      b44_halt(bp);
++                      b44_init_rings(bp);
++                      b44_init_hw(bp);
++              } else {
++                      __b44_set_flow_ctrl(bp, bp->flags);
++              }
++              spin_unlock_irq(&bp->lock);
++
++              b44_enable_ints(bp);
++              
++              return 0;
++      }
++      };
++
++      return -EOPNOTSUPP;
++}
++
+ static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ {
+       struct mii_ioctl_data *data = if_mii(ifr);
+       struct b44 *bp = netdev_priv(dev);
+       int err;
+-      spin_lock_irq(&bp->lock);
+-      err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL);
+-      spin_unlock_irq(&bp->lock);
++      switch (cmd) {
++      case SIOCETHTOOL:
++              return b44_ethtool_ioctl(dev, (void __user*) ifr->ifr_data);
++
++      case SIOCGMIIPHY:
++              data->phy_id = bp->phy_addr;
++
++              /* fallthru */
++      case SIOCGMIIREG: {
++              u32 mii_regval;
+-      return err;
++              spin_lock_irq(&bp->lock);
++              err = __b44_readphy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, &mii_regval);
++              spin_unlock_irq(&bp->lock);
++
++              data->val_out = mii_regval;
++
++              return err;
++      }
++
++      case SIOCSMIIREG:
++              if (!capable(CAP_NET_ADMIN))
++                      return -EPERM;
++
++              spin_lock_irq(&bp->lock);
++              err = __b44_writephy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
++              spin_unlock_irq(&bp->lock);
++
++              return err;
++
++      default:
++              /* do nothing */
++              break;
++      };
++      return -EOPNOTSUPP;
+ }
+ /* Read 128-bytes of EEPROM. */
+@@ -1698,7 +2013,7 @@
+       u16 *ptr = (u16 *) data;
+       for (i = 0; i < 128; i += 2)
+-              ptr[i / 2] = readw(bp->regs + 4096 + i);
++              ptr[i / 2] = readw((void *)bp->regs + 4096 + i);
+       return 0;
+ }
+@@ -1707,19 +2022,41 @@
+ {
+       u8 eeprom[128];
+       int err;
++      unsigned long flags;
+-      err = b44_read_eeprom(bp, &eeprom[0]);
+-      if (err)
+-              goto out;
+-
+-      bp->dev->dev_addr[0] = eeprom[79];
+-      bp->dev->dev_addr[1] = eeprom[78];
+-      bp->dev->dev_addr[2] = eeprom[81];
+-      bp->dev->dev_addr[3] = eeprom[80];
+-      bp->dev->dev_addr[4] = eeprom[83];
+-      bp->dev->dev_addr[5] = eeprom[82];
+-
+-      bp->phy_addr = eeprom[90] & 0x1f;
++      if (bp->pdev->device == PCI_DEVICE_ID_BCM4713) {
++              /* 
++               * BCM47xx boards don't have a EEPROM. The MAC is stored in
++               * a NVRAM area somewhere in the flash memory. As we don't
++               * know the location and/or the format of the NVRAM area
++               * here, we simply rely on the bootloader to write the
++               * MAC into the CAM.
++               */
++              spin_lock_irqsave(&bp->lock, flags);
++              __b44_cam_read(bp, bp->dev->dev_addr, 0);
++              spin_unlock_irqrestore(&bp->lock, flags);
++
++              /* 
++               * BCM47xx boards don't have a PHY. Usually there is a switch
++               * chip with multiple PHYs connected to the PHY port.
++               */
++              bp->phy_addr = B44_PHY_ADDR_NO_PHY;
++              bp->dma_offset = 0;
++      } else {
++              err = b44_read_eeprom(bp, &eeprom[0]);
++              if (err)
++                      return err;
++
++              bp->dev->dev_addr[0] = eeprom[79];
++              bp->dev->dev_addr[1] = eeprom[78];
++              bp->dev->dev_addr[2] = eeprom[81];
++              bp->dev->dev_addr[3] = eeprom[80];
++              bp->dev->dev_addr[4] = eeprom[83];
++              bp->dev->dev_addr[5] = eeprom[82];
++
++              bp->phy_addr = eeprom[90] & 0x1f;
++              bp->dma_offset = SB_PCI_DMA;
++      } 
+       /* With this, plus the rx_header prepended to the data by the
+        * hardware, we'll land the ethernet header on a 2-byte boundary.
+@@ -1729,13 +2066,12 @@
+       bp->imask = IMASK_DEF;
+       bp->core_unit = ssb_core_unit(bp);
+-      bp->dma_offset = SB_PCI_DMA;
+       /* XXX - really required? 
+          bp->flags |= B44_FLAG_BUGGY_TXPTR;
+          */
+-out:
+-      return err;
++
++      return 0;
+ }
+ static int __devinit b44_init_one(struct pci_dev *pdev,
+@@ -1813,7 +2149,7 @@
+       spin_lock_init(&bp->lock);
+-      bp->regs = ioremap(b44reg_base, b44reg_len);
++      bp->regs = (unsigned long) ioremap(b44reg_base, b44reg_len);
+       if (bp->regs == 0UL) {
+               printk(KERN_ERR PFX "Cannot map device registers, "
+                      "aborting.\n");
+@@ -1874,15 +2210,21 @@
+       pci_save_state(bp->pdev);
+-      printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
++      printk(KERN_INFO "%s: Broadcom %s 10/100BaseT Ethernet ", dev->name,
++              (pdev->device == PCI_DEVICE_ID_BCM4713) ? "47xx" : "4400");
+       for (i = 0; i < 6; i++)
+               printk("%2.2x%c", dev->dev_addr[i],
+                      i == 5 ? '\n' : ':');
++      /* Initialize phy */
++      spin_lock_irq(&bp->lock);
++      b44_chip_reset(bp);
++      spin_unlock_irq(&bp->lock);
++      
+       return 0;
+ err_out_iounmap:
+-      iounmap(bp->regs);
++      iounmap((void *) bp->regs);
+ err_out_free_dev:
+       free_netdev(dev);
+@@ -1904,7 +2246,7 @@
+               struct b44 *bp = netdev_priv(dev);
+               unregister_netdev(dev);
+-              iounmap(bp->regs);
++              iounmap((void *) bp->regs);
+               free_netdev(dev);
+               pci_release_regions(pdev);
+               pci_disable_device(pdev);
+diff -ur linux-2.6.14.3/drivers/net/b44.h linux-2.6.14.3-openwrt/drivers/net/b44.h
+--- linux-2.6.14.3/drivers/net/b44.h   2005-11-24 23:10:21.000000000 +0100
++++ linux-2.6.14.3-openwrt/drivers/net/b44.h   2005-12-08 13:24:35.000000000 +0100
+@@ -292,6 +292,9 @@
+ #define SSB_PCI_MASK1         0xfc000000
+ #define SSB_PCI_MASK2         0xc0000000
++#define br32(REG)     readl((void *)bp->regs + (REG))
++#define bw32(REG,VAL) writel((VAL), (void *)bp->regs + (REG))
++
+ /* 4400 PHY registers */
+ #define B44_MII_AUXCTRL               24      /* Auxiliary Control */
+ #define  MII_AUXCTRL_DUPLEX   0x0001  /* Full Duplex */
+@@ -345,6 +348,8 @@
+ };
+ #define B44_MCAST_TABLE_SIZE  32
++#define B44_PHY_ADDR_NO_PHY   30
++#define B44_MDC_RATIO         5000000
+ /* SW copy of device statistics, kept up to date by periodic timer
+  * which probes HW values.  Must have same relative layout as HW
+@@ -410,7 +415,7 @@
+       struct net_device_stats stats;
+       struct b44_hw_stats     hw_stats;
+-      void __iomem            *regs;
++      unsigned long           regs;
+       struct pci_dev          *pdev;
+       struct net_device       *dev;
diff --git a/openwrt/target/linux/linux-2.6/patches/generic/003-net-b44.patch b/openwrt/target/linux/linux-2.6/patches/generic/003-net-b44.patch
deleted file mode 100644 (file)
index 17f82b6..0000000
+++ /dev/null
@@ -1,1089 +0,0 @@
-diff -Nur linux-2.6.12.5/drivers/net/b44.c linux-2.6.12.5-b44/drivers/net/b44.c
---- linux-2.6.12.5/drivers/net/b44.c   2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-b44/drivers/net/b44.c       2005-09-16 22:19:33.841633800 +0200
-@@ -1,7 +1,8 @@
--/* b44.c: Broadcom 4400 device driver.
-+/* b44.c: Broadcom 4400/47xx device driver.
-  *
-  * Copyright (C) 2002 David S. Miller (davem@redhat.com)
-- * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
-+ * Copyright (C) 2004 Pekka Pietikainen (pp@ee.oulu.fi)
-+ * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
-  *
-  * Distribute under GPL.
-  */
-@@ -78,7 +79,7 @@
-       DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
- MODULE_AUTHOR("Florian Schirmer, Pekka Pietikainen, David S. Miller");
--MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver");
-+MODULE_DESCRIPTION("Broadcom 4400/47xx 10/100 PCI ethernet driver");
- MODULE_LICENSE("GPL");
- MODULE_VERSION(DRV_MODULE_VERSION);
-@@ -93,6 +94,8 @@
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
-       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
-+      { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4713,
-+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
-       { }     /* terminate list with empty entry */
- };
-@@ -106,24 +109,13 @@
- static void b44_poll_controller(struct net_device *dev);
- #endif
--static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
--{
--      return readl(bp->regs + reg);
--}
--
--static inline void bw32(const struct b44 *bp, 
--                      unsigned long reg, unsigned long val)
--{
--      writel(val, bp->regs + reg);
--}
--
- static int b44_wait_bit(struct b44 *bp, unsigned long reg,
-                       u32 bit, unsigned long timeout, const int clear)
- {
-       unsigned long i;
-       for (i = 0; i < timeout; i++) {
--              u32 val = br32(bp, reg);
-+              u32 val = br32(reg);
-               if (clear && !(val & bit))
-                       break;
-@@ -154,7 +146,7 @@
- static u32 ssb_get_core_rev(struct b44 *bp)
- {
--      return (br32(bp, B44_SBIDHIGH) & SBIDHIGH_RC_MASK);
-+      return (br32(B44_SBIDHIGH) & SBIDHIGH_RC_MASK);
- }
- static u32 ssb_pci_setup(struct b44 *bp, u32 cores)
-@@ -165,13 +157,13 @@
-       pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, BCM4400_PCI_CORE_ADDR);
-       pci_rev = ssb_get_core_rev(bp);
--      val = br32(bp, B44_SBINTVEC);
-+      val = br32(B44_SBINTVEC);
-       val |= cores;
--      bw32(bp, B44_SBINTVEC, val);
-+      bw32(B44_SBINTVEC, val);
--      val = br32(bp, SSB_PCI_TRANS_2);
-+      val = br32(SSB_PCI_TRANS_2);
-       val |= SSB_PCI_PREF | SSB_PCI_BURST;
--      bw32(bp, SSB_PCI_TRANS_2, val);
-+      bw32(SSB_PCI_TRANS_2, val);
-       pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, bar_orig);
-@@ -180,18 +172,18 @@
- static void ssb_core_disable(struct b44 *bp)
- {
--      if (br32(bp, B44_SBTMSLOW) & SBTMSLOW_RESET)
-+      if (br32(B44_SBTMSLOW) & SBTMSLOW_RESET)
-               return;
--      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_CLOCK));
-+      bw32(B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_CLOCK));
-       b44_wait_bit(bp, B44_SBTMSLOW, SBTMSLOW_REJECT, 100000, 0);
-       b44_wait_bit(bp, B44_SBTMSHIGH, SBTMSHIGH_BUSY, 100000, 1);
--      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_FGC | SBTMSLOW_CLOCK |
-+      bw32(B44_SBTMSLOW, (SBTMSLOW_FGC | SBTMSLOW_CLOCK |
-                           SBTMSLOW_REJECT | SBTMSLOW_RESET));
--      br32(bp, B44_SBTMSLOW);
-+      br32(B44_SBTMSLOW);
-       udelay(1);
--      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_RESET));
--      br32(bp, B44_SBTMSLOW);
-+      bw32(B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_RESET));
-+      br32(B44_SBTMSLOW);
-       udelay(1);
- }
-@@ -200,58 +192,65 @@
-       u32 val;
-       ssb_core_disable(bp);
--      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_RESET | SBTMSLOW_CLOCK | SBTMSLOW_FGC));
--      br32(bp, B44_SBTMSLOW);
-+      bw32(B44_SBTMSLOW, (SBTMSLOW_RESET | SBTMSLOW_CLOCK | SBTMSLOW_FGC));
-+      br32(B44_SBTMSLOW);
-       udelay(1);
-       /* Clear SERR if set, this is a hw bug workaround.  */
--      if (br32(bp, B44_SBTMSHIGH) & SBTMSHIGH_SERR)
--              bw32(bp, B44_SBTMSHIGH, 0);
-+      if (br32(B44_SBTMSHIGH) & SBTMSHIGH_SERR)
-+              bw32(B44_SBTMSHIGH, 0);
--      val = br32(bp, B44_SBIMSTATE);
-+      val = br32(B44_SBIMSTATE);
-       if (val & (SBIMSTATE_IBE | SBIMSTATE_TO))
--              bw32(bp, B44_SBIMSTATE, val & ~(SBIMSTATE_IBE | SBIMSTATE_TO));
-+              bw32(B44_SBIMSTATE, val & ~(SBIMSTATE_IBE | SBIMSTATE_TO));
--      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK | SBTMSLOW_FGC));
--      br32(bp, B44_SBTMSLOW);
-+      bw32(B44_SBTMSLOW, (SBTMSLOW_CLOCK | SBTMSLOW_FGC));
-+      br32(B44_SBTMSLOW);
-       udelay(1);
--      bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK));
--      br32(bp, B44_SBTMSLOW);
-+      bw32(B44_SBTMSLOW, (SBTMSLOW_CLOCK));
-+      br32(B44_SBTMSLOW);
-       udelay(1);
- }
-+static int b44_4713_instance;
-+
- static int ssb_core_unit(struct b44 *bp)
- {
--#if 0
--      u32 val = br32(bp, B44_SBADMATCH0);
--      u32 base;
--
--      type = val & SBADMATCH0_TYPE_MASK;
--      switch (type) {
--      case 0:
--              base = val & SBADMATCH0_BS0_MASK;
--              break;
--
--      case 1:
--              base = val & SBADMATCH0_BS1_MASK;
--              break;
--
--      case 2:
--      default:
--              base = val & SBADMATCH0_BS2_MASK;
--              break;
--      };
--#endif
--      return 0;
-+      if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
-+              return b44_4713_instance++;
-+      else
-+              return 0;
- }
- static int ssb_is_core_up(struct b44 *bp)
- {
--      return ((br32(bp, B44_SBTMSLOW) & (SBTMSLOW_RESET | SBTMSLOW_REJECT | SBTMSLOW_CLOCK))
-+      return ((br32(B44_SBTMSLOW) & (SBTMSLOW_RESET | SBTMSLOW_REJECT | SBTMSLOW_CLOCK))
-               == SBTMSLOW_CLOCK);
- }
-+static void __b44_cam_read(struct b44 *bp, unsigned char *data, int index)
-+{
-+      u32 val;
-+
-+      bw32(B44_CAM_CTRL, (CAM_CTRL_READ |
-+                          (index << CAM_CTRL_INDEX_SHIFT)));
-+
-+      b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);  
-+
-+      val = br32(B44_CAM_DATA_LO);
-+
-+      data[2] = (val >> 24) & 0xFF;
-+      data[3] = (val >> 16) & 0xFF;
-+      data[4] = (val >> 8) & 0xFF;
-+      data[5] = (val >> 0) & 0xFF;
-+
-+      val = br32(B44_CAM_DATA_HI);
-+      
-+      data[0] = (val >> 8) & 0xFF;
-+      data[1] = (val >> 0) & 0xFF;
-+}
-+
- static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
- {
-       u32 val;
-@@ -260,19 +259,19 @@
-       val |= ((u32) data[3]) << 16;
-       val |= ((u32) data[4]) <<  8;
-       val |= ((u32) data[5]) <<  0;
--      bw32(bp, B44_CAM_DATA_LO, val);
-+      bw32(B44_CAM_DATA_LO, val);
-       val = (CAM_DATA_HI_VALID | 
-              (((u32) data[0]) << 8) |
-              (((u32) data[1]) << 0));
--      bw32(bp, B44_CAM_DATA_HI, val);
--      bw32(bp, B44_CAM_CTRL, (CAM_CTRL_WRITE |
-+      bw32(B44_CAM_DATA_HI, val);
-+      bw32(B44_CAM_CTRL, (CAM_CTRL_WRITE |
-                           (index << CAM_CTRL_INDEX_SHIFT)));
-       b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);  
- }
- static inline void __b44_disable_ints(struct b44 *bp)
- {
--      bw32(bp, B44_IMASK, 0);
-+      bw32(B44_IMASK, 0);
- }
- static void b44_disable_ints(struct b44 *bp)
-@@ -280,42 +279,59 @@
-       __b44_disable_ints(bp);
-       /* Flush posted writes. */
--      br32(bp, B44_IMASK);
-+      br32(B44_IMASK);
- }
- static void b44_enable_ints(struct b44 *bp)
- {
--      bw32(bp, B44_IMASK, bp->imask);
-+      bw32(B44_IMASK, bp->imask);
- }
--static int b44_readphy(struct b44 *bp, int reg, u32 *val)
-+static int __b44_readphy(struct b44 *bp, int phy_addr, int reg, u32 *val)
- {
-       int err;
--      bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII);
--      bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START |
-+      bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
-+      bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
-                            (MDIO_OP_READ << MDIO_DATA_OP_SHIFT) |
--                           (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
-+                           (phy_addr << MDIO_DATA_PMD_SHIFT) |
-                            (reg << MDIO_DATA_RA_SHIFT) |
-                            (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT)));
-       err = b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
--      *val = br32(bp, B44_MDIO_DATA) & MDIO_DATA_DATA;
-+      *val = br32(B44_MDIO_DATA) & MDIO_DATA_DATA;
-       return err;
- }
--static int b44_writephy(struct b44 *bp, int reg, u32 val)
-+static int b44_readphy(struct b44 *bp, int reg, u32 *val)
-+{
-+      if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
-+              return 0;
-+
-+      return __b44_readphy(bp, bp->phy_addr, reg, val);
-+}
-+
-+static int __b44_writephy(struct b44 *bp, int phy_addr, int reg, u32 val)
- {
--      bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII);
--      bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START |
-+      bw32(B44_EMAC_ISTAT, EMAC_INT_MII);
-+      bw32(B44_MDIO_DATA, (MDIO_DATA_SB_START |
-                            (MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT) |
--                           (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
-+                           (phy_addr << MDIO_DATA_PMD_SHIFT) |
-                            (reg << MDIO_DATA_RA_SHIFT) |
-                            (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT) |
-                            (val & MDIO_DATA_DATA)));
-       return b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
- }
-+static int b44_writephy(struct b44 *bp, int reg, u32 val)
-+{
-+      if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
-+              return 0;
-+              
-+      return __b44_writephy(bp, bp->phy_addr, reg, val);
-+}
-+
-+
- /* miilib interface */
- /* FIXME FIXME: phy_id is ignored, bp->phy_addr use is unconditional
-  * due to code existing before miilib use was added to this driver.
-@@ -344,6 +360,9 @@
-       u32 val;
-       int err;
-+      if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
-+              return 0;
-+
-       err = b44_writephy(bp, MII_BMCR, BMCR_RESET);
-       if (err)
-               return err;
-@@ -367,20 +386,20 @@
-       bp->flags &= ~(B44_FLAG_TX_PAUSE | B44_FLAG_RX_PAUSE);
-       bp->flags |= pause_flags;
--      val = br32(bp, B44_RXCONFIG);
-+      val = br32(B44_RXCONFIG);
-       if (pause_flags & B44_FLAG_RX_PAUSE)
-               val |= RXCONFIG_FLOW;
-       else
-               val &= ~RXCONFIG_FLOW;
--      bw32(bp, B44_RXCONFIG, val);
-+      bw32(B44_RXCONFIG, val);
--      val = br32(bp, B44_MAC_FLOW);
-+      val = br32(B44_MAC_FLOW);
-       if (pause_flags & B44_FLAG_TX_PAUSE)
-               val |= (MAC_FLOW_PAUSE_ENAB |
-                       (0xc0 & MAC_FLOW_RX_HI_WATER));
-       else
-               val &= ~MAC_FLOW_PAUSE_ENAB;
--      bw32(bp, B44_MAC_FLOW, val);
-+      bw32(B44_MAC_FLOW, val);
- }
- static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
-@@ -414,6 +433,9 @@
-       u32 val;
-       int err;
-+      if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
-+              return 0;
-+
-       if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0)
-               goto out;
-       if ((err = b44_writephy(bp, B44_MII_ALEDCTRL,
-@@ -476,11 +498,11 @@
-       val = &bp->hw_stats.tx_good_octets;
-       for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
--              *val++ += br32(bp, reg);
-+              *val++ += br32(reg);
-       }
-       val = &bp->hw_stats.rx_good_octets;
-       for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
--              *val++ += br32(bp, reg);
-+              *val++ += br32(reg);
-       }
- }
-@@ -506,6 +528,19 @@
- {
-       u32 bmsr, aux;
-+      if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) {
-+              bp->flags |= B44_FLAG_100_BASE_T;
-+              bp->flags |= B44_FLAG_FULL_DUPLEX;
-+              if (!netif_carrier_ok(bp->dev)) {
-+                      u32 val = br32(B44_TX_CTRL);
-+                      val |= TX_CTRL_DUPLEX;
-+                      bw32(B44_TX_CTRL, val);
-+                      netif_carrier_on(bp->dev);
-+                      b44_link_report(bp);
-+              }
-+              return;
-+      }
-+
-       if (!b44_readphy(bp, MII_BMSR, &bmsr) &&
-           !b44_readphy(bp, B44_MII_AUXCTRL, &aux) &&
-           (bmsr != 0xffff)) {
-@@ -520,14 +555,14 @@
-               if (!netif_carrier_ok(bp->dev) &&
-                   (bmsr & BMSR_LSTATUS)) {
--                      u32 val = br32(bp, B44_TX_CTRL);
-+                      u32 val = br32(B44_TX_CTRL);
-                       u32 local_adv, remote_adv;
-                       if (bp->flags & B44_FLAG_FULL_DUPLEX)
-                               val |= TX_CTRL_DUPLEX;
-                       else
-                               val &= ~TX_CTRL_DUPLEX;
--                      bw32(bp, B44_TX_CTRL, val);
-+                      bw32(B44_TX_CTRL, val);
-                       if (!(bp->flags & B44_FLAG_FORCE_LINK) &&
-                           !b44_readphy(bp, MII_ADVERTISE, &local_adv) &&
-@@ -572,7 +607,7 @@
- {
-       u32 cur, cons;
--      cur  = br32(bp, B44_DMATX_STAT) & DMATX_STAT_CDMASK;
-+      cur  = br32(B44_DMATX_STAT) & DMATX_STAT_CDMASK;
-       cur /= sizeof(struct dma_desc);
-       /* XXX needs updating when NETIF_F_SG is supported */
-@@ -596,7 +631,7 @@
-           TX_BUFFS_AVAIL(bp) > B44_TX_WAKEUP_THRESH)
-               netif_wake_queue(bp->dev);
--      bw32(bp, B44_GPTIMER, 0);
-+      bw32(B44_GPTIMER, 0);
- }
- /* Works like this.  This chip writes a 'struct rx_header" 30 bytes
-@@ -713,7 +748,7 @@
-       u32 cons, prod;
-       received = 0;
--      prod  = br32(bp, B44_DMARX_STAT) & DMARX_STAT_CDMASK;
-+      prod  = br32(B44_DMARX_STAT) & DMARX_STAT_CDMASK;
-       prod /= sizeof(struct dma_desc);
-       cons = bp->rx_cons;
-@@ -792,7 +827,7 @@
-       }
-       bp->rx_cons = cons;
--      bw32(bp, B44_DMARX_PTR, cons * sizeof(struct dma_desc));
-+      bw32(B44_DMARX_PTR, cons * sizeof(struct dma_desc));
-       return received;
- }
-@@ -856,8 +891,8 @@
-       spin_lock_irqsave(&bp->lock, flags);
--      istat = br32(bp, B44_ISTAT);
--      imask = br32(bp, B44_IMASK);
-+      istat = br32(B44_ISTAT);
-+      imask = br32(B44_IMASK);
-       /* ??? What the fuck is the purpose of the interrupt mask
-        * ??? register if we have to mask it out by hand anyways?
-@@ -877,8 +912,8 @@
-                              dev->name);
-               }
--              bw32(bp, B44_ISTAT, istat);
--              br32(bp, B44_ISTAT);
-+              bw32(B44_ISTAT, istat);
-+              br32(B44_ISTAT);
-       }
-       spin_unlock_irqrestore(&bp->lock, flags);
-       return IRQ_RETVAL(handled);
-@@ -965,11 +1000,11 @@
-       wmb();
--      bw32(bp, B44_DMATX_PTR, entry * sizeof(struct dma_desc));
-+      bw32(B44_DMATX_PTR, entry * sizeof(struct dma_desc));
-       if (bp->flags & B44_FLAG_BUGGY_TXPTR)
--              bw32(bp, B44_DMATX_PTR, entry * sizeof(struct dma_desc));
-+              bw32(B44_DMATX_PTR, entry * sizeof(struct dma_desc));
-       if (bp->flags & B44_FLAG_REORDER_BUG)
--              br32(bp, B44_DMATX_PTR);
-+              br32(B44_DMATX_PTR);
-       if (TX_BUFFS_AVAIL(bp) < 1)
-               netif_stop_queue(dev);
-@@ -1137,32 +1172,35 @@
- {
-       unsigned long reg;
--      bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
-+      bw32(B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
-       for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL)
--              br32(bp, reg);
-+              br32(reg);
-       for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL)
--              br32(bp, reg);
-+              br32(reg);
- }
- /* bp->lock is held. */
- static void b44_chip_reset(struct b44 *bp)
- {
-+      unsigned int sb_clock;
-+
-       if (ssb_is_core_up(bp)) {
--              bw32(bp, B44_RCV_LAZY, 0);
--              bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE);
-+              bw32(B44_RCV_LAZY, 0);
-+              bw32(B44_ENET_CTRL, ENET_CTRL_DISABLE);
-               b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 100, 1);
--              bw32(bp, B44_DMATX_CTRL, 0);
-+              bw32(B44_DMATX_CTRL, 0);
-               bp->tx_prod = bp->tx_cons = 0;
--              if (br32(bp, B44_DMARX_STAT) & DMARX_STAT_EMASK) {
-+              if (br32(B44_DMARX_STAT) & DMARX_STAT_EMASK) {
-                       b44_wait_bit(bp, B44_DMARX_STAT, DMARX_STAT_SIDLE,
-                                    100, 0);
-               }
--              bw32(bp, B44_DMARX_CTRL, 0);
-+              bw32(B44_DMARX_CTRL, 0);
-               bp->rx_prod = bp->rx_cons = 0;
-       } else {
--              ssb_pci_setup(bp, (bp->core_unit == 0 ?
--                                 SBINTVEC_ENET0 :
--                                 SBINTVEC_ENET1));
-+              if (bp->pdev->device != PCI_DEVICE_ID_BCM4713)
-+                      ssb_pci_setup(bp, (bp->core_unit == 0 ?
-+                                         SBINTVEC_ENET0 :
-+                                         SBINTVEC_ENET1));
-       }
-       ssb_core_reset(bp);
-@@ -1170,20 +1208,26 @@
-       b44_clear_stats(bp);
-       /* Make PHY accessible. */
--      bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
--                           (0x0d & MDIO_CTRL_MAXF_MASK)));
--      br32(bp, B44_MDIO_CTRL);
--
--      if (!(br32(bp, B44_DEVCTRL) & DEVCTRL_IPP)) {
--              bw32(bp, B44_ENET_CTRL, ENET_CTRL_EPSEL);
--              br32(bp, B44_ENET_CTRL);
-+      if (bp->pdev->device == PCI_DEVICE_ID_BCM4713)
-+              sb_clock = 100000000; /* 100 MHz */
-+      else
-+              sb_clock = 62500000; /* 62.5 MHz */
-+
-+      bw32(B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
-+                           (((sb_clock + (B44_MDC_RATIO / 2)) / B44_MDC_RATIO)
-+                           & MDIO_CTRL_MAXF_MASK)));
-+      br32(B44_MDIO_CTRL);
-+
-+      if (!(br32(B44_DEVCTRL) & DEVCTRL_IPP)) {
-+              bw32(B44_ENET_CTRL, ENET_CTRL_EPSEL);
-+              br32(B44_ENET_CTRL);
-               bp->flags &= ~B44_FLAG_INTERNAL_PHY;
-       } else {
--              u32 val = br32(bp, B44_DEVCTRL);
-+              u32 val = br32(B44_DEVCTRL);
-               if (val & DEVCTRL_EPR) {
--                      bw32(bp, B44_DEVCTRL, (val & ~DEVCTRL_EPR));
--                      br32(bp, B44_DEVCTRL);
-+                      bw32(B44_DEVCTRL, (val & ~DEVCTRL_EPR));
-+                      br32(B44_DEVCTRL);
-                       udelay(100);
-               }
-               bp->flags |= B44_FLAG_INTERNAL_PHY;
-@@ -1200,13 +1244,13 @@
- /* bp->lock is held. */
- static void __b44_set_mac_addr(struct b44 *bp)
- {
--      bw32(bp, B44_CAM_CTRL, 0);
-+      bw32(B44_CAM_CTRL, 0);
-       if (!(bp->dev->flags & IFF_PROMISC)) {
-               u32 val;
-               __b44_cam_write(bp, bp->dev->dev_addr, 0);
--              val = br32(bp, B44_CAM_CTRL);
--              bw32(bp, B44_CAM_CTRL, val | CAM_CTRL_ENABLE);
-+              val = br32(B44_CAM_CTRL);
-+              bw32(B44_CAM_CTRL, val | CAM_CTRL_ENABLE);
-       }
- }
-@@ -1240,30 +1284,30 @@
-       b44_setup_phy(bp);
-       /* Enable CRC32, set proper LED modes and power on PHY */
--      bw32(bp, B44_MAC_CTRL, MAC_CTRL_CRC32_ENAB | MAC_CTRL_PHY_LEDCTRL);
--      bw32(bp, B44_RCV_LAZY, (1 << RCV_LAZY_FC_SHIFT));
-+      bw32(B44_MAC_CTRL, MAC_CTRL_CRC32_ENAB | MAC_CTRL_PHY_LEDCTRL);
-+      bw32(B44_RCV_LAZY, (1 << RCV_LAZY_FC_SHIFT));
-       /* This sets the MAC address too.  */
-       __b44_set_rx_mode(bp->dev);
-       /* MTU + eth header + possible VLAN tag + struct rx_header */
--      bw32(bp, B44_RXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
--      bw32(bp, B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
-+      bw32(B44_RXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
-+      bw32(B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
--      bw32(bp, B44_TX_WMARK, 56); /* XXX magic */
--      bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE);
--      bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset);
--      bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
-+      bw32(B44_TX_WMARK, 56); /* XXX magic */
-+      bw32(B44_DMATX_CTRL, DMATX_CTRL_ENABLE);
-+      bw32(B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset);
-+      bw32(B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
-                             (bp->rx_offset << DMARX_CTRL_ROSHIFT)));
--      bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
-+      bw32(B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
--      bw32(bp, B44_DMARX_PTR, bp->rx_pending);
-+      bw32(B44_DMARX_PTR, bp->rx_pending);
-       bp->rx_prod = bp->rx_pending;   
--      bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
-+      bw32(B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
--      val = br32(bp, B44_ENET_CTRL);
--      bw32(bp, B44_ENET_CTRL, (val | ENET_CTRL_ENABLE));
-+      val = br32(B44_ENET_CTRL);
-+      bw32(B44_ENET_CTRL, (val | ENET_CTRL_ENABLE));
- }
- static int b44_open(struct net_device *dev)
-@@ -1416,11 +1460,11 @@
-       int i=0;
-       unsigned char zero[6] = {0,0,0,0,0,0};
--      val = br32(bp, B44_RXCONFIG);
-+      val = br32(B44_RXCONFIG);
-       val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
-       if (dev->flags & IFF_PROMISC) {
-               val |= RXCONFIG_PROMISC;
--              bw32(bp, B44_RXCONFIG, val);
-+              bw32(B44_RXCONFIG, val);
-       } else {
-               __b44_set_mac_addr(bp);
-@@ -1432,9 +1476,9 @@
-               for(;i<64;i++) {
-                       __b44_cam_write(bp, zero, i);                   
-               }
--              bw32(bp, B44_RXCONFIG, val);
--              val = br32(bp, B44_CAM_CTRL);
--              bw32(bp, B44_CAM_CTRL, val | CAM_CTRL_ENABLE);
-+              bw32(B44_RXCONFIG, val);
-+              val = br32(B44_CAM_CTRL);
-+              bw32(B44_CAM_CTRL, val | CAM_CTRL_ENABLE);
-       }
- }
-@@ -1675,17 +1719,288 @@
-       .set_msglevel           = b44_set_msglevel,
- };
-+static int b44_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
-+{
-+      struct b44 *bp = dev->priv;
-+      struct pci_dev *pci_dev = bp->pdev;
-+      u32 ethcmd;
-+
-+      if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
-+              return -EFAULT;
-+
-+      switch (ethcmd) {
-+      case ETHTOOL_GDRVINFO: {
-+              struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
-+              strcpy (info.driver, DRV_MODULE_NAME);
-+              strcpy (info.version, DRV_MODULE_VERSION);
-+              memset(&info.fw_version, 0, sizeof(info.fw_version));
-+              strcpy (info.bus_info, pci_name(pci_dev));
-+              info.eedump_len = 0;
-+              info.regdump_len = 0;
-+              if (copy_to_user (useraddr, &info, sizeof (info)))
-+                      return -EFAULT;
-+              return 0;
-+      }
-+
-+      case ETHTOOL_GSET: {
-+              struct ethtool_cmd cmd = { ETHTOOL_GSET };
-+
-+              if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
-+                      return -EAGAIN;
-+              cmd.supported = (SUPPORTED_Autoneg);
-+              cmd.supported |= (SUPPORTED_100baseT_Half |
-+                                SUPPORTED_100baseT_Full |
-+                                SUPPORTED_10baseT_Half |
-+                                SUPPORTED_10baseT_Full |
-+                                SUPPORTED_MII);
-+
-+              cmd.advertising = 0;
-+              if (bp->flags & B44_FLAG_ADV_10HALF)
-+                      cmd.advertising |= ADVERTISE_10HALF;
-+              if (bp->flags & B44_FLAG_ADV_10FULL)
-+                      cmd.advertising |= ADVERTISE_10FULL;
-+              if (bp->flags & B44_FLAG_ADV_100HALF)
-+                      cmd.advertising |= ADVERTISE_100HALF;
-+              if (bp->flags & B44_FLAG_ADV_100FULL)
-+                      cmd.advertising |= ADVERTISE_100FULL;
-+              cmd.advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
-+              cmd.speed = (bp->flags & B44_FLAG_100_BASE_T) ?
-+                      SPEED_100 : SPEED_10;
-+              cmd.duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
-+                      DUPLEX_FULL : DUPLEX_HALF;
-+              cmd.port = 0;
-+              cmd.phy_address = bp->phy_addr;
-+              cmd.transceiver = (bp->flags & B44_FLAG_INTERNAL_PHY) ?
-+                      XCVR_INTERNAL : XCVR_EXTERNAL;
-+              cmd.autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
-+                      AUTONEG_DISABLE : AUTONEG_ENABLE;
-+              cmd.maxtxpkt = 0;
-+              cmd.maxrxpkt = 0;
-+              if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
-+                      return -EFAULT;
-+              return 0;
-+      }
-+      case ETHTOOL_SSET: {
-+              struct ethtool_cmd cmd;
-+
-+              if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
-+                      return -EAGAIN;
-+
-+              if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
-+                      return -EFAULT;
-+
-+              /* We do not support gigabit. */
-+              if (cmd.autoneg == AUTONEG_ENABLE) {
-+                      if (cmd.advertising &
-+                          (ADVERTISED_1000baseT_Half |
-+                           ADVERTISED_1000baseT_Full))
-+                              return -EINVAL;
-+              } else if ((cmd.speed != SPEED_100 &&
-+                          cmd.speed != SPEED_10) ||
-+                         (cmd.duplex != DUPLEX_HALF &&
-+                          cmd.duplex != DUPLEX_FULL)) {
-+                              return -EINVAL;
-+              }
-+
-+              spin_lock_irq(&bp->lock);
-+
-+              if (cmd.autoneg == AUTONEG_ENABLE) {
-+                      bp->flags &= ~B44_FLAG_FORCE_LINK;
-+                      bp->flags &= ~(B44_FLAG_ADV_10HALF |
-+                                     B44_FLAG_ADV_10FULL |
-+                                     B44_FLAG_ADV_100HALF |
-+                                     B44_FLAG_ADV_100FULL);
-+                      if (cmd.advertising & ADVERTISE_10HALF)
-+                              bp->flags |= B44_FLAG_ADV_10HALF;
-+                      if (cmd.advertising & ADVERTISE_10FULL)
-+                              bp->flags |= B44_FLAG_ADV_10FULL;
-+                      if (cmd.advertising & ADVERTISE_100HALF)
-+                              bp->flags |= B44_FLAG_ADV_100HALF;
-+                      if (cmd.advertising & ADVERTISE_100FULL)
-+                              bp->flags |= B44_FLAG_ADV_100FULL;
-+              } else {
-+                      bp->flags |= B44_FLAG_FORCE_LINK;
-+                      if (cmd.speed == SPEED_100)
-+                              bp->flags |= B44_FLAG_100_BASE_T;
-+                      if (cmd.duplex == DUPLEX_FULL)
-+                              bp->flags |= B44_FLAG_FULL_DUPLEX;
-+              }
-+
-+              b44_setup_phy(bp);
-+
-+              spin_unlock_irq(&bp->lock);
-+
-+              return 0;
-+      }
-+
-+      case ETHTOOL_GMSGLVL: {
-+              struct ethtool_value edata = { ETHTOOL_GMSGLVL };
-+              edata.data = bp->msg_enable;
-+              if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+                      return -EFAULT;
-+              return 0;
-+      }
-+      case ETHTOOL_SMSGLVL: {
-+              struct ethtool_value edata;
-+              if (copy_from_user(&edata, useraddr, sizeof(edata)))
-+                      return -EFAULT;
-+              bp->msg_enable = edata.data;
-+              return 0;
-+      }
-+      case ETHTOOL_NWAY_RST: {
-+              u32 bmcr;
-+              int r;
-+
-+              spin_lock_irq(&bp->lock);
-+              b44_readphy(bp, MII_BMCR, &bmcr);
-+              b44_readphy(bp, MII_BMCR, &bmcr);
-+              r = -EINVAL;
-+              if (bmcr & BMCR_ANENABLE) {
-+                      b44_writephy(bp, MII_BMCR,
-+                                   bmcr | BMCR_ANRESTART);
-+                      r = 0;
-+              }
-+              spin_unlock_irq(&bp->lock);
-+
-+              return r;
-+      }
-+      case ETHTOOL_GLINK: {
-+              struct ethtool_value edata = { ETHTOOL_GLINK };
-+              edata.data = netif_carrier_ok(bp->dev) ? 1 : 0;
-+              if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+                      return -EFAULT;
-+              return 0;
-+      }
-+      case ETHTOOL_GRINGPARAM: {
-+              struct ethtool_ringparam ering = { ETHTOOL_GRINGPARAM };
-+
-+              ering.rx_max_pending = B44_RX_RING_SIZE - 1;
-+              ering.rx_pending = bp->rx_pending;
-+
-+              /* XXX ethtool lacks a tx_max_pending, oops... */
-+
-+              if (copy_to_user(useraddr, &ering, sizeof(ering)))
-+                      return -EFAULT;
-+              return 0;
-+      }
-+      case ETHTOOL_SRINGPARAM: {
-+              struct ethtool_ringparam ering;
-+
-+              if (copy_from_user(&ering, useraddr, sizeof(ering)))
-+                      return -EFAULT;
-+
-+              if ((ering.rx_pending > B44_RX_RING_SIZE - 1) ||
-+                  (ering.rx_mini_pending != 0) ||
-+                  (ering.rx_jumbo_pending != 0) ||
-+                  (ering.tx_pending > B44_TX_RING_SIZE - 1))
-+                      return -EINVAL;
-+
-+              spin_lock_irq(&bp->lock);
-+
-+              bp->rx_pending = ering.rx_pending;
-+              bp->tx_pending = ering.tx_pending;
-+
-+              b44_halt(bp);
-+              b44_init_rings(bp);
-+              b44_init_hw(bp);
-+              netif_wake_queue(bp->dev);
-+              spin_unlock_irq(&bp->lock);
-+
-+              b44_enable_ints(bp);
-+              
-+              return 0;
-+      }
-+      case ETHTOOL_GPAUSEPARAM: {
-+              struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM };
-+
-+              epause.autoneg =
-+                      (bp->flags & B44_FLAG_PAUSE_AUTO) != 0;
-+              epause.rx_pause =
-+                      (bp->flags & B44_FLAG_RX_PAUSE) != 0;
-+              epause.tx_pause =
-+                      (bp->flags & B44_FLAG_TX_PAUSE) != 0;
-+              if (copy_to_user(useraddr, &epause, sizeof(epause)))
-+                      return -EFAULT;
-+              return 0;
-+      }
-+      case ETHTOOL_SPAUSEPARAM: {
-+              struct ethtool_pauseparam epause;
-+
-+              if (copy_from_user(&epause, useraddr, sizeof(epause)))
-+                      return -EFAULT;
-+
-+              spin_lock_irq(&bp->lock);
-+              if (epause.autoneg)
-+                      bp->flags |= B44_FLAG_PAUSE_AUTO;
-+              else
-+                      bp->flags &= ~B44_FLAG_PAUSE_AUTO;
-+              if (epause.rx_pause)
-+                      bp->flags |= B44_FLAG_RX_PAUSE;
-+              else
-+                      bp->flags &= ~B44_FLAG_RX_PAUSE;
-+              if (epause.tx_pause)
-+                      bp->flags |= B44_FLAG_TX_PAUSE;
-+              else
-+                      bp->flags &= ~B44_FLAG_TX_PAUSE;
-+              if (bp->flags & B44_FLAG_PAUSE_AUTO) {
-+                      b44_halt(bp);
-+                      b44_init_rings(bp);
-+                      b44_init_hw(bp);
-+              } else {
-+                      __b44_set_flow_ctrl(bp, bp->flags);
-+              }
-+              spin_unlock_irq(&bp->lock);
-+
-+              b44_enable_ints(bp);
-+              
-+              return 0;
-+      }
-+      };
-+
-+      return -EOPNOTSUPP;
-+}
-+
- static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
- {
-       struct mii_ioctl_data *data = if_mii(ifr);
-       struct b44 *bp = netdev_priv(dev);
-       int err;
--      spin_lock_irq(&bp->lock);
--      err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL);
--      spin_unlock_irq(&bp->lock);
-+      switch (cmd) {
-+      case SIOCETHTOOL:
-+              return b44_ethtool_ioctl(dev, (void __user*) ifr->ifr_data);
-+
-+      case SIOCGMIIPHY:
-+              data->phy_id = bp->phy_addr;
-+
-+              /* fallthru */
-+      case SIOCGMIIREG: {
-+              u32 mii_regval;
--      return err;
-+              spin_lock_irq(&bp->lock);
-+              err = __b44_readphy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, &mii_regval);
-+              spin_unlock_irq(&bp->lock);
-+
-+              data->val_out = mii_regval;
-+
-+              return err;
-+      }
-+
-+      case SIOCSMIIREG:
-+              if (!capable(CAP_NET_ADMIN))
-+                      return -EPERM;
-+
-+              spin_lock_irq(&bp->lock);
-+              err = __b44_writephy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
-+              spin_unlock_irq(&bp->lock);
-+
-+              return err;
-+
-+      default:
-+              /* do nothing */
-+              break;
-+      };
-+      return -EOPNOTSUPP;
- }
- /* Read 128-bytes of EEPROM. */
-@@ -1695,7 +2010,7 @@
-       u16 *ptr = (u16 *) data;
-       for (i = 0; i < 128; i += 2)
--              ptr[i / 2] = readw(bp->regs + 4096 + i);
-+              ptr[i / 2] = readw((void *)bp->regs + 4096 + i);
-       return 0;
- }
-@@ -1704,19 +2019,41 @@
- {
-       u8 eeprom[128];
-       int err;
-+      unsigned long flags;
--      err = b44_read_eeprom(bp, &eeprom[0]);
--      if (err)
--              goto out;
--
--      bp->dev->dev_addr[0] = eeprom[79];
--      bp->dev->dev_addr[1] = eeprom[78];
--      bp->dev->dev_addr[2] = eeprom[81];
--      bp->dev->dev_addr[3] = eeprom[80];
--      bp->dev->dev_addr[4] = eeprom[83];
--      bp->dev->dev_addr[5] = eeprom[82];
--
--      bp->phy_addr = eeprom[90] & 0x1f;
-+      if (bp->pdev->device == PCI_DEVICE_ID_BCM4713) {
-+              /* 
-+               * BCM47xx boards don't have a EEPROM. The MAC is stored in
-+               * a NVRAM area somewhere in the flash memory. As we don't
-+               * know the location and/or the format of the NVRAM area
-+               * here, we simply rely on the bootloader to write the
-+               * MAC into the CAM.
-+               */
-+              spin_lock_irqsave(&bp->lock, flags);
-+              __b44_cam_read(bp, bp->dev->dev_addr, 0);
-+              spin_unlock_irqrestore(&bp->lock, flags);
-+
-+              /* 
-+               * BCM47xx boards don't have a PHY. Usually there is a switch
-+               * chip with multiple PHYs connected to the PHY port.
-+               */
-+              bp->phy_addr = B44_PHY_ADDR_NO_PHY;
-+              bp->dma_offset = 0;
-+      } else {
-+              err = b44_read_eeprom(bp, &eeprom[0]);
-+              if (err)
-+                      return err;
-+
-+              bp->dev->dev_addr[0] = eeprom[79];
-+              bp->dev->dev_addr[1] = eeprom[78];
-+              bp->dev->dev_addr[2] = eeprom[81];
-+              bp->dev->dev_addr[3] = eeprom[80];
-+              bp->dev->dev_addr[4] = eeprom[83];
-+              bp->dev->dev_addr[5] = eeprom[82];
-+
-+              bp->phy_addr = eeprom[90] & 0x1f;
-+              bp->dma_offset = SB_PCI_DMA;
-+      } 
-       /* With this, plus the rx_header prepended to the data by the
-        * hardware, we'll land the ethernet header on a 2-byte boundary.
-@@ -1726,13 +2063,12 @@
-       bp->imask = IMASK_DEF;
-       bp->core_unit = ssb_core_unit(bp);
--      bp->dma_offset = SB_PCI_DMA;
-       /* XXX - really required? 
-          bp->flags |= B44_FLAG_BUGGY_TXPTR;
-          */
--out:
--      return err;
-+
-+      return 0;
- }
- static int __devinit b44_init_one(struct pci_dev *pdev,
-@@ -1810,7 +2146,7 @@
-       spin_lock_init(&bp->lock);
--      bp->regs = ioremap(b44reg_base, b44reg_len);
-+      bp->regs = (unsigned long) ioremap(b44reg_base, b44reg_len);
-       if (bp->regs == 0UL) {
-               printk(KERN_ERR PFX "Cannot map device registers, "
-                      "aborting.\n");
-@@ -1871,15 +2207,21 @@
-       pci_save_state(bp->pdev);
--      printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
-+      printk(KERN_INFO "%s: Broadcom %s 10/100BaseT Ethernet ", dev->name,
-+              (pdev->device == PCI_DEVICE_ID_BCM4713) ? "47xx" : "4400");
-       for (i = 0; i < 6; i++)
-               printk("%2.2x%c", dev->dev_addr[i],
-                      i == 5 ? '\n' : ':');
-+      /* Initialize phy */
-+      spin_lock_irq(&bp->lock);
-+      b44_chip_reset(bp);
-+      spin_unlock_irq(&bp->lock);
-+      
-       return 0;
- err_out_iounmap:
--      iounmap(bp->regs);
-+      iounmap((void *) bp->regs);
- err_out_free_dev:
-       free_netdev(dev);
-@@ -1901,7 +2243,7 @@
-               struct b44 *bp = netdev_priv(dev);
-               unregister_netdev(dev);
--              iounmap(bp->regs);
-+              iounmap((void *) bp->regs);
-               free_netdev(dev);
-               pci_release_regions(pdev);
-               pci_disable_device(pdev);
-diff -Nur linux-2.6.12.5/drivers/net/b44.h linux-2.6.12.5-b44/drivers/net/b44.h
---- linux-2.6.12.5/drivers/net/b44.h   2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-b44/drivers/net/b44.h       2005-09-16 22:18:06.217954624 +0200
-@@ -292,6 +292,9 @@
- #define SSB_PCI_MASK1         0xfc000000
- #define SSB_PCI_MASK2         0xc0000000
-+#define br32(REG)     readl((void *)bp->regs + (REG))
-+#define bw32(REG,VAL) writel((VAL), (void *)bp->regs + (REG))
-+
- /* 4400 PHY registers */
- #define B44_MII_AUXCTRL               24      /* Auxiliary Control */
- #define  MII_AUXCTRL_DUPLEX   0x0001  /* Full Duplex */
-@@ -345,6 +348,8 @@
- };
- #define B44_MCAST_TABLE_SIZE  32
-+#define B44_PHY_ADDR_NO_PHY   30
-+#define B44_MDC_RATIO         5000000
- /* SW copy of device statistics, kept up to date by periodic timer
-  * which probes HW values.  Must have same relative layout as HW
-@@ -410,7 +415,7 @@
-       struct net_device_stats stats;
-       struct b44_hw_stats     hw_stats;
--      void __iomem            *regs;
-+      unsigned long           regs;
-       struct pci_dev          *pdev;
-       struct net_device       *dev;
index 80a7b90b8523938588d482bf40d5677b51263609..0dd2ccf7cc8f917b13b5a89efb99b25d8eab6c8e 100644 (file)
@@ -1,6 +1,6 @@
---- linux-2.6.11.3-stock/include/linux/netfilter_ipv4/ip_conntrack.h   2005-03-13 00:44:41.000000000 -0600
-+++ linux-2.6.11.3-layer7/include/linux/netfilter_ipv4/ip_conntrack.h  2005-03-13 20:30:01.000000000 -0600
-@@ -177,6 +177,15 @@ struct ip_conntrack
+--- linux-2.6.14/include/linux/netfilter_ipv4/ip_conntrack.h   2005-10-27 19:02:08.000000000 -0500
++++ linux-2.6.14-layer7/include/linux/netfilter_ipv4/ip_conntrack.h    2005-11-12 17:31:34.000000000 -0600
+@@ -253,6 +253,15 @@ struct ip_conntrack
        /* Traversed often, so hopefully in different cacheline to top */
        /* These are my tuples; original and reply */
        struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
@@ -16,8 +16,8 @@
  };
  
  struct ip_conntrack_expect
---- linux-2.6.11.3-stock/include/linux/netfilter_ipv4/ipt_layer7.h     1969-12-31 18:00:00.000000000 -0600
-+++ linux-2.6.11.3-layer7/include/linux/netfilter_ipv4/ipt_layer7.h    2005-03-13 20:30:01.000000000 -0600
+--- linux-2.6.14/include/linux/netfilter_ipv4/ipt_layer7.h     1969-12-31 18:00:00.000000000 -0600
++++ linux-2.6.14-layer7/include/linux/netfilter_ipv4/ipt_layer7.h      2005-11-12 17:31:34.000000000 -0600
 @@ -0,0 +1,26 @@
 +/* 
 +  By Matthew Strait <quadong@users.sf.net>, Dec 2003.
@@ -45,9 +45,9 @@
 +};
 +
 +#endif /* _IPT_LAYER7_H */
---- linux-2.6.11.3-stock/net/ipv4/netfilter/Kconfig    2005-03-13 00:44:38.000000000 -0600
-+++ linux-2.6.11.3-layer7/net/ipv4/netfilter/Kconfig   2005-03-13 20:30:01.000000000 -0600
-@@ -146,6 +146,33 @@ config IP_NF_MATCH_MAC
+--- linux-2.6.14/net/ipv4/netfilter/Kconfig    2005-10-27 19:02:08.000000000 -0500
++++ linux-2.6.14-layer7/net/ipv4/netfilter/Kconfig     2005-11-12 17:31:34.000000000 -0600
+@@ -205,6 +205,24 @@ config IP_NF_MATCH_MAC
  
          To compile it as a module, choose M here.  If unsure, say N.
  
 +      depends on IP_NF_MATCH_LAYER7
 +      help
 +        Say Y to get lots of debugging output.
-+
-+config IP_NF_MATCH_LAYER7_MAXDATALEN
-+        int "Buffer size for application layer data" if IP_NF_MATCH_LAYER7
-+        range 256 65536 
-+        default 2048
-+      help
-+        Size of the buffer that the application layer data is stored in.
-+        Unless you know what you're doing, leave it at the default of 2kB.
-+
 +
  config IP_NF_MATCH_PKTTYPE
        tristate "Packet type match support"
        depends on IP_NF_IPTABLES
---- linux-2.6.11.3-stock/net/ipv4/netfilter/Makefile   2005-03-13 00:44:14.000000000 -0600
-+++ linux-2.6.11.3-layer7/net/ipv4/netfilter/Makefile  2005-03-13 20:30:01.000000000 -0600
-@@ -60,6 +60,8 @@ obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ip
- obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
+--- linux-2.6.14/net/ipv4/netfilter/Makefile   2005-10-27 19:02:08.000000000 -0500
++++ linux-2.6.14-layer7/net/ipv4/netfilter/Makefile    2005-11-12 17:31:34.000000000 -0600
+@@ -74,6 +74,8 @@ obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt
  obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o
+ obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
  
 +obj-$(CONFIG_IP_NF_MATCH_LAYER7) += ipt_layer7.o
 +
  # targets
  obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
  obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
---- linux-2.6.11.3-stock/net/ipv4/netfilter/ip_conntrack_core.c        2005-03-13 00:43:57.000000000 -0600
-+++ linux-2.6.11.3-layer7/net/ipv4/netfilter/ip_conntrack_core.c       2005-03-13 22:09:32.000000000 -0600
-@@ -247,6 +247,13 @@ destroy_conntrack(struct nf_conntrack *n
+--- linux-2.6.14/net/ipv4/netfilter/ip_conntrack_core.c        2005-10-27 19:02:08.000000000 -0500
++++ linux-2.6.14-layer7/net/ipv4/netfilter/ip_conntrack_core.c 2005-11-12 17:31:34.000000000 -0600
+@@ -335,6 +335,13 @@ destroy_conntrack(struct nf_conntrack *n
         * too. */
-       remove_expectations(ct);
+       ip_ct_remove_expectations(ct);
  
 +      #if defined(CONFIG_IP_NF_MATCH_LAYER7) || defined(CONFIG_IP_NF_MATCH_LAYER7_MODULE)
 +      if(ct->layer7.app_proto)
        /* We overload first tuple to link into unconfirmed list. */
        if (!is_confirmed(ct)) {
                BUG_ON(list_empty(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list));
---- linux-2.6.11.3-stock/net/ipv4/netfilter/ip_conntrack_standalone.c  2005-03-13 00:44:25.000000000 -0600
-+++ linux-2.6.11.3-layer7/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-03-13 20:30:01.000000000 -0600
-@@ -152,6 +152,12 @@ static int ct_seq_real_show(const struct
-               return 1;
+--- linux-2.6.14/net/ipv4/netfilter/ip_conntrack_standalone.c  2005-10-27 19:02:08.000000000 -0500
++++ linux-2.6.14-layer7/net/ipv4/netfilter/ip_conntrack_standalone.c   2005-11-12 17:31:34.000000000 -0600
+@@ -188,6 +188,12 @@ static int ct_seq_show(struct seq_file *
+               return -ENOSPC;
  #endif
  
 +#if defined(CONFIG_IP_NF_MATCH_LAYER7) || defined(CONFIG_IP_NF_MATCH_LAYER7_MODULE)
 +#endif
 +
        if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use)))
-               return 1;
+               return -ENOSPC;
  
---- linux-2.6.11.3-stock/net/ipv4/netfilter/ipt_layer7.c       1969-12-31 18:00:00.000000000 -0600
-+++ linux-2.6.11.3-layer7/net/ipv4/netfilter/ipt_layer7.c      2005-03-13 20:30:01.000000000 -0600
-@@ -0,0 +1,552 @@
+--- linux-2.6.14/net/ipv4/netfilter/ipt_layer7.c       1969-12-31 18:00:00.000000000 -0600
++++ linux-2.6.14-layer7/net/ipv4/netfilter/ipt_layer7.c        2005-11-12 17:49:24.000000000 -0600
+@@ -0,0 +1,569 @@
 +/* 
 +  Kernel module to match application layer (OSI layer 7) 
 +  data in connections.
 +#include <linux/ctype.h>
 +#include <net/ip.h>
 +#include <net/tcp.h>
-+#include <linux/netfilter_ipv4/lockhelp.h>
++#include <linux/spinlock.h>
 +
 +#include "regexp/regexp.c"
 +
 +MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>");
 +MODULE_LICENSE("GPL");
 +MODULE_DESCRIPTION("iptables application layer match module");
++MODULE_VERSION("2.0");
++
++static int maxdatalen = 2048; // this is the default
++module_param(maxdatalen, int, 0444);
++MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter");
 +
-+#if defined(CONFIG_IP_NF_MATCH_LAYER7_DEBUG)
++#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
 +      #define DPRINTK(format,args...) printk(format,##args)
 +#else
 +      #define DPRINTK(format,args...)
 +
 +/* Number of packets whose data we look at.
 +This can be modified through /proc/net/layer7_numpackets */
-+static int num_packets = 8;
++static int num_packets = 10;
 +
 +static struct pattern_cache {
 +      char * regex_string;
 +  time.  In this case, we have to protect the conntracks and the list of 
 +  compiled patterns.
 +*/
-+DECLARE_RWLOCK(ct_lock);
-+DECLARE_LOCK(list_lock);
++DEFINE_RWLOCK(ct_lock);
++DEFINE_SPINLOCK(list_lock);
 +
-+#if CONFIG_IP_NF_MATCH_LAYER7_DEBUG
++#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
 +/* Converts an unfriendly string into a friendly one by 
 +replacing unprintables with periods and all whitespace with " ". */
 +static char * friendly_print(unsigned char * s)
 +                      struct ipt_layer7_info * info)
 +{
 +      /* If we're in here, throw the app data away */
-+      WRITE_LOCK(&ct_lock);
++      write_lock(&ct_lock);
 +      if(master_conntrack->layer7.app_data != NULL) {
 +
 +      #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
 +              kfree(master_conntrack->layer7.app_data);
 +              master_conntrack->layer7.app_data = NULL; /* don't free again */
 +      }
-+      WRITE_UNLOCK(&ct_lock);
++      write_unlock(&ct_lock);
 +
 +      if(master_conntrack->layer7.app_proto){
 +              /* Here child connections set their .app_proto (for /proc/net/ip_conntrack) */
-+              WRITE_LOCK(&ct_lock);
++              write_lock(&ct_lock);
 +              if(!conntrack->layer7.app_proto) {
 +                      conntrack->layer7.app_proto = kmalloc(strlen(master_conntrack->layer7.app_proto)+1, GFP_ATOMIC);
 +                      if(!conntrack->layer7.app_proto){
 +                              if (net_ratelimit()) 
 +                                      printk(KERN_ERR "layer7: out of memory in match_no_append, bailing.\n");
-+                              WRITE_UNLOCK(&ct_lock);
++                              write_unlock(&ct_lock);
 +                              return 1;
 +                      }
 +                      strcpy(conntrack->layer7.app_proto, master_conntrack->layer7.app_proto);
 +              }
-+              WRITE_UNLOCK(&ct_lock);
++              write_unlock(&ct_lock);
 +      
 +              return (!strcmp(master_conntrack->layer7.app_proto, info->protocol));
 +      }
 +      else {
 +              /* If not classified, set to "unknown" to distinguish from 
 +              connections that are still being tested. */
-+              WRITE_LOCK(&ct_lock);
++              write_lock(&ct_lock);
 +              master_conntrack->layer7.app_proto = kmalloc(strlen("unknown")+1, GFP_ATOMIC);
 +              if(!master_conntrack->layer7.app_proto){
 +                      if (net_ratelimit()) 
 +                              printk(KERN_ERR "layer7: out of memory in match_no_append, bailing.\n");
-+                      WRITE_UNLOCK(&ct_lock);
++                      write_unlock(&ct_lock);
 +                      return 1;
 +              }
 +              strcpy(master_conntrack->layer7.app_proto, "unknown");
-+              WRITE_UNLOCK(&ct_lock);
++              write_unlock(&ct_lock);
 +              return 0;
 +      }
 +}
 +
 +      /* Strip nulls. Make everything lower case (our regex lib doesn't
 +      do case insensitivity).  Add it to the end of the current data. */
-+      for(i = 0; i < CONFIG_IP_NF_MATCH_LAYER7_MAXDATALEN-oldlength-1 && 
++      for(i = 0; i < maxdatalen-oldlength-1 && 
 +                 i < appdatalen; i++) {
 +              if(app_data[i] != '\0') {
 +                      master_conntrack->layer7.app_data[length+oldlength] = 
 +              return info->invert;
 +      }
 +
-+      /* Treat the parent and all its children together as one connection, 
-+      except for the purpose of setting conntrack->layer7.app_proto in the 
-+      actual connection. This makes /proc/net/ip_conntrack somewhat more 
-+      satisfying. */
-+      if(!(conntrack  = ip_conntrack_get((struct sk_buff *)skb, &ctinfo)) ||
++      /* Treat parent & all its children together as one connection, except 
++      for the purpose of setting conntrack->layer7.app_proto in the actual 
++      connection. This makes /proc/net/ip_conntrack more satisfying. */
++      if(!(conntrack = ip_conntrack_get((struct sk_buff *)skb, &ctinfo)) ||
 +         !(master_conntrack = ip_conntrack_get((struct sk_buff *)skb, &master_ctinfo))) {
-+              DPRINTK("layer7: packet is not from a known connection, giving up.\n");
++              //DPRINTK("layer7: packet is not from a known connection, giving up.\n");
 +              return info->invert;
 +      }
 +      
 +      app_data = skb->data + app_data_offset(skb);
 +      appdatalen = skb->tail - app_data;
 +
-+      LOCK_BH(&list_lock);
++      spin_lock_bh(&list_lock);
 +      /* the return value gets checked later, when we're ready to use it */
 +      comppattern = compile_and_cache(info->pattern, info->protocol);
-+      UNLOCK_BH(&list_lock);
++      spin_unlock_bh(&list_lock);
 +
 +      /* On the first packet of a connection, allocate space for app data */
-+      WRITE_LOCK(&ct_lock);
++      write_lock(&ct_lock);
 +      if(TOTAL_PACKETS == 1 && !skb->cb[0] && !master_conntrack->layer7.app_data) {
-+              master_conntrack->layer7.app_data = kmalloc(CONFIG_IP_NF_MATCH_LAYER7_MAXDATALEN, GFP_ATOMIC);
++              master_conntrack->layer7.app_data = kmalloc(maxdatalen, GFP_ATOMIC);
 +              if(!master_conntrack->layer7.app_data){                                                  
 +                      if (net_ratelimit()) 
 +                              printk(KERN_ERR "layer7: out of memory in match, bailing.\n");
-+                      WRITE_UNLOCK(&ct_lock);
++                      write_unlock(&ct_lock);
 +                      return info->invert;
 +              }
 +
 +              master_conntrack->layer7.app_data[0] = '\0';
 +      }
-+      WRITE_UNLOCK(&ct_lock);
++      write_unlock(&ct_lock);
 +
 +      /* Can be here, but unallocated, if numpackets is increased near 
 +      the beginning of a connection */
 +
 +      if(!skb->cb[0]){
 +              int newbytes;
-+              WRITE_LOCK(&ct_lock);
++              write_lock(&ct_lock);
 +              newbytes = add_data(master_conntrack, app_data, appdatalen);
-+              WRITE_UNLOCK(&ct_lock);
++              write_unlock(&ct_lock);
 +
 +              if(newbytes == 0) { /* didn't add any data */
 +                      skb->cb[0] = 1;
 +              pattern_result = 0;
 +      /* If the regexp failed to compile, don't bother running it */
 +      } else if(comppattern && regexec(comppattern, master_conntrack->layer7.app_data)) {
-+              DPRINTK("layer7: regexec positive: %s!\n", info->protocol);
++              DPRINTK("layer7: matched %s\n", info->protocol);
 +              pattern_result = 1;
 +      } else pattern_result = 0;
 +
 +      if(pattern_result) {
-+              WRITE_LOCK(&ct_lock);
++              write_lock(&ct_lock);
 +              master_conntrack->layer7.app_proto = kmalloc(strlen(info->protocol)+1, GFP_ATOMIC);
 +              if(!master_conntrack->layer7.app_proto){
 +                      if (net_ratelimit()) 
 +                              printk(KERN_ERR "layer7: out of memory in match, bailing.\n");
-+                      WRITE_UNLOCK(&ct_lock);
++                      write_unlock(&ct_lock);
 +                      return (pattern_result ^ info->invert);
 +              }
 +              strcpy(master_conntrack->layer7.app_proto, info->protocol);
-+              WRITE_UNLOCK(&ct_lock);
++              write_unlock(&ct_lock);
 +      }
 +
 +      /* mark the packet seen */
 +              return count;
 +      }
 +
-+      copy_from_user(foo, buffer, count);
++      if(copy_from_user(foo, buffer, count)) {
++              return -EFAULT;
++      }
++      
 +
 +      num_packets = my_atoi(foo);
 +      kfree (foo);
 +static int __init init(void)
 +{
 +      layer7_init_proc();
++      if(maxdatalen < 1) {
++              printk(KERN_WARNING "layer7: maxdatalen can't be < 1, using 1\n");
++              maxdatalen = 1;
++      }
++      /* This is not a hard limit.  It's just here to prevent people from 
++      bringing their slow machines to a grinding halt. */
++      else if(maxdatalen > 65536) {
++              printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, using 65536\n");
++              maxdatalen = 65536;             
++      }       
 +      return ipt_register_match(&layer7_match);
 +}
 +
 +
 +module_init(init);
 +module_exit(fini);
---- linux-2.6.11.3-stock/net/ipv4/netfilter/regexp/regexp.c    1969-12-31 18:00:00.000000000 -0600
-+++ linux-2.6.11.3-layer7/net/ipv4/netfilter/regexp/regexp.c   2005-03-13 20:30:01.000000000 -0600
+--- linux-2.6.14/net/ipv4/netfilter/regexp/regexp.c    1969-12-31 18:00:00.000000000 -0600
++++ linux-2.6.14-layer7/net/ipv4/netfilter/regexp/regexp.c     2005-11-12 17:31:34.000000000 -0600
 @@ -0,0 +1,1195 @@
 +/*
 + * regcomp and regexec -- regsub and regerror are elsewhere
 +#endif
 +
 +
---- linux-2.6.11.3-stock/net/ipv4/netfilter/regexp/regexp.h    1969-12-31 18:00:00.000000000 -0600
-+++ linux-2.6.11.3-layer7/net/ipv4/netfilter/regexp/regexp.h   2005-03-13 20:30:01.000000000 -0600
+--- linux-2.6.14/net/ipv4/netfilter/regexp/regexp.h    1969-12-31 18:00:00.000000000 -0600
++++ linux-2.6.14-layer7/net/ipv4/netfilter/regexp/regexp.h     2005-11-12 17:31:34.000000000 -0600
 @@ -0,0 +1,41 @@
 +/*
 + * Definitions etc. for regexp(3) routines.
 +void regerror(char *s);
 +
 +#endif
---- linux-2.6.11.3-stock/net/ipv4/netfilter/regexp/regmagic.h  1969-12-31 18:00:00.000000000 -0600
-+++ linux-2.6.11.3-layer7/net/ipv4/netfilter/regexp/regmagic.h 2005-03-13 20:30:01.000000000 -0600
+--- linux-2.6.14/net/ipv4/netfilter/regexp/regmagic.h  1969-12-31 18:00:00.000000000 -0600
++++ linux-2.6.14-layer7/net/ipv4/netfilter/regexp/regmagic.h   2005-11-12 17:31:34.000000000 -0600
 @@ -0,0 +1,5 @@
 +/*
 + * The first byte of the regexp internal "program" is actually this magic
 + * number; the start node begins in the second byte.
 + */
 +#define       MAGIC   0234
---- linux-2.6.11.3-stock/net/ipv4/netfilter/regexp/regsub.c    1969-12-31 18:00:00.000000000 -0600
-+++ linux-2.6.11.3-layer7/net/ipv4/netfilter/regexp/regsub.c   2005-03-13 20:30:01.000000000 -0600
+--- linux-2.6.14/net/ipv4/netfilter/regexp/regsub.c    1969-12-31 18:00:00.000000000 -0600
++++ linux-2.6.14-layer7/net/ipv4/netfilter/regexp/regsub.c     2005-11-12 17:31:34.000000000 -0600
 @@ -0,0 +1,95 @@
 +/*
 + * regsub
diff --git a/openwrt/target/linux/linux-2.6/patches/generic/101-mppe-mppc-1.3.patch b/openwrt/target/linux/linux-2.6/patches/generic/101-mppe-mppc-1.3.patch
deleted file mode 100644 (file)
index aa43025..0000000
+++ /dev/null
@@ -1,1559 +0,0 @@
-diff -ruN linux-2.6.12.orig/drivers/net/Kconfig linux-2.6.12/drivers/net/Kconfig
---- linux-2.6.12.orig/drivers/net/Kconfig      2005-06-28 19:57:16.000000000 +0200
-+++ linux-2.6.12/drivers/net/Kconfig   2005-06-28 20:07:01.000000000 +0200
-@@ -2417,6 +2417,32 @@
-         module; it is called bsd_comp and will show up in the directory
-         modules once you have said "make modules". If unsure, say N.
-+config PPP_MPPE_MPPC
-+      tristate "Microsoft PPP compression/encryption (MPPC/MPPE)"
-+      depends on PPP
-+      select CRYPTO_SHA1
-+      select CRYPTO_ARC4
-+      ---help---
-+        Support for the Microsoft Point-To-Point Compression (RFC2118) and 
-+        Microsoft Point-To-Point Encryption (RFC3078). These protocols are
-+        supported by Microsoft Windows and wide range of "hardware" access
-+        servers. MPPE is common protocol in Virtual Private Networks. According
-+        to RFC3078, MPPE supports 40, 56 and 128-bit key lengths. Depending on
-+        PPP daemon configuration on both ends of the link, following scenarios
-+        are possible:
-+              - only compression (MPPC) is used,
-+              - only encryption (MPPE) is used,
-+              - compression and encryption (MPPC+MPPE) are used.
-+
-+        Please note that Hi/Fn (http://www.hifn.com) holds patent on MPPC so
-+        you should check if this patent is valid in your country in order to
-+        avoid legal problems.
-+
-+        For more information please visit http://free.polbox.pl/h/hs001
-+
-+        To compile this driver as a module, choose M here. The module will
-+        be called ppp_mppe_mppc.ko.
-+
- config PPPOE
-       tristate "PPP over Ethernet (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && PPP
-diff -ruN linux-2.6.12.orig/drivers/net/Makefile linux-2.6.12/drivers/net/Makefile
---- linux-2.6.12.orig/drivers/net/Makefile     2005-06-28 19:57:16.000000000 +0200
-+++ linux-2.6.12/drivers/net/Makefile  2005-06-28 20:07:01.000000000 +0200
-@@ -105,6 +105,7 @@
- obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
- obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
- obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
-+obj-$(CONFIG_PPP_MPPE_MPPC) += ppp_mppe_mppc.o
- obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
- obj-$(CONFIG_SLIP) += slip.o
-diff -ruN linux-2.6.12.orig/drivers/net/ppp_generic.c linux-2.6.12/drivers/net/ppp_generic.c
---- linux-2.6.12.orig/drivers/net/ppp_generic.c        2005-06-28 19:57:20.000000000 +0200
-+++ linux-2.6.12/drivers/net/ppp_generic.c     2005-06-28 20:07:01.000000000 +0200
-@@ -19,7 +19,7 @@
-  * PPP driver, written by Michael Callahan and Al Longyear, and
-  * subsequently hacked by Paul Mackerras.
-  *
-- * ==FILEVERSION 20041108==
-+ * ==FILEVERSION 20050110==
-  */
- #include <linux/config.h>
-@@ -105,6 +105,7 @@
-       spinlock_t      rlock;          /* lock for receive side 58 */
-       spinlock_t      wlock;          /* lock for transmit side 5c */
-       int             mru;            /* max receive unit 60 */
-+      int             mru_alloc;      /* MAX(1500,MRU) for dev_alloc_skb() */
-       unsigned int    flags;          /* control bits 64 */
-       unsigned int    xstate;         /* transmit state bits 68 */
-       unsigned int    rstate;         /* receive state bits 6c */
-@@ -632,7 +633,9 @@
-       case PPPIOCSMRU:
-               if (get_user(val, p))
-                       break;
--              ppp->mru = val;
-+              ppp->mru_alloc = ppp->mru = val;
-+              if (ppp->mru_alloc < PPP_MRU)
-+                  ppp->mru_alloc = PPP_MRU;   /* increase for broken peers */
-               err = 0;
-               break;
-@@ -1107,14 +1110,37 @@
-       case PPP_CCP:
-               /* peek at outbound CCP frames */
-               ppp_ccp_peek(ppp, skb, 0);
-+              /*
-+               * When LZS or MPPE/MPPC has been negotiated we don't send
-+               * CCP_RESETACK after receiving CCP_RESETREQ; in fact pppd
-+               * sends such a packet but we silently discard it here
-+               */
-+              if (CCP_CODE(skb->data+2) == CCP_RESETACK
-+                  && (ppp->xcomp->compress_proto == CI_MPPE
-+                      || ppp->xcomp->compress_proto == CI_LZS)) {
-+                  --ppp->stats.tx_packets;
-+                  ppp->stats.tx_bytes -= skb->len - 2;
-+                  kfree_skb(skb);
-+                  return;
-+              }
-               break;
-       }
-       /* try to do packet compression */
-       if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
-           && proto != PPP_LCP && proto != PPP_CCP) {
--              new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
--                                  GFP_ATOMIC);
-+              int comp_ovhd = 0;
-+              /* 
-+               * because of possible data expansion when MPPC or LZS
-+               * is used, allocate compressor's buffer 12.5% bigger
-+               * than MTU
-+               */
-+              if (ppp->xcomp->compress_proto == CI_MPPE)
-+                  comp_ovhd = ((ppp->dev->mtu * 9) / 8) + 1 + MPPE_OVHD;
-+              else if (ppp->xcomp->compress_proto == CI_LZS)
-+                  comp_ovhd = ((ppp->dev->mtu * 9) / 8) + 1 + LZS_OVHD;
-+              new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len
-+                                  + comp_ovhd, GFP_ATOMIC);
-               if (new_skb == 0) {
-                       printk(KERN_ERR "PPP: no memory (comp pkt)\n");
-                       goto drop;
-@@ -1132,9 +1158,21 @@
-                       skb = new_skb;
-                       skb_put(skb, len);
-                       skb_pull(skb, 2);       /* pull off A/C bytes */
--              } else {
-+              } else if (len == 0) {
-                       /* didn't compress, or CCP not up yet */
-                       kfree_skb(new_skb);
-+              } else {
-+                      /*
-+                       * (len < 0)
-+                       * MPPE requires that we do not send unencrypted
-+                       * frames.  The compressor will return -1 if we
-+                       * should drop the frame.  We cannot simply test
-+                       * the compress_proto because MPPE and MPPC share
-+                       * the same number.
-+                       */
-+                      printk(KERN_ERR "ppp: compressor dropped pkt\n");
-+                      kfree_skb(new_skb);
-+                      goto drop;
-               }
-       }
-@@ -1640,14 +1678,15 @@
-               goto err;
-       if (proto == PPP_COMP) {
--              ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN);
-+              ns = dev_alloc_skb(ppp->mru_alloc + PPP_HDRLEN);
-               if (ns == 0) {
-                       printk(KERN_ERR "ppp_decompress_frame: no memory\n");
-                       goto err;
-               }
-               /* the decompressor still expects the A/C bytes in the hdr */
-               len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2,
--                              skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN);
-+                              skb->len + 2, ns->data,
-+                              ppp->mru_alloc + PPP_HDRLEN);
-               if (len < 0) {
-                       /* Pass the compressed frame to pppd as an
-                          error indication. */
-@@ -1673,7 +1712,14 @@
-       return skb;
-  err:
--      ppp->rstate |= SC_DC_ERROR;
-+      if (ppp->rcomp->compress_proto != CI_MPPE
-+          && ppp->rcomp->compress_proto != CI_LZS) {
-+          /*
-+           * If decompression protocol isn't MPPE/MPPC or LZS, we set
-+           * SC_DC_ERROR flag and wait for CCP_RESETACK
-+           */
-+          ppp->rstate |= SC_DC_ERROR;
-+      }
-       ppp_receive_error(ppp);
-       return skb;
- }
-@@ -2349,6 +2395,7 @@
-       memset(ppp, 0, sizeof(struct ppp));
-       ppp->mru = PPP_MRU;
-+      ppp->mru_alloc = PPP_MRU;
-       init_ppp_file(&ppp->file, INTERFACE);
-       ppp->file.hdrlen = PPP_HDRLEN - 2;      /* don't count proto bytes */
-       for (i = 0; i < NUM_NP; ++i)
-diff -ruN linux-2.6.12.orig/drivers/net/ppp_mppe_mppc.c linux-2.6.12/drivers/net/ppp_mppe_mppc.c
---- linux-2.6.12.orig/drivers/net/ppp_mppe_mppc.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12/drivers/net/ppp_mppe_mppc.c   2005-06-28 20:07:01.000000000 +0200
-@@ -0,0 +1,1299 @@
-+/*
-+ * ppp_mppe_mppc.c - MPPC/MPPE "compressor/decompressor" module.
-+ *
-+ * Copyright (c) 1994 Árpád Magosányi <mag@bunuel.tii.matav.hu>
-+ * Copyright (c) 1999 Tim Hockin, Cobalt Networks Inc. <thockin@cobaltnet.com>
-+ * Copyright (c) 2002-2004 Jan Dubiec <jdx@slackware.pl>
-+ * 
-+ * Permission to use, copy, modify, and distribute this software and its
-+ * documentation is hereby granted, provided that the above copyright
-+ * notice appears in all copies. This software is provided without any
-+ * warranty, express or implied.
-+ *
-+ * The code is based on MPPE kernel module written by Árpád Magosányi and
-+ * Tim Hockin which can be found on http://planetmirror.com/pub/mppe/.
-+ * I have added MPPC and 56 bit session keys support in MPPE.
-+ *
-+ * WARNING! Although this is open source code, its usage in some countries
-+ * (in particular in the USA) may violate Stac Inc. patent for MPPC.
-+ *
-+ *  ==FILEVERSION 20041123==
-+ *
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <asm/scatterlist.h>
-+#include <linux/vmalloc.h>
-+#include <linux/crypto.h>
-+
-+#include <linux/ppp_defs.h>
-+#include <linux/ppp-comp.h>
-+
-+/*
-+ * State for a mppc/mppe "(de)compressor".
-+ */
-+struct ppp_mppe_state {
-+    struct crypto_tfm *arc4_tfm;
-+    struct crypto_tfm *sha1_tfm;
-+    u8                *sha1_digest;
-+    u8                master_key[MPPE_MAX_KEY_LEN];
-+    u8                session_key[MPPE_MAX_KEY_LEN];
-+    u8                mppc;           /* do we use compression (MPPC)? */
-+    u8                mppe;           /* do we use encryption (MPPE)? */
-+    u8                keylen;         /* key length in bytes */
-+    u8                bitkeylen;      /* key length in bits */
-+    u16               ccount;         /* coherency counter */
-+    u16               bits;           /* MPPC/MPPE control bits */
-+    u8                stateless;      /* do we use stateless mode? */
-+    u8                nextflushed;    /* set A bit in the next outgoing packet;
-+                                 used only by compressor*/
-+    u8                flushexpected;  /* drop packets until A bit is received;
-+                                 used only by decompressor*/
-+    u8                *hist;          /* MPPC history */
-+    u16               *hash;          /* Hash table; used only by compressor */
-+    u16               histptr;        /* history "cursor" */
-+    int               unit;
-+    int               debug;
-+    int               mru;
-+    struct compstat stats;
-+};
-+
-+#define MPPE_HIST_LEN         8192    /* MPPC history size */
-+#define MPPE_MAX_CCOUNT               0x0FFF  /* max. coherency counter value */
-+
-+#define MPPE_BIT_FLUSHED      0x80    /* bit A */
-+#define MPPE_BIT_RESET                0x40    /* bit B */
-+#define MPPE_BIT_COMP         0x20    /* bit C */
-+#define MPPE_BIT_ENCRYPTED    0x10    /* bit D */
-+
-+#define MPPE_SALT0            0xD1    /* values used in MPPE key derivation */
-+#define MPPE_SALT1            0x26    /* according to RFC3079 */
-+#define MPPE_SALT2            0x9E
-+
-+#define MPPE_CCOUNT(x)                ((((x)[4] & 0x0f) << 8) + (x)[5])
-+#define MPPE_BITS(x)          ((x)[4] & 0xf0)
-+#define MPPE_CTRLHI(x)                ((((x)->ccount & 0xf00)>>8)|((x)->bits))
-+#define MPPE_CTRLLO(x)                ((x)->ccount & 0xff)
-+
-+/*
-+ * Kernel Crypto API needs its arguments to be in kmalloc'd memory, not in the
-+ * module static data area. That means sha_pad needs to be kmalloc'd. It is done
-+ * in mppe_module_init(). This has been pointed out on 30th July 2004 by Oleg
-+ * Makarenko on pptpclient-devel mailing list.
-+ */
-+#define SHA1_PAD_SIZE         40
-+struct sha_pad {
-+    unsigned char sha_pad1[SHA1_PAD_SIZE];
-+    unsigned char sha_pad2[SHA1_PAD_SIZE];
-+};
-+static struct sha_pad *sha_pad;
-+
-+static inline void
-+setup_sg(struct scatterlist *sg, const void  *address, unsigned int length)
-+{
-+    sg[0].page = virt_to_page(address);
-+    sg[0].offset = offset_in_page(address);
-+    sg[0].length = length;
-+}
-+
-+static inline void
-+arc4_setkey(struct ppp_mppe_state *state, const unsigned char *key,
-+          const unsigned int keylen)
-+{
-+    crypto_cipher_setkey(state->arc4_tfm, key, keylen);
-+}
-+
-+static inline void
-+arc4_encrypt(struct ppp_mppe_state *state, const unsigned char *in,
-+           const unsigned int len, unsigned char *out)
-+{
-+    struct scatterlist sgin[4], sgout[4];
-+
-+    setup_sg(sgin, in, len);
-+    setup_sg(sgout, out, len);
-+    crypto_cipher_encrypt(state->arc4_tfm, sgout, sgin, len);
-+}
-+
-+#define arc4_decrypt arc4_encrypt
-+
-+/*
-+ * Key Derivation, from RFC 3078, RFC 3079.
-+ * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
-+ */
-+static void
-+get_new_key_from_sha(struct ppp_mppe_state *state, unsigned char *interim_key)
-+{
-+    struct scatterlist sg[4];
-+
-+    setup_sg(&sg[0], state->master_key, state->keylen);
-+    setup_sg(&sg[1], sha_pad->sha_pad1, sizeof(sha_pad->sha_pad1));
-+    setup_sg(&sg[2], state->session_key, state->keylen);
-+    setup_sg(&sg[3], sha_pad->sha_pad2, sizeof(sha_pad->sha_pad2));
-+
-+    crypto_digest_digest (state->sha1_tfm, sg, 4, state->sha1_digest);
-+
-+    memcpy(interim_key, state->sha1_digest, state->keylen);
-+}
-+
-+static void
-+mppe_change_key(struct ppp_mppe_state *state, int initialize)
-+{
-+    unsigned char interim_key[MPPE_MAX_KEY_LEN];
-+
-+    get_new_key_from_sha(state, interim_key);
-+    if (initialize) {
-+      memcpy(state->session_key, interim_key, state->keylen);
-+    } else {
-+      arc4_setkey(state, interim_key, state->keylen);
-+      arc4_encrypt(state, interim_key, state->keylen, state->session_key);
-+    }
-+    if (state->keylen == 8) {
-+      if (state->bitkeylen == 40) {
-+          state->session_key[0] = MPPE_SALT0;
-+          state->session_key[1] = MPPE_SALT1;
-+          state->session_key[2] = MPPE_SALT2;
-+      } else {
-+          state->session_key[0] = MPPE_SALT0;
-+      }
-+    }
-+    arc4_setkey(state, state->session_key, state->keylen);
-+}
-+
-+/* increase 12-bit coherency counter */
-+static inline void
-+mppe_increase_ccount(struct ppp_mppe_state *state)
-+{
-+    state->ccount = (state->ccount + 1) & MPPE_MAX_CCOUNT;
-+    if (state->mppe) {
-+      if (state->stateless) {
-+          mppe_change_key(state, 0);
-+          state->nextflushed = 1;
-+      } else {
-+          if ((state->ccount & 0xff) == 0xff) {
-+              mppe_change_key(state, 0);
-+          }
-+      }
-+    }
-+}
-+
-+/* allocate space for a MPPE/MPPC (de)compressor.  */
-+/*   comp != 0 -> init compressor */
-+/*   comp = 0 -> init decompressor */
-+static void *
-+mppe_alloc(unsigned char *options, int opt_len, int comp)
-+{
-+    struct ppp_mppe_state *state;
-+    unsigned int digestsize;
-+    u8* fname;
-+
-+    fname = comp ? "mppe_comp_alloc" : "mppe_decomp_alloc";
-+
-+    /*  
-+     * Hack warning - additionally to the standard MPPC/MPPE configuration
-+     * options, pppd passes to the (de)copressor 8 or 16 byte session key.
-+     * Therefore options[1] contains MPPC/MPPE configuration option length
-+     * (CILEN_MPPE = 6), but the real options length, depending on the key
-+     * length, is 6+8 or 6+16.
-+     */
-+    if (opt_len < CILEN_MPPE) {
-+      printk(KERN_WARNING "%s: wrong options length: %u\n", fname, opt_len);
-+      return NULL;
-+    }
-+
-+    if (options[0] != CI_MPPE || options[1] != CILEN_MPPE ||
-+      (options[2] & ~MPPE_STATELESS) != 0 ||
-+      options[3] != 0 || options[4] != 0 ||
-+      (options[5] & ~(MPPE_128BIT|MPPE_56BIT|MPPE_40BIT|MPPE_MPPC)) != 0 ||
-+      (options[5] & (MPPE_128BIT|MPPE_56BIT|MPPE_40BIT|MPPE_MPPC)) == 0) {
-+      printk(KERN_WARNING "%s: options rejected: o[0]=%02x, o[1]=%02x, "
-+             "o[2]=%02x, o[3]=%02x, o[4]=%02x, o[5]=%02x\n", fname, options[0],
-+             options[1], options[2], options[3], options[4], options[5]);
-+      return NULL;
-+    }
-+
-+    state = (struct ppp_mppe_state *)kmalloc(sizeof(*state), GFP_KERNEL);
-+    if (state == NULL) {
-+      printk(KERN_ERR "%s: cannot allocate space for %scompressor\n", fname,
-+             comp ? "" : "de");
-+      return NULL;
-+    }
-+    memset(state, 0, sizeof(struct ppp_mppe_state));
-+
-+    state->mppc = options[5] & MPPE_MPPC;     /* Do we use MPPC? */
-+    state->mppe = options[5] & (MPPE_128BIT | MPPE_56BIT |
-+      MPPE_40BIT);                            /* Do we use MPPE? */
-+
-+    if (state->mppc) {
-+      /* allocate MPPC history */
-+      state->hist = (u8*)vmalloc(2*MPPE_HIST_LEN*sizeof(u8));
-+      if (state->hist == NULL) {
-+          kfree(state);
-+          printk(KERN_ERR "%s: cannot allocate space for MPPC history\n",
-+                 fname);
-+          return NULL;
-+      }
-+
-+      /* allocate hashtable for MPPC compressor */
-+      if (comp) {
-+          state->hash = (u16*)vmalloc(MPPE_HIST_LEN*sizeof(u16));
-+          if (state->hash == NULL) {
-+              vfree(state->hist);
-+              kfree(state);
-+              printk(KERN_ERR "%s: cannot allocate space for MPPC history\n",
-+                     fname);
-+              return NULL;
-+          }
-+      }
-+    }
-+
-+    if (state->mppe) { /* specific for MPPE */
-+      /* Load ARC4 algorithm */
-+      state->arc4_tfm = crypto_alloc_tfm("arc4", 0);
-+      if (state->arc4_tfm == NULL) {
-+          if (state->mppc) {
-+              vfree(state->hash);
-+              if (comp)
-+                  vfree(state->hist);
-+          }
-+          kfree(state);
-+          printk(KERN_ERR "%s: cannot load ARC4 module\n", fname);
-+          return NULL;
-+      }
-+
-+      /* Load SHA1 algorithm */
-+      state->sha1_tfm = crypto_alloc_tfm("sha1", 0);
-+      if (state->sha1_tfm == NULL) {
-+          crypto_free_tfm(state->arc4_tfm);
-+          if (state->mppc) {
-+              vfree(state->hash);
-+              if (comp)
-+                  vfree(state->hist);
-+          }
-+          kfree(state);
-+          printk(KERN_ERR "%s: cannot load SHA1 module\n", fname);
-+          return NULL;
-+      }
-+
-+      digestsize = crypto_tfm_alg_digestsize(state->sha1_tfm);
-+      if (digestsize < MPPE_MAX_KEY_LEN) {
-+          crypto_free_tfm(state->sha1_tfm);
-+          crypto_free_tfm(state->arc4_tfm);
-+          if (state->mppc) {
-+              vfree(state->hash);
-+              if (comp)
-+                  vfree(state->hist);
-+          }
-+          kfree(state);
-+          printk(KERN_ERR "%s: CryptoAPI SHA1 digest size too small\n", fname);
-+      }
-+
-+      state->sha1_digest = kmalloc(digestsize, GFP_KERNEL);
-+      if (!state->sha1_digest) {
-+          crypto_free_tfm(state->sha1_tfm);
-+          crypto_free_tfm(state->arc4_tfm);
-+          if (state->mppc) {
-+              vfree(state->hash);
-+              if (comp)
-+                  vfree(state->hist);
-+          }
-+          kfree(state);
-+          printk(KERN_ERR "%s: cannot allocate space for SHA1 digest\n", fname);
-+      }
-+
-+      memcpy(state->master_key, options+CILEN_MPPE, MPPE_MAX_KEY_LEN);
-+      memcpy(state->session_key, state->master_key, MPPE_MAX_KEY_LEN);
-+      /* initial key generation is done in mppe_init() */
-+    }
-+
-+    return (void *) state;
-+}
-+
-+static void *
-+mppe_comp_alloc(unsigned char *options, int opt_len)
-+{
-+    return mppe_alloc(options, opt_len, 1);
-+}
-+
-+static void *
-+mppe_decomp_alloc(unsigned char *options, int opt_len)
-+{
-+    return mppe_alloc(options, opt_len, 0);
-+}
-+
-+/* cleanup the (de)compressor */
-+static void
-+mppe_comp_free(void *arg)
-+{
-+    struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
-+
-+    if (state != NULL) {
-+      if (state->mppe) {
-+          if (state->sha1_digest != NULL)
-+              kfree(state->sha1_digest);
-+          if (state->sha1_tfm != NULL)
-+              crypto_free_tfm(state->sha1_tfm);
-+          if (state->arc4_tfm != NULL)
-+              crypto_free_tfm(state->arc4_tfm);
-+      }
-+      if (state->hist != NULL)
-+          vfree(state->hist);
-+      if (state->hash != NULL)
-+          vfree(state->hash);
-+      kfree(state);
-+    }
-+}
-+
-+/* init MPPC/MPPE (de)compresor */
-+/*   comp != 0 -> init compressor */
-+/*   comp = 0 -> init decompressor */
-+static int
-+mppe_init(void *arg, unsigned char *options, int opt_len, int unit,
-+        int hdrlen, int mru, int debug, int comp)
-+{
-+    struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
-+    u8* fname;
-+
-+    fname = comp ? "mppe_comp_init" : "mppe_decomp_init";
-+
-+    if (opt_len < CILEN_MPPE) {
-+      if (debug)
-+          printk(KERN_WARNING "%s: wrong options length: %u\n",
-+                 fname, opt_len);
-+      return 0;
-+    }
-+
-+    if (options[0] != CI_MPPE || options[1] != CILEN_MPPE ||
-+      (options[2] & ~MPPE_STATELESS) != 0 ||
-+      options[3] != 0 || options[4] != 0 ||
-+      (options[5] & ~(MPPE_56BIT|MPPE_128BIT|MPPE_40BIT|MPPE_MPPC)) != 0 ||
-+      (options[5] & (MPPE_56BIT|MPPE_128BIT|MPPE_40BIT|MPPE_MPPC)) == 0) {
-+      if (debug)
-+          printk(KERN_WARNING "%s: options rejected: o[0]=%02x, o[1]=%02x, "
-+                 "o[2]=%02x, o[3]=%02x, o[4]=%02x, o[5]=%02x\n", fname,
-+                 options[0], options[1], options[2], options[3], options[4],
-+                 options[5]);
-+      return 0;
-+    }
-+
-+    if ((options[5] & ~MPPE_MPPC) != MPPE_128BIT &&
-+      (options[5] & ~MPPE_MPPC) != MPPE_56BIT &&
-+      (options[5] & ~MPPE_MPPC) != MPPE_40BIT &&
-+      (options[5] & MPPE_MPPC) != MPPE_MPPC) {
-+      if (debug)
-+          printk(KERN_WARNING "%s: don't know what to do: o[5]=%02x\n",
-+                 fname, options[5]);
-+      return 0;
-+    }
-+
-+    state->mppc = options[5] & MPPE_MPPC;     /* Do we use MPPC? */
-+    state->mppe = options[5] & (MPPE_128BIT | MPPE_56BIT |
-+      MPPE_40BIT);                            /* Do we use MPPE? */
-+    state->stateless = options[2] & MPPE_STATELESS; /* Do we use stateless mode? */
-+
-+    switch (state->mppe) {
-+    case MPPE_40BIT:     /* 40 bit key */
-+      state->keylen = 8;
-+      state->bitkeylen = 40;
-+      break;
-+    case MPPE_56BIT:     /* 56 bit key */
-+      state->keylen = 8;
-+      state->bitkeylen = 56;
-+      break;
-+    case MPPE_128BIT:    /* 128 bit key */
-+      state->keylen = 16;
-+      state->bitkeylen = 128;
-+      break;
-+    default:
-+      state->keylen = 0;
-+      state->bitkeylen = 0;
-+    }
-+
-+    state->ccount = MPPE_MAX_CCOUNT;
-+    state->bits = 0;
-+    state->unit  = unit;
-+    state->debug = debug;
-+    state->histptr = MPPE_HIST_LEN;
-+    if (state->mppc) {        /* reset history if MPPC was negotiated */
-+      memset(state->hist, 0, 2*MPPE_HIST_LEN*sizeof(u8));
-+    }
-+
-+    if (state->mppe) { /* generate initial session keys */
-+      mppe_change_key(state, 1);
-+    }
-+
-+    if (comp) { /* specific for compressor */
-+      state->nextflushed = 1;
-+    } else { /* specific for decompressor */
-+      state->mru = mru;
-+      state->flushexpected = 1;
-+    }
-+
-+    return 1;
-+}
-+
-+static int
-+mppe_comp_init(void *arg, unsigned char *options, int opt_len, int unit,
-+             int hdrlen, int debug)
-+{
-+    return mppe_init(arg, options, opt_len, unit, hdrlen, 0, debug, 1);
-+}
-+
-+
-+static int
-+mppe_decomp_init(void *arg, unsigned char *options, int opt_len, int unit,
-+               int hdrlen, int mru, int debug)
-+{
-+    return mppe_init(arg, options, opt_len, unit, hdrlen, mru, debug, 0);
-+}
-+
-+static void
-+mppe_comp_reset(void *arg)
-+{
-+    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
-+
-+    if (state->debug)
-+      printk(KERN_DEBUG "%s%d: resetting MPPC/MPPE compressor\n",
-+             __FUNCTION__, state->unit);
-+
-+    state->nextflushed = 1;
-+    if (state->mppe)
-+      arc4_setkey(state, state->session_key, state->keylen);
-+}
-+
-+static void
-+mppe_decomp_reset(void *arg)
-+{
-+    /* When MPPC/MPPE is in use, we shouldn't receive any CCP Reset-Ack.
-+       But when we receive such a packet, we just ignore it. */
-+    return;
-+}
-+
-+static void
-+mppe_stats(void *arg, struct compstat *stats)
-+{
-+    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
-+
-+    *stats = state->stats;
-+}
-+
-+/***************************/
-+/**** Compression stuff ****/
-+/***************************/
-+/* inserts 1 to 8 bits into the output buffer */
-+static inline void putbits8(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l)
-+{
-+    buf += *i;
-+    if (*l >= n) {
-+      *l = (*l) - n;
-+      val <<= *l;
-+      *buf = *buf | (val & 0xff);
-+      if (*l == 0) {
-+          *l = 8;
-+          (*i)++;
-+          *(++buf) = 0;
-+      }
-+    } else {
-+      (*i)++;
-+      *l = 8 - n + (*l);
-+      val <<= *l;
-+      *buf = *buf | ((val >> 8) & 0xff);
-+      *(++buf) = val & 0xff;
-+    }
-+}
-+
-+/* inserts 9 to 16 bits into the output buffer */
-+static inline void putbits16(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l)
-+{
-+    buf += *i;
-+    if (*l >= n - 8) {
-+      (*i)++;
-+      *l = 8 - n + (*l);
-+      val <<= *l;
-+      *buf = *buf | ((val >> 8) & 0xff);
-+      *(++buf) = val & 0xff;
-+      if (*l == 0) {
-+          *l = 8;
-+          (*i)++;
-+          *(++buf) = 0;
-+      }
-+    } else {
-+      (*i)++; (*i)++;
-+      *l = 16 - n + (*l);
-+      val <<= *l;
-+      *buf = *buf | ((val >> 16) & 0xff);
-+      *(++buf) = (val >> 8) & 0xff;
-+      *(++buf) = val & 0xff;
-+    }
-+}
-+
-+/* inserts 17 to 24 bits into the output buffer */
-+static inline void putbits24(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l)
-+{
-+    buf += *i;
-+    if (*l >= n - 16) {
-+      (*i)++; (*i)++;
-+      *l = 16 - n + (*l);
-+      val <<= *l;
-+      *buf = *buf | ((val >> 16) & 0xff);
-+      *(++buf) = (val >> 8) & 0xff;
-+      *(++buf) = val & 0xff;
-+      if (*l == 0) {
-+          *l = 8;
-+          (*i)++;
-+          *(++buf) = 0;
-+      }
-+    } else {
-+      (*i)++; (*i)++; (*i)++;
-+      *l = 24 - n + (*l);
-+      val <<= *l;
-+      *buf = *buf | ((val >> 24) & 0xff);
-+      *(++buf) = (val >> 16) & 0xff;
-+      *(++buf) = (val >> 8) & 0xff;
-+      *(++buf) = val & 0xff;
-+    }
-+}
-+
-+static int
-+mppc_compress(struct ppp_mppe_state *state, unsigned char *ibuf,
-+            unsigned char *obuf, int isize, int osize)
-+{
-+    u32 olen, off, len, idx, i, l;
-+    u8 *hist, *sbuf, *p, *q, *r, *s;
-+
-+    /*  
-+      At this point, to avoid possible buffer overflow caused by packet
-+      expansion during/after compression,  we should make sure that
-+      osize >= (((isize*9)/8)+1)+2, but we don't do that because in
-+      ppp_generic.c we simply allocate bigger obuf.
-+
-+      Maximum MPPC packet expansion is 12.5%. This is the worst case when
-+      all octets in the input buffer are >= 0x80 and we cannot find any
-+      repeated tokens. Additionally we have to reserve 2 bytes for MPPE/MPPC
-+      status bits and coherency counter.
-+    */
-+
-+    hist = state->hist + MPPE_HIST_LEN;
-+    /* check if there is enough room at the end of the history */
-+    if (state->histptr + isize >= 2*MPPE_HIST_LEN) {
-+      state->bits |= MPPE_BIT_RESET;
-+      state->histptr = MPPE_HIST_LEN;
-+      memcpy(state->hist, hist, MPPE_HIST_LEN);
-+    }
-+    /* add packet to the history; isize must be <= MPPE_HIST_LEN */
-+    sbuf = state->hist + state->histptr;
-+    memcpy(sbuf, ibuf, isize);
-+    state->histptr += isize;
-+
-+    /* compress data */
-+    r = sbuf + isize;
-+    *obuf = olen = i = 0;
-+    l = 8;
-+    while (i < isize - 2) {
-+      s = q = sbuf + i;
-+      idx = ((40543*((((s[0]<<4)^s[1])<<4)^s[2]))>>4) & 0x1fff;
-+      p = hist + state->hash[idx];
-+      state->hash[idx] = (u16) (s - hist);
-+      off = s - p;
-+      if (off > MPPE_HIST_LEN - 1 || off < 1 || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++) {
-+          /* no match found; encode literal byte */
-+          if (ibuf[i] < 0x80) {               /* literal byte < 0x80 */
-+              putbits8(obuf, (u32) ibuf[i], 8, &olen, &l);
-+          } else {                            /* literal byte >= 0x80 */
-+              putbits16(obuf, (u32) (0x100|(ibuf[i]&0x7f)), 9, &olen, &l);
-+          }
-+          ++i;
-+          continue;
-+      }
-+      if (r - q >= 64) {
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
-+          *p++ != *s++;
-+          if (s - q == 64) {
-+              p--; s--;
-+              while((*p++ == *s++) && (s < r) && (p < q));
-+          }
-+      } else {
-+          while((*p++ == *s++) && (s < r) && (p < q));
-+      }
-+      len = s - q - 1;
-+      i += len;
-+
-+      /* at least 3 character match found; code data */
-+      /* encode offset */
-+      if (off < 64) {                 /* 10-bit offset; 0 <= offset < 64 */
-+          putbits16(obuf, 0x3c0|off, 10, &olen, &l);
-+      } else if (off < 320) {         /* 12-bit offset; 64 <= offset < 320 */
-+          putbits16(obuf, 0xe00|(off-64), 12, &olen, &l);
-+      } else if (off < 8192) {        /* 16-bit offset; 320 <= offset < 8192 */
-+          putbits16(obuf, 0xc000|(off-320), 16, &olen, &l);
-+      } else {
-+          /* This shouldn't happen; we return 0 what means "packet expands",
-+          and we send packet uncompressed. */
-+          if (state->debug)
-+              printk(KERN_DEBUG "%s%d: wrong offset value: %d\n",
-+                     __FUNCTION__, state->unit, off);
-+          return 0;
-+      }
-+      /* encode length of match */
-+      if (len < 4) {                  /* length = 3 */
-+          putbits8(obuf, 0, 1, &olen, &l);
-+      } else if (len < 8) {           /* 4 <= length < 8 */
-+          putbits8(obuf, 0x08|(len&0x03), 4, &olen, &l);
-+      } else if (len < 16) {          /* 8 <= length < 16 */
-+          putbits8(obuf, 0x30|(len&0x07), 6, &olen, &l);
-+      } else if (len < 32) {          /* 16 <= length < 32 */
-+          putbits8(obuf, 0xe0|(len&0x0f), 8, &olen, &l);
-+      } else if (len < 64) {          /* 32 <= length < 64 */
-+          putbits16(obuf, 0x3c0|(len&0x1f), 10, &olen, &l);
-+      } else if (len < 128) {         /* 64 <= length < 128 */
-+          putbits16(obuf, 0xf80|(len&0x3f), 12, &olen, &l);
-+      } else if (len < 256) {         /* 128 <= length < 256 */
-+          putbits16(obuf, 0x3f00|(len&0x7f), 14, &olen, &l);
-+      } else if (len < 512) {         /* 256 <= length < 512 */
-+          putbits16(obuf, 0xfe00|(len&0xff), 16, &olen, &l);
-+      } else if (len < 1024) {        /* 512 <= length < 1024 */
-+          putbits24(obuf, 0x3fc00|(len&0x1ff), 18, &olen, &l);
-+      } else if (len < 2048) {        /* 1024 <= length < 2048 */
-+          putbits24(obuf, 0xff800|(len&0x3ff), 20, &olen, &l);
-+      } else if (len < 4096) {        /* 2048 <= length < 4096 */
-+          putbits24(obuf, 0x3ff000|(len&0x7ff), 22, &olen, &l);
-+      } else if (len < 8192) {        /* 4096 <= length < 8192 */
-+          putbits24(obuf, 0xffe000|(len&0xfff), 24, &olen, &l);
-+      } else {
-+          /* This shouldn't happen; we return 0 what means "packet expands",
-+          and send packet uncompressed. */
-+          if (state->debug)
-+              printk(KERN_DEBUG "%s%d: wrong length of match value: %d\n",
-+                     __FUNCTION__, state->unit, len);
-+          return 0;
-+      }
-+    }
-+
-+    /* Add remaining octets to the output */
-+    while(isize - i > 0) {
-+      if (ibuf[i] < 0x80) {   /* literal byte < 0x80 */
-+          putbits8(obuf, (u32) ibuf[i++], 8, &olen, &l);
-+      } else {                /* literal byte >= 0x80 */
-+          putbits16(obuf, (u32) (0x100|(ibuf[i++]&0x7f)), 9, &olen, &l);
-+      }
-+    }
-+    /* Reset unused bits of the last output octet */
-+    if ((l != 0) && (l != 8)) {
-+      putbits8(obuf, 0, l, &olen, &l);
-+    }
-+
-+    return (int) olen;
-+}
-+
-+int
-+mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
-+            int isize, int osize)
-+{
-+    struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
-+    int proto, olen, complen, off;
-+    unsigned char *wptr;
-+
-+    /* Check that the protocol is in the range we handle. */
-+    proto = PPP_PROTOCOL(ibuf);
-+    if (proto < 0x0021 || proto > 0x00fa)
-+      return 0;
-+
-+    wptr = obuf;
-+    /* Copy over the PPP header */
-+    wptr[0] = PPP_ADDRESS(ibuf);
-+    wptr[1] = PPP_CONTROL(ibuf);
-+    wptr[2] = PPP_COMP >> 8;
-+    wptr[3] = PPP_COMP;
-+    wptr += PPP_HDRLEN + (MPPE_OVHD / 2); /* Leave two octets for MPPE/MPPC bits */
-+
-+    /* 
-+     * In ver. 0.99 protocol field was compressed. Deflate and BSD compress
-+     * do PFC before actual compression, RCF2118 and RFC3078 are not precise
-+     * on this topic so I decided to do PFC. Unfortunately this change caused
-+     * incompatibility with older/other MPPE/MPPC modules. I have received
-+     * a lot of complaints from unexperienced users so I have decided to revert
-+     * to previous state, i.e. the protocol field is sent uncompressed now.
-+     * Although this may be changed in the future.
-+     *
-+     * Receiving side (mppe_decompress()) still accepts packets with compressed
-+     * and uncompressed protocol field so you shouldn't get "Unsupported protocol
-+     * 0x2145 received" messages anymore.
-+     */
-+    //off = (proto > 0xff) ? 2 : 3; /* PFC - skip first protocol byte if 0 */
-+    off = 2;
-+
-+    ibuf += off;
-+
-+    mppe_increase_ccount(state);
-+
-+    if (state->nextflushed) {
-+      state->bits |= MPPE_BIT_FLUSHED;
-+      state->nextflushed = 0;
-+      if (state->mppe && !state->stateless) {
-+          /*
-+           * If this is the flag packet, the key has been already changed in
-+           * mppe_increase_ccount() so we dont't do it once again.
-+           */
-+          if ((state->ccount & 0xff) != 0xff) {
-+              arc4_setkey(state, state->session_key, state->keylen);
-+          }
-+      }
-+      if (state->mppc) { /* reset history */
-+          state->bits |= MPPE_BIT_RESET;
-+          state->histptr = MPPE_HIST_LEN;
-+          memset(state->hist + MPPE_HIST_LEN, 0, MPPE_HIST_LEN*sizeof(u8));
-+      }
-+    }
-+
-+    if (state->mppc && !state->mppe) { /* Do only compression */
-+      complen = mppc_compress(state, ibuf, wptr, isize - off,
-+                              osize - PPP_HDRLEN - (MPPE_OVHD / 2));
-+      /*
-+       * TODO: Implement an heuristics to handle packet expansion in a smart
-+       * way. Now, when a packet expands, we send it as uncompressed and
-+       * when next packet is sent we have to reset compressor's history.
-+       * Maybe it would be better to send such packet as compressed in order
-+       * to keep history's continuity.
-+       */
-+      if ((complen > isize) || (complen > osize - PPP_HDRLEN) ||
-+          (complen == 0)) {
-+          /* packet expands */
-+          state->nextflushed = 1;
-+          memcpy(wptr, ibuf, isize - off);
-+          olen = isize - (off - 2) + MPPE_OVHD;
-+          (state->stats).inc_bytes += olen;
-+          (state->stats).inc_packets++;
-+      } else {
-+          state->bits |= MPPE_BIT_COMP;
-+          olen = complen + PPP_HDRLEN + (MPPE_OVHD / 2);
-+          (state->stats).comp_bytes += olen;
-+          (state->stats).comp_packets++;
-+      }
-+    } else { /* Do encryption with or without compression */
-+      state->bits |= MPPE_BIT_ENCRYPTED;
-+      if (!state->mppc && state->mppe) { /* Do only encryption */
-+          /* read from ibuf, write to wptr, adjust for PPP_HDRLEN */
-+          arc4_encrypt(state, ibuf, isize - off, wptr);
-+          olen = isize - (off - 2) + MPPE_OVHD;
-+          (state->stats).inc_bytes += olen;
-+          (state->stats).inc_packets++;
-+      } else { /* Do compression and then encryption - RFC3078 */
-+          complen = mppc_compress(state, ibuf, wptr, isize - off,
-+                                  osize - PPP_HDRLEN - (MPPE_OVHD / 2));
-+          /*
-+           * TODO: Implement an heuristics to handle packet expansion in a smart
-+           * way. Now, when a packet expands, we send it as uncompressed and
-+           * when next packet is sent we have to reset compressor's history.
-+           * Maybe it would be good to send such packet as compressed in order
-+           * to keep history's continuity.
-+           */
-+          if ((complen > isize) || (complen > osize - PPP_HDRLEN) ||
-+              (complen == 0)) {
-+              /* packet expands */
-+              state->nextflushed = 1;
-+              arc4_encrypt(state, ibuf, isize - off, wptr);
-+              olen = isize - (off - 2) + MPPE_OVHD;
-+              (state->stats).inc_bytes += olen;
-+              (state->stats).inc_packets++;
-+          } else {
-+              state->bits |= MPPE_BIT_COMP;
-+              /* Hack warning !!! RC4 implementation which we use does
-+                 encryption "in place" - it means that input and output
-+                 buffers can be *the same* memory area. Therefore we don't
-+                 need to use a temporary buffer. But be careful - other
-+                 implementations don't have to be so nice.
-+                 I used to use ibuf as temporary buffer here, but it led
-+                 packet sniffers into error. Thanks to Wilfried Weissmann
-+                 for pointing that. */
-+              arc4_encrypt(state, wptr, complen, wptr);
-+              olen = complen + PPP_HDRLEN + (MPPE_OVHD / 2);
-+              (state->stats).comp_bytes += olen;
-+              (state->stats).comp_packets++;
-+          }
-+      }
-+    }
-+
-+    /* write status bits and coherency counter into the output buffer */
-+    wptr = obuf + PPP_HDRLEN;
-+    wptr[0] = MPPE_CTRLHI(state);
-+    wptr[1] = MPPE_CTRLLO(state);
-+
-+    state->bits = 0;
-+
-+    (state->stats).unc_bytes += isize;
-+    (state->stats).unc_packets++;
-+
-+    return olen;
-+}
-+
-+/***************************/
-+/*** Decompression stuff ***/
-+/***************************/
-+static inline u32 getbits(const u8 *buf, const u32 n, u32 *i, u32 *l)
-+{
-+    static const u32 m[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
-+    u32 res, ol;
-+
-+    ol = *l;
-+    if (*l >= n) {
-+      *l = (*l) - n;
-+      res = (buf[*i] & m[ol]) >> (*l);
-+      if (*l == 0) {
-+          *l = 8;
-+          (*i)++;
-+      }
-+    } else {
-+      *l = 8 - n + (*l);
-+      res = (buf[(*i)++] & m[ol]) << 8;
-+      res = (res | buf[*i]) >> (*l);
-+    }
-+
-+    return res;
-+}
-+
-+static inline u32 getbyte(const u8 *buf, const u32 i, const u32 l)
-+{
-+    if (l == 8) {
-+      return buf[i];
-+    } else {
-+      return (((buf[i] << 8) | buf[i+1]) >> l) & 0xff;
-+    }
-+}
-+
-+static inline void lamecopy(u8 *dst, u8 *src, u32 len)
-+{
-+    while (len--)
-+      *dst++ = *src++;
-+}
-+
-+static int
-+mppc_decompress(struct ppp_mppe_state *state, unsigned char *ibuf,
-+              unsigned char *obuf, int isize, int osize)
-+{
-+    u32 olen, off, len, bits, val, sig, i, l;
-+    u8 *history, *s;
-+
-+    history = state->hist + state->histptr;
-+    olen = len = i = 0;
-+    l = 8;
-+    bits = isize * 8;
-+    while (bits >= 8) {
-+      val = getbyte(ibuf, i++, l);
-+      if (val < 0x80) {               /* literal byte < 0x80 */
-+          if (state->histptr < 2*MPPE_HIST_LEN) {
-+              /* copy uncompressed byte to the history */
-+              (state->hist)[(state->histptr)++] = (u8) val;
-+          } else {
-+              /* buffer overflow; drop packet */
-+              if (state->debug)
-+                  printk(KERN_ERR "%s%d: trying to write outside history "
-+                         "buffer\n", __FUNCTION__, state->unit);
-+              return DECOMP_ERROR;
-+          }
-+          olen++;
-+          bits -= 8;
-+          continue;
-+      }
-+
-+      sig = val & 0xc0;
-+      if (sig == 0x80) {              /* literal byte >= 0x80 */
-+          if (state->histptr < 2*MPPE_HIST_LEN) {
-+              /* copy uncompressed byte to the history */
-+              (state->hist)[(state->histptr)++] = 
-+                  (u8) (0x80|((val&0x3f)<<1)|getbits(ibuf, 1 , &i ,&l));
-+          } else {
-+              /* buffer overflow; drop packet */
-+              if (state->debug)
-+                  printk(KERN_ERR "%s%d: trying to write outside history "
-+                         "buffer\n", __FUNCTION__, state->unit);
-+              return DECOMP_ERROR;
-+          }
-+          olen++;
-+          bits -= 9;
-+          continue;
-+      }
-+
-+      /* Not a literal byte so it must be an (offset,length) pair */
-+      /* decode offset */
-+      sig = val & 0xf0;
-+      if (sig == 0xf0) {              /* 10-bit offset; 0 <= offset < 64 */
-+          off = (((val&0x0f)<<2)|getbits(ibuf, 2 , &i ,&l));
-+          bits -= 10;
-+      } else {
-+          if (sig == 0xe0) {          /* 12-bit offset; 64 <= offset < 320 */
-+              off = ((((val&0x0f)<<4)|getbits(ibuf, 4 , &i ,&l))+64);
-+              bits -= 12;
-+          } else {
-+              if ((sig&0xe0) == 0xc0) {/* 16-bit offset; 320 <= offset < 8192 */
-+                  off = ((((val&0x1f)<<8)|getbyte(ibuf, i++, l))+320);
-+                  bits -= 16;
-+                  if (off > MPPE_HIST_LEN - 1) {
-+                      if (state->debug)
-+                          printk(KERN_DEBUG "%s%d: too big offset value: %d\n",
-+                                 __FUNCTION__, state->unit, off);
-+                      return DECOMP_ERROR;
-+                  }
-+              } else {                /* this shouldn't happen */
-+                  if (state->debug)
-+                      printk(KERN_DEBUG "%s%d: cannot decode offset value\n",
-+                             __FUNCTION__, state->unit);
-+                  return DECOMP_ERROR;
-+              }
-+          }
-+      }
-+      /* decode length of match */
-+      val = getbyte(ibuf, i, l);
-+      if ((val & 0x80) == 0x00) {                     /* len = 3 */
-+          len = 3;
-+          bits--;
-+          getbits(ibuf, 1 , &i ,&l);
-+      } else if ((val & 0xc0) == 0x80) {              /* 4 <= len < 8 */
-+          len = 0x04 | ((val>>4) & 0x03);
-+          bits -= 4;
-+          getbits(ibuf, 4 , &i ,&l);
-+      } else if ((val & 0xe0) == 0xc0) {              /* 8 <= len < 16 */
-+          len = 0x08 | ((val>>2) & 0x07);
-+          bits -= 6;
-+          getbits(ibuf, 6 , &i ,&l);
-+      } else if ((val & 0xf0) == 0xe0) {              /* 16 <= len < 32 */
-+          len = 0x10 | (val & 0x0f);
-+          bits -= 8;
-+          i++;
-+      } else {
-+          bits -= 8;
-+          val = (val << 8) | getbyte(ibuf, ++i, l);
-+          if ((val & 0xf800) == 0xf000) {             /* 32 <= len < 64 */
-+              len = 0x0020 | ((val >> 6) & 0x001f);
-+              bits -= 2;
-+              getbits(ibuf, 2 , &i ,&l);
-+          } else if ((val & 0xfc00) == 0xf800) {      /* 64 <= len < 128 */
-+              len = 0x0040 | ((val >> 4) & 0x003f);
-+              bits -= 4;
-+              getbits(ibuf, 4 , &i ,&l);
-+          } else if ((val & 0xfe00) == 0xfc00) {      /* 128 <= len < 256 */
-+              len = 0x0080 | ((val >> 2) & 0x007f);
-+              bits -= 6;
-+              getbits(ibuf, 6 , &i ,&l);
-+          } else if ((val & 0xff00) == 0xfe00) {      /* 256 <= len < 512 */
-+              len = 0x0100 | (val & 0x00ff);
-+              bits -= 8;
-+              i++;
-+          } else {
-+              bits -= 8;
-+              val = (val << 8) | getbyte(ibuf, ++i, l);
-+              if ((val & 0xff8000) == 0xff0000) {     /* 512 <= len < 1024 */
-+                  len = 0x000200 | ((val >> 6) & 0x0001ff);
-+                  bits -= 2;
-+                  getbits(ibuf, 2 , &i ,&l);
-+              } else if ((val & 0xffc000) == 0xff8000) {/* 1024 <= len < 2048 */
-+                  len = 0x000400 | ((val >> 4) & 0x0003ff);
-+                  bits -= 4;
-+                  getbits(ibuf, 4 , &i ,&l);
-+              } else if ((val & 0xffe000) == 0xffc000) {/* 2048 <= len < 4096 */
-+                  len = 0x000800 | ((val >> 2) & 0x0007ff);
-+                  bits -= 6;
-+                  getbits(ibuf, 6 , &i ,&l);
-+              } else if ((val & 0xfff000) == 0xffe000) {/* 4096 <= len < 8192 */
-+                  len = 0x001000 | (val & 0x000fff);
-+                  bits -= 8;
-+                  i++;
-+              } else {                                /* this shouldn't happen */
-+                  if (state->debug)
-+                      printk(KERN_DEBUG "%s%d: wrong length code: 0x%X\n",
-+                             __FUNCTION__, state->unit, val);
-+                  return DECOMP_ERROR;
-+              }
-+          }
-+      }
-+      s = state->hist + state->histptr;
-+      state->histptr += len;
-+      olen += len;
-+      if (state->histptr < 2*MPPE_HIST_LEN) {
-+          /* copy uncompressed bytes to the history */
-+
-+          /* In some cases len may be greater than off. It means that memory
-+           * areas pointed by s and s-off overlap. I had used memmove() here
-+           * because I thought that it acts as libc's version. Unfortunately,
-+           * I was wrong. :-) I got strange errors sometimes. Wilfried suggested
-+           * using of byte by byte copying here and strange errors disappeared.
-+           */
-+          lamecopy(s, s - off, len);
-+      } else {
-+          /* buffer overflow; drop packet */
-+          if (state->debug)
-+              printk(KERN_ERR "%s%d: trying to write outside history "
-+                     "buffer\n", __FUNCTION__, state->unit);
-+          return DECOMP_ERROR;
-+      }
-+    }
-+
-+    /* Do PFC decompression */
-+    len = olen;
-+    if ((history[0] & 0x01) != 0) {
-+      obuf[0] = 0;
-+      obuf++;
-+      len++;
-+    }
-+
-+    if (len <= osize) {
-+      /* copy uncompressed packet to the output buffer */
-+      memcpy(obuf, history, olen);
-+    } else {
-+      /* buffer overflow; drop packet */
-+      if (state->debug)
-+          printk(KERN_ERR "%s%d: too big uncompressed packet: %d\n",
-+                 __FUNCTION__, state->unit, len + (PPP_HDRLEN / 2));
-+      return DECOMP_ERROR;
-+    }
-+
-+    return (int) len;
-+}
-+
-+int
-+mppe_decompress(void *arg, unsigned char *ibuf, int isize,
-+              unsigned char *obuf, int osize)
-+{
-+    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
-+    int seq, bits, uncomplen;
-+
-+    if (isize <= PPP_HDRLEN + MPPE_OVHD) {
-+      if (state->debug) {
-+          printk(KERN_DEBUG "%s%d: short packet (len=%d)\n",  __FUNCTION__,
-+                 state->unit, isize);
-+      }
-+      return DECOMP_ERROR;
-+    }
-+
-+    /* Get coherency counter and control bits from input buffer */
-+    seq = MPPE_CCOUNT(ibuf);
-+    bits = MPPE_BITS(ibuf);
-+
-+    if (state->stateless) {
-+      /* RFC 3078, sec 8.1. */
-+      mppe_increase_ccount(state);
-+      if ((seq != state->ccount) && state->debug)
-+          printk(KERN_DEBUG "%s%d: bad sequence number: %d, expected: %d\n",
-+                 __FUNCTION__, state->unit, seq, state->ccount);
-+      while (seq != state->ccount)
-+          mppe_increase_ccount(state);
-+    } else {
-+      /* RFC 3078, sec 8.2. */
-+      if (state->flushexpected) { /* discard state */
-+          if ((bits & MPPE_BIT_FLUSHED)) { /* we received expected FLUSH bit */
-+              while (seq != state->ccount)
-+                  mppe_increase_ccount(state);
-+              state->flushexpected = 0;
-+          } else /* drop packet*/
-+              return DECOMP_ERROR;
-+      } else { /* normal state */
-+          mppe_increase_ccount(state);
-+          if (seq != state->ccount) {
-+              /* Packet loss detected, enter the discard state. */
-+              if (state->debug)
-+                  printk(KERN_DEBUG "%s%d: bad sequence number: %d, expected: %d\n",
-+                         __FUNCTION__, state->unit, seq, state->ccount);
-+              state->flushexpected = 1;
-+              return DECOMP_ERROR;
-+          }
-+      }
-+      if (state->mppe && (bits & MPPE_BIT_FLUSHED)) {
-+          arc4_setkey(state, state->session_key, state->keylen);
-+      }
-+    }
-+
-+    if (state->mppc && (bits & (MPPE_BIT_FLUSHED | MPPE_BIT_RESET))) {
-+      state->histptr = MPPE_HIST_LEN;
-+      if ((bits & MPPE_BIT_FLUSHED)) {
-+          memset(state->hist + MPPE_HIST_LEN, 0, MPPE_HIST_LEN*sizeof(u8));
-+      } else
-+          if ((bits & MPPE_BIT_RESET)) {
-+              memcpy(state->hist, state->hist + MPPE_HIST_LEN, MPPE_HIST_LEN);
-+          }
-+    }
-+
-+    /* Fill in the first part of the PPP header. The protocol field
-+       comes from the decompressed data. */
-+    obuf[0] = PPP_ADDRESS(ibuf);
-+    obuf[1] = PPP_CONTROL(ibuf);
-+    obuf += PPP_HDRLEN / 2;
-+
-+    if (state->mppe) { /* process encrypted packet */
-+      if ((bits & MPPE_BIT_ENCRYPTED)) {
-+          /* OK, packet encrypted, so decrypt it */
-+          if (state->mppc && (bits & MPPE_BIT_COMP)) {
-+              /* Hack warning !!! RC4 implementation which we use does
-+                 decryption "in place" - it means that input and output
-+                 buffers can be *the same* memory area. Therefore we don't
-+                 need to use a temporary buffer. But be careful - other
-+                 implementations don't have to be so nice. */
-+              arc4_decrypt(state, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2), isize -
-+                           PPP_HDRLEN - (MPPE_OVHD / 2), ibuf + PPP_HDRLEN +
-+                           (MPPE_OVHD / 2));
-+              uncomplen = mppc_decompress(state, ibuf + PPP_HDRLEN +
-+                                          (MPPE_OVHD / 2), obuf, isize -
-+                                          PPP_HDRLEN - (MPPE_OVHD / 2),
-+                                          osize - (PPP_HDRLEN / 2));
-+              if (uncomplen == DECOMP_ERROR) {
-+                  state->flushexpected = 1;
-+                  return DECOMP_ERROR;
-+              }
-+              uncomplen += PPP_HDRLEN / 2;
-+              (state->stats).comp_bytes += isize;
-+              (state->stats).comp_packets++;
-+          } else {
-+              uncomplen = isize - MPPE_OVHD;
-+              /* Decrypt the first byte in order to check if it is
-+                 compressed or uncompressed protocol field */
-+              arc4_decrypt(state, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2), 1, obuf);
-+              /* Do PFC decompression */
-+              if ((obuf[0] & 0x01) != 0) {
-+                  obuf[1] = obuf[0];
-+                  obuf[0] = 0;
-+                  obuf++;
-+                  uncomplen++;
-+              }
-+              /* And finally, decrypt the rest of the frame. */
-+              arc4_decrypt(state, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2) + 1,
-+                           isize - PPP_HDRLEN - (MPPE_OVHD / 2) - 1, obuf + 1);
-+              (state->stats).inc_bytes += isize;
-+              (state->stats).inc_packets++;
-+          }
-+      } else { /* this shouldn't happen */
-+          if (state->debug)
-+              printk(KERN_ERR "%s%d: encryption negotiated but not an "
-+                     "encrypted packet received\n", __FUNCTION__, state->unit);
-+          mppe_change_key(state, 0);
-+          state->flushexpected = 1;
-+          return DECOMP_ERROR;
-+      }
-+    } else {
-+      if (state->mppc) { /* no MPPE, only MPPC */
-+          if ((bits & MPPE_BIT_COMP)) {
-+              uncomplen = mppc_decompress(state, ibuf + PPP_HDRLEN +
-+                                          (MPPE_OVHD / 2), obuf, isize -
-+                                          PPP_HDRLEN - (MPPE_OVHD / 2),
-+                                          osize - (PPP_HDRLEN / 2));
-+              if (uncomplen == DECOMP_ERROR) {
-+                  state->flushexpected = 1;
-+                  return DECOMP_ERROR;
-+              }
-+              uncomplen += PPP_HDRLEN / 2;
-+              (state->stats).comp_bytes += isize;
-+              (state->stats).comp_packets++;
-+          } else {
-+              memcpy(obuf, ibuf + PPP_HDRLEN + (MPPE_OVHD / 2), isize -
-+                     PPP_HDRLEN - (MPPE_OVHD / 2));
-+              uncomplen = isize - MPPE_OVHD;
-+              (state->stats).inc_bytes += isize;
-+              (state->stats).inc_packets++;
-+          }
-+      } else { /* this shouldn't happen */
-+          if (state->debug)
-+              printk(KERN_ERR "%s%d: error - not an  MPPC or MPPE frame "
-+                     "received\n", __FUNCTION__, state->unit);
-+          state->flushexpected = 1;
-+          return DECOMP_ERROR;
-+      }
-+    }
-+
-+    (state->stats).unc_bytes += uncomplen;
-+    (state->stats).unc_packets++;
-+
-+    return uncomplen;
-+}
-+
-+
-+/************************************************************
-+ * Module interface table
-+ ************************************************************/
-+
-+/* These are in ppp_generic.c */
-+extern int  ppp_register_compressor   (struct compressor *cp);
-+extern void ppp_unregister_compressor (struct compressor *cp);
-+
-+/*
-+ * Functions exported to ppp_generic.c.
-+ *
-+ * In case of MPPC/MPPE there is no need to process incompressible data
-+ * because such a data is sent in MPPC/MPPE frame. Therefore the (*incomp)
-+ * callback function isn't needed.
-+ */
-+struct compressor ppp_mppe = {
-+    .compress_proto = CI_MPPE,
-+    .comp_alloc =     mppe_comp_alloc,
-+    .comp_free =      mppe_comp_free,
-+    .comp_init =      mppe_comp_init,
-+    .comp_reset =     mppe_comp_reset,
-+    .compress =               mppe_compress,
-+    .comp_stat =      mppe_stats,
-+    .decomp_alloc =   mppe_decomp_alloc,
-+    .decomp_free =    mppe_comp_free,
-+    .decomp_init =    mppe_decomp_init,
-+    .decomp_reset =   mppe_decomp_reset,
-+    .decompress =     mppe_decompress,
-+    .incomp =         NULL,
-+    .decomp_stat =    mppe_stats,
-+    .owner =          THIS_MODULE
-+};
-+
-+/************************************************************
-+ * Module support routines
-+ ************************************************************/
-+
-+int __init mppe_module_init(void)
-+{
-+    int answer;
-+
-+    if (!(crypto_alg_available("arc4", 0) && crypto_alg_available("sha1", 0))) {
-+      printk(KERN_ERR "Kernel doesn't provide ARC4 and/or SHA1 algorithms "
-+             "required by MPPE/MPPC. Check CryptoAPI configuration.\n");
-+      return -ENODEV;
-+    }
-+
-+    /* Allocate space for SHAPad1, SHAPad2 and ... */
-+    sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL);
-+    if (sha_pad == NULL)
-+      return -ENOMEM;
-+    /* ... initialize them */
-+    memset(sha_pad->sha_pad1, 0x00, sizeof(sha_pad->sha_pad1));
-+    memset(sha_pad->sha_pad2, 0xf2, sizeof(sha_pad->sha_pad2));
-+
-+    answer = ppp_register_compressor(&ppp_mppe);
-+    if (answer == 0) {
-+      printk(KERN_INFO "MPPE/MPPC encryption/compression module registered\n");
-+    }
-+    return answer;
-+}
-+
-+void __exit mppe_module_cleanup(void)
-+{
-+    kfree(sha_pad);
-+    ppp_unregister_compressor(&ppp_mppe);
-+    printk(KERN_INFO "MPPE/MPPC encryption/compression module unregistered\n");
-+}
-+
-+module_init(mppe_module_init);
-+module_exit(mppe_module_cleanup);
-+
-+MODULE_AUTHOR("Jan Dubiec <jdx@slackware.pl>");
-+MODULE_DESCRIPTION("MPPE/MPPC encryption/compression module for Linux");
-+MODULE_VERSION("1.2");
-+MODULE_LICENSE("Dual BSD/GPL");
-+MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
-diff -ruN linux-2.6.12.orig/include/linux/ppp-comp.h linux-2.6.12/include/linux/ppp-comp.h
---- linux-2.6.12.orig/include/linux/ppp-comp.h 2004-12-24 22:33:47.000000000 +0100
-+++ linux-2.6.12/include/linux/ppp-comp.h      2005-06-28 20:07:01.000000000 +0200
-@@ -28,7 +28,7 @@
-  */
- /*
-- *  ==FILEVERSION 980319==
-+ *  ==FILEVERSION 20040509==
-  *
-  *  NOTE TO MAINTAINERS:
-  *     If you modify this file at all, please set the above date.
-@@ -80,7 +80,7 @@
-       /* Compress a packet */
-       int     (*compress) (void *state, unsigned char *rptr,
--                            unsigned char *obuf, int isize, int osize);
-+                           unsigned char *obuf, int isize, int osize);
-       /* Return compression statistics */
-       void    (*comp_stat) (void *state, struct compstat *stats);
-@@ -101,7 +101,7 @@
-       /* Decompress a packet. */
-       int     (*decompress) (void *state, unsigned char *ibuf, int isize,
--                              unsigned char *obuf, int osize);
-+                             unsigned char *obuf, int osize);
-       /* Update state for an incompressible packet received */
-       void    (*incomp) (void *state, unsigned char *ibuf, int icnt);
-@@ -191,6 +191,42 @@
- #define DEFLATE_CHK_SEQUENCE  0
- /*
-+ * Definitions for MPPE/MPPC.
-+ */
-+
-+#define CI_MPPE                       18      /* config option for MPPE */
-+#define CILEN_MPPE            6       /* length of config option */
-+
-+#define MPPE_OVHD             4       /* MPPE overhead */
-+#define MPPE_MAX_KEY_LEN      16      /* largest key length (128-bit) */
-+
-+#define MPPE_STATELESS          0x01  /* configuration bit H */
-+#define MPPE_40BIT              0x20  /* configuration bit L */
-+#define MPPE_56BIT              0x80  /* configuration bit M */
-+#define MPPE_128BIT             0x40  /* configuration bit S */
-+#define MPPE_MPPC               0x01  /* configuration bit C */
-+
-+/*
-+ * Definitions for Stac LZS.
-+ */
-+
-+#define CI_LZS                        17      /* config option for Stac LZS */
-+#define CILEN_LZS             5       /* length of config option */
-+
-+#define LZS_OVHD              4       /* max. LZS overhead */
-+#define LZS_HIST_LEN          2048    /* LZS history size */
-+#define LZS_MAX_CCOUNT                0x0FFF  /* max. coherency counter value */
-+
-+#define LZS_MODE_NONE         0
-+#define LZS_MODE_LCB          1
-+#define LZS_MODE_CRC          2
-+#define LZS_MODE_SEQ          3
-+#define LZS_MODE_EXT          4
-+
-+#define LZS_EXT_BIT_FLUSHED   0x80    /* bit A */
-+#define LZS_EXT_BIT_COMP      0x20    /* bit C */
-+
-+/*
-  * Definitions for other, as yet unsupported, compression methods.
-  */
diff --git a/openwrt/target/linux/linux-2.6/patches/generic/104-pf_ring.patch b/openwrt/target/linux/linux-2.6/patches/generic/104-pf_ring.patch
deleted file mode 100644 (file)
index 759fb2c..0000000
+++ /dev/null
@@ -1,5299 +0,0 @@
-diff --unified --recursive --new-file linux-2.6.12.5/include/linux/ring.h linux-2.6.12.5-1-686-smp-ring3/include/linux/ring.h
---- linux-2.6.12.5/include/linux/ring.h        1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-1-686-smp-ring3/include/linux/ring.h        2005-10-22 23:50:44.951445250 +0200
-@@ -0,0 +1,108 @@
-+/*
-+ * Definitions for packet ring
-+ *
-+ * 2004 - Luca Deri <deri@ntop.org>
-+ */
-+#ifndef __RING_H
-+#define __RING_H
-+
-+
-+#define INCLUDE_MAC_INFO
-+
-+#ifdef INCLUDE_MAC_INFO
-+#define SKB_DISPLACEMENT    14 /* Include MAC address information */
-+#else
-+#define SKB_DISPLACEMENT    0  /* Do NOT include MAC address information */
-+#endif
-+
-+#define RING_MAGIC
-+#define RING_MAGIC_VALUE      0x88
-+#define RING_FLOWSLOT_VERSION    5
-+#define RING_VERSION          "3.0"
-+
-+#define SO_ADD_TO_CLUSTER        99
-+#define SO_REMOVE_FROM_CLUSTER  100
-+#define SO_SET_REFLECTOR        101
-+
-+/* *********************************** */
-+
-+#ifndef HAVE_PCAP
-+struct pcap_pkthdr {
-+  struct timeval ts;    /* time stamp */
-+  u_int32_t caplen;     /* length of portion present */
-+  u_int32_t len;        /* length this packet (off wire) */
-+};
-+#endif
-+
-+/* *********************************** */
-+
-+enum cluster_type {
-+  cluster_per_flow = 0,
-+  cluster_round_robin
-+};
-+
-+/* *********************************** */
-+
-+#define RING_MIN_SLOT_SIZE    (60+sizeof(struct pcap_pkthdr))
-+#define RING_MAX_SLOT_SIZE    (1514+sizeof(struct pcap_pkthdr))
-+
-+/* *********************************** */
-+
-+typedef struct flowSlotInfo {
-+  u_int16_t version, sample_rate;
-+  u_int32_t tot_slots, slot_len, tot_mem;
-+  
-+  u_int64_t tot_pkts, tot_lost;
-+  u_int64_t tot_insert, tot_read;  
-+  u_int16_t insert_idx;
-+  u_int16_t remove_idx;
-+} FlowSlotInfo;
-+
-+/* *********************************** */
-+
-+typedef struct flowSlot {
-+#ifdef RING_MAGIC
-+  u_char     magic;      /* It must alwasy be zero */
-+#endif
-+  u_char     slot_state; /* 0=empty, 1=full   */
-+  u_char     bucket;     /* bucket[bucketLen] */
-+} FlowSlot;
-+
-+/* *********************************** */
-+
-+#ifdef __KERNEL__ 
-+
-+FlowSlotInfo* getRingPtr(void);
-+int allocateRing(char *deviceName, u_int numSlots,
-+               u_int bucketLen, u_int sampleRate);
-+unsigned int pollRing(struct file *fp, struct poll_table_struct * wait);
-+void deallocateRing(void);
-+
-+/* ************************* */
-+
-+typedef int (*handle_ring_skb)(struct sk_buff *skb,
-+                             u_char recv_packet, u_char real_skb);
-+extern handle_ring_skb get_skb_ring_handler(void);
-+extern void set_skb_ring_handler(handle_ring_skb the_handler);
-+extern void do_skb_ring_handler(struct sk_buff *skb,
-+                              u_char recv_packet, u_char real_skb);
-+
-+typedef int (*handle_ring_buffer)(struct net_device *dev, 
-+                                   char *data, int len);
-+extern handle_ring_buffer get_buffer_ring_handler(void);
-+extern void set_buffer_ring_handler(handle_ring_buffer the_handler);
-+extern int do_buffer_ring_handler(struct net_device *dev,
-+                                char *data, int len);
-+#endif /* __KERNEL__  */
-+
-+/* *********************************** */
-+
-+#define PF_RING          27      /* Packet Ring */
-+#define SOCK_RING        PF_RING
-+
-+/* ioctl() */
-+#define SIORINGPOLL      0x8888
-+
-+/* *********************************** */
-+
-+#endif /* __RING_H */
-diff --unified --recursive --new-file linux-2.6.12.5/net/Kconfig linux-2.6.12.5-1-686-smp-ring3/net/Kconfig
---- linux-2.6.12.5/net/Kconfig 2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-1-686-smp-ring3/net/Kconfig 2005-10-22 23:50:45.535481750 +0200
-@@ -72,6 +72,7 @@
-         Say Y unless you know what you are doing.
-+source "net/ring/Kconfig"
- config INET
-       bool "TCP/IP networking"
-       ---help---
-diff --unified --recursive --new-file linux-2.6.12.5/net/Makefile linux-2.6.12.5-1-686-smp-ring3/net/Makefile
---- linux-2.6.12.5/net/Makefile        2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-1-686-smp-ring3/net/Makefile        2005-10-22 23:50:45.491479000 +0200
-@@ -41,6 +41,7 @@
- obj-$(CONFIG_DECNET)          += decnet/
- obj-$(CONFIG_ECONET)          += econet/
- obj-$(CONFIG_VLAN_8021Q)      += 8021q/
-+obj-$(CONFIG_RING)            += ring/
- obj-$(CONFIG_IP_SCTP)         += sctp/
- ifeq ($(CONFIG_NET),y)
-diff --unified --recursive --new-file linux-2.6.12.5/net/Makefile.ORG linux-2.6.12.5-1-686-smp-ring3/net/Makefile.ORG
---- linux-2.6.12.5/net/Makefile.ORG    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-1-686-smp-ring3/net/Makefile.ORG    2005-10-22 23:50:45.483478500 +0200
-@@ -0,0 +1,48 @@
-+#
-+# Makefile for the linux networking.
-+#
-+# 2 Sep 2000, Christoph Hellwig <hch@infradead.org>
-+# Rewritten to use lists instead of if-statements.
-+#
-+
-+obj-y := nonet.o
-+
-+obj-$(CONFIG_NET)             := socket.o core/
-+
-+tmp-$(CONFIG_COMPAT)          := compat.o
-+obj-$(CONFIG_NET)             += $(tmp-y)
-+
-+# LLC has to be linked before the files in net/802/
-+obj-$(CONFIG_LLC)             += llc/
-+obj-$(CONFIG_NET)             += ethernet/ 802/ sched/ netlink/
-+obj-$(CONFIG_INET)            += ipv4/
-+obj-$(CONFIG_XFRM)            += xfrm/
-+obj-$(CONFIG_UNIX)            += unix/
-+ifneq ($(CONFIG_IPV6),)
-+obj-y                         += ipv6/
-+endif
-+obj-$(CONFIG_PACKET)          += packet/
-+obj-$(CONFIG_NET_KEY)         += key/
-+obj-$(CONFIG_NET_SCHED)               += sched/
-+obj-$(CONFIG_BRIDGE)          += bridge/
-+obj-$(CONFIG_IPX)             += ipx/
-+obj-$(CONFIG_ATALK)           += appletalk/
-+obj-$(CONFIG_WAN_ROUTER)      += wanrouter/
-+obj-$(CONFIG_X25)             += x25/
-+obj-$(CONFIG_LAPB)            += lapb/
-+obj-$(CONFIG_NETROM)          += netrom/
-+obj-$(CONFIG_ROSE)            += rose/
-+obj-$(CONFIG_AX25)            += ax25/
-+obj-$(CONFIG_IRDA)            += irda/
-+obj-$(CONFIG_BT)              += bluetooth/
-+obj-$(CONFIG_SUNRPC)          += sunrpc/
-+obj-$(CONFIG_RXRPC)           += rxrpc/
-+obj-$(CONFIG_ATM)             += atm/
-+obj-$(CONFIG_DECNET)          += decnet/
-+obj-$(CONFIG_ECONET)          += econet/
-+obj-$(CONFIG_VLAN_8021Q)      += 8021q/
-+obj-$(CONFIG_IP_SCTP)         += sctp/
-+
-+ifeq ($(CONFIG_NET),y)
-+obj-$(CONFIG_SYSCTL)          += sysctl_net.o
-+endif
-diff --unified --recursive --new-file linux-2.6.12.5/net/core/dev.c linux-2.6.12.5-1-686-smp-ring3/net/core/dev.c
---- linux-2.6.12.5/net/core/dev.c      2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-1-686-smp-ring3/net/core/dev.c      2005-10-22 23:50:45.479478250 +0200
-@@ -115,6 +115,56 @@
- #endif        /* CONFIG_NET_RADIO */
- #include <asm/current.h>
-+#if defined (CONFIG_RING) || defined(CONFIG_RING_MODULE)
-+
-+/* #define RING_DEBUG */
-+
-+#include <linux/ring.h>
-+#include <linux/version.h>
-+
-+static handle_ring_skb ring_handler = NULL;
-+
-+handle_ring_skb get_skb_ring_handler() { return(ring_handler); }
-+
-+void set_skb_ring_handler(handle_ring_skb the_handler) {
-+  ring_handler = the_handler;
-+}
-+
-+void do_skb_ring_handler(struct sk_buff *skb,
-+                       u_char recv_packet, u_char real_skb) {
-+  if(ring_handler)
-+    ring_handler(skb, recv_packet, real_skb);
-+}
-+
-+/* ******************* */
-+
-+static handle_ring_buffer buffer_ring_handler = NULL;
-+
-+handle_ring_buffer get_buffer_ring_handler() { return(buffer_ring_handler); }
-+
-+void set_buffer_ring_handler(handle_ring_buffer the_handler) {
-+  buffer_ring_handler = the_handler;
-+}
-+
-+int do_buffer_ring_handler(struct net_device *dev, char *data, int len) {
-+  if(buffer_ring_handler) {
-+    buffer_ring_handler(dev, data, len);
-+    return(1);
-+  } else 
-+    return(0);
-+}
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+EXPORT_SYMBOL(get_skb_ring_handler);
-+EXPORT_SYMBOL(set_skb_ring_handler);
-+EXPORT_SYMBOL(do_skb_ring_handler);
-+
-+EXPORT_SYMBOL(get_buffer_ring_handler);
-+EXPORT_SYMBOL(set_buffer_ring_handler);
-+EXPORT_SYMBOL(do_buffer_ring_handler);
-+#endif
-+
-+#endif
- /* This define, if set, will randomly drop a packet when congestion
-  * is more than moderate.  It helps fairness in the multi-interface
-  * case when one of them is a hog, but it kills performance for the
-@@ -1293,6 +1343,10 @@
-       skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS);
- #endif
-       if (q->enqueue) {
-+#if defined (CONFIG_RING) || defined(CONFIG_RING_MODULE)
-+      if(ring_handler) ring_handler(skb, 0, 1);
-+#endif /* CONFIG_RING */
-+
-               /* Grab device queue */
-               spin_lock(&dev->queue_lock);
-@@ -1509,6 +1563,13 @@
-       preempt_disable();
-       err = netif_rx(skb);
-+#if defined (CONFIG_RING) || defined(CONFIG_RING_MODULE)
-+      if(ring_handler && ring_handler(skb, 1, 1)) {
-+        /* The packet has been copied into a ring */
-+        return(NET_RX_SUCCESS);
-+      }
-+#endif /* CONFIG_RING */
-+
-       if (local_softirq_pending())
-               do_softirq();
-       preempt_enable();
-@@ -1655,6 +1716,13 @@
-       int ret = NET_RX_DROP;
-       unsigned short type;
-+#if defined (CONFIG_RING) || defined(CONFIG_RING_MODULE)
-+      if(ring_handler && ring_handler(skb, 1, 1)) {
-+        /* The packet has been copied into a ring */
-+        return(NET_RX_SUCCESS);
-+      }
-+#endif /* CONFIG_RING */
-+
-       /* if we've gotten here through NAPI, check netpoll */
-       if (skb->dev->poll && netpoll_rx(skb))
-               return NET_RX_DROP;
-diff --unified --recursive --new-file linux-2.6.12.5/net/core/dev.c.ORG linux-2.6.12.5-1-686-smp-ring3/net/core/dev.c.ORG
---- linux-2.6.12.5/net/core/dev.c.ORG  1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-1-686-smp-ring3/net/core/dev.c.ORG  2005-10-22 23:50:45.203461000 +0200
-@@ -0,0 +1,3385 @@
-+/*
-+ *    NET3    Protocol independent device support routines.
-+ *
-+ *            This program is free software; you can redistribute it and/or
-+ *            modify it under the terms of the GNU General Public License
-+ *            as published by the Free Software Foundation; either version
-+ *            2 of the License, or (at your option) any later version.
-+ *
-+ *    Derived from the non IP parts of dev.c 1.0.19
-+ *            Authors:        Ross Biro
-+ *                            Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
-+ *                            Mark Evans, <evansmp@uhura.aston.ac.uk>
-+ *
-+ *    Additional Authors:
-+ *            Florian la Roche <rzsfl@rz.uni-sb.de>
-+ *            Alan Cox <gw4pts@gw4pts.ampr.org>
-+ *            David Hinds <dahinds@users.sourceforge.net>
-+ *            Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
-+ *            Adam Sulmicki <adam@cfar.umd.edu>
-+ *              Pekka Riikonen <priikone@poesidon.pspt.fi>
-+ *
-+ *    Changes:
-+ *              D.J. Barrow     :       Fixed bug where dev->refcnt gets set
-+ *                                    to 2 if register_netdev gets called
-+ *                                    before net_dev_init & also removed a
-+ *                                    few lines of code in the process.
-+ *            Alan Cox        :       device private ioctl copies fields back.
-+ *            Alan Cox        :       Transmit queue code does relevant
-+ *                                    stunts to keep the queue safe.
-+ *            Alan Cox        :       Fixed double lock.
-+ *            Alan Cox        :       Fixed promisc NULL pointer trap
-+ *            ????????        :       Support the full private ioctl range
-+ *            Alan Cox        :       Moved ioctl permission check into
-+ *                                    drivers
-+ *            Tim Kordas      :       SIOCADDMULTI/SIOCDELMULTI
-+ *            Alan Cox        :       100 backlog just doesn't cut it when
-+ *                                    you start doing multicast video 8)
-+ *            Alan Cox        :       Rewrote net_bh and list manager.
-+ *            Alan Cox        :       Fix ETH_P_ALL echoback lengths.
-+ *            Alan Cox        :       Took out transmit every packet pass
-+ *                                    Saved a few bytes in the ioctl handler
-+ *            Alan Cox        :       Network driver sets packet type before
-+ *                                    calling netif_rx. Saves a function
-+ *                                    call a packet.
-+ *            Alan Cox        :       Hashed net_bh()
-+ *            Richard Kooijman:       Timestamp fixes.
-+ *            Alan Cox        :       Wrong field in SIOCGIFDSTADDR
-+ *            Alan Cox        :       Device lock protection.
-+ *            Alan Cox        :       Fixed nasty side effect of device close
-+ *                                    changes.
-+ *            Rudi Cilibrasi  :       Pass the right thing to
-+ *                                    set_mac_address()
-+ *            Dave Miller     :       32bit quantity for the device lock to
-+ *                                    make it work out on a Sparc.
-+ *            Bjorn Ekwall    :       Added KERNELD hack.
-+ *            Alan Cox        :       Cleaned up the backlog initialise.
-+ *            Craig Metz      :       SIOCGIFCONF fix if space for under
-+ *                                    1 device.
-+ *        Thomas Bogendoerfer :       Return ENODEV for dev_open, if there
-+ *                                    is no device open function.
-+ *            Andi Kleen      :       Fix error reporting for SIOCGIFCONF
-+ *        Michael Chastain    :       Fix signed/unsigned for SIOCGIFCONF
-+ *            Cyrus Durgin    :       Cleaned for KMOD
-+ *            Adam Sulmicki   :       Bug Fix : Network Device Unload
-+ *                                    A network device unload needs to purge
-+ *                                    the backlog queue.
-+ *    Paul Rusty Russell      :       SIOCSIFNAME
-+ *              Pekka Riikonen  :     Netdev boot-time settings code
-+ *              Andrew Morton   :       Make unregister_netdevice wait
-+ *                                    indefinitely on dev->refcnt
-+ *            J Hadi Salim    :       - Backlog queue sampling
-+ *                                    - netif_rx() feedback
-+ */
-+
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <linux/bitops.h>
-+#include <linux/config.h>
-+#include <linux/cpu.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/socket.h>
-+#include <linux/sockios.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/if_ether.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/notifier.h>
-+#include <linux/skbuff.h>
-+#include <net/sock.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/proc_fs.h>
-+#include <linux/seq_file.h>
-+#include <linux/stat.h>
-+#include <linux/if_bridge.h>
-+#include <linux/divert.h>
-+#include <net/dst.h>
-+#include <net/pkt_sched.h>
-+#include <net/checksum.h>
-+#include <linux/highmem.h>
-+#include <linux/init.h>
-+#include <linux/kmod.h>
-+#include <linux/module.h>
-+#include <linux/kallsyms.h>
-+#include <linux/netpoll.h>
-+#include <linux/rcupdate.h>
-+#include <linux/delay.h>
-+#ifdef CONFIG_NET_RADIO
-+#include <linux/wireless.h>           /* Note : will define WIRELESS_EXT */
-+#include <net/iw_handler.h>
-+#endif        /* CONFIG_NET_RADIO */
-+#include <asm/current.h>
-+
-+/* This define, if set, will randomly drop a packet when congestion
-+ * is more than moderate.  It helps fairness in the multi-interface
-+ * case when one of them is a hog, but it kills performance for the
-+ * single interface case so it is off now by default.
-+ */
-+#undef RAND_LIE
-+
-+/* Setting this will sample the queue lengths and thus congestion
-+ * via a timer instead of as each packet is received.
-+ */
-+#undef OFFLINE_SAMPLE
-+
-+/*
-+ *    The list of packet types we will receive (as opposed to discard)
-+ *    and the routines to invoke.
-+ *
-+ *    Why 16. Because with 16 the only overlap we get on a hash of the
-+ *    low nibble of the protocol value is RARP/SNAP/X.25.
-+ *
-+ *      NOTE:  That is no longer true with the addition of VLAN tags.  Not
-+ *             sure which should go first, but I bet it won't make much
-+ *             difference if we are running VLANs.  The good news is that
-+ *             this protocol won't be in the list unless compiled in, so
-+ *             the average user (w/out VLANs) will not be adversly affected.
-+ *             --BLG
-+ *
-+ *            0800    IP
-+ *            8100    802.1Q VLAN
-+ *            0001    802.3
-+ *            0002    AX.25
-+ *            0004    802.2
-+ *            8035    RARP
-+ *            0005    SNAP
-+ *            0805    X.25
-+ *            0806    ARP
-+ *            8137    IPX
-+ *            0009    Localtalk
-+ *            86DD    IPv6
-+ */
-+
-+static DEFINE_SPINLOCK(ptype_lock);
-+static struct list_head ptype_base[16];       /* 16 way hashed list */
-+static struct list_head ptype_all;            /* Taps */
-+
-+#ifdef OFFLINE_SAMPLE
-+static void sample_queue(unsigned long dummy);
-+static struct timer_list samp_timer = TIMER_INITIALIZER(sample_queue, 0, 0);
-+#endif
-+
-+/*
-+ * The @dev_base list is protected by @dev_base_lock and the rtln
-+ * semaphore.
-+ *
-+ * Pure readers hold dev_base_lock for reading.
-+ *
-+ * Writers must hold the rtnl semaphore while they loop through the
-+ * dev_base list, and hold dev_base_lock for writing when they do the
-+ * actual updates.  This allows pure readers to access the list even
-+ * while a writer is preparing to update it.
-+ *
-+ * To put it another way, dev_base_lock is held for writing only to
-+ * protect against pure readers; the rtnl semaphore provides the
-+ * protection against other writers.
-+ *
-+ * See, for example usages, register_netdevice() and
-+ * unregister_netdevice(), which must be called with the rtnl
-+ * semaphore held.
-+ */
-+struct net_device *dev_base;
-+static struct net_device **dev_tail = &dev_base;
-+DEFINE_RWLOCK(dev_base_lock);
-+
-+EXPORT_SYMBOL(dev_base);
-+EXPORT_SYMBOL(dev_base_lock);
-+
-+#define NETDEV_HASHBITS       8
-+static struct hlist_head dev_name_head[1<<NETDEV_HASHBITS];
-+static struct hlist_head dev_index_head[1<<NETDEV_HASHBITS];
-+
-+static inline struct hlist_head *dev_name_hash(const char *name)
-+{
-+      unsigned hash = full_name_hash(name, strnlen(name, IFNAMSIZ));
-+      return &dev_name_head[hash & ((1<<NETDEV_HASHBITS)-1)];
-+}
-+
-+static inline struct hlist_head *dev_index_hash(int ifindex)
-+{
-+      return &dev_index_head[ifindex & ((1<<NETDEV_HASHBITS)-1)];
-+}
-+
-+/*
-+ *    Our notifier list
-+ */
-+
-+static struct notifier_block *netdev_chain;
-+
-+/*
-+ *    Device drivers call our routines to queue packets here. We empty the
-+ *    queue in the local softnet handler.
-+ */
-+DEFINE_PER_CPU(struct softnet_data, softnet_data) = { 0, };
-+
-+#ifdef CONFIG_SYSFS
-+extern int netdev_sysfs_init(void);
-+extern int netdev_register_sysfs(struct net_device *);
-+extern void netdev_unregister_sysfs(struct net_device *);
-+#else
-+#define netdev_sysfs_init()           (0)
-+#define netdev_register_sysfs(dev)    (0)
-+#define       netdev_unregister_sysfs(dev)    do { } while(0)
-+#endif
-+
-+
-+/*******************************************************************************
-+
-+              Protocol management and registration routines
-+
-+*******************************************************************************/
-+
-+/*
-+ *    For efficiency
-+ */
-+
-+int netdev_nit;
-+
-+/*
-+ *    Add a protocol ID to the list. Now that the input handler is
-+ *    smarter we can dispense with all the messy stuff that used to be
-+ *    here.
-+ *
-+ *    BEWARE!!! Protocol handlers, mangling input packets,
-+ *    MUST BE last in hash buckets and checking protocol handlers
-+ *    MUST start from promiscuous ptype_all chain in net_bh.
-+ *    It is true now, do not change it.
-+ *    Explanation follows: if protocol handler, mangling packet, will
-+ *    be the first on list, it is not able to sense, that packet
-+ *    is cloned and should be copied-on-write, so that it will
-+ *    change it and subsequent readers will get broken packet.
-+ *                                                    --ANK (980803)
-+ */
-+
-+/**
-+ *    dev_add_pack - add packet handler
-+ *    @pt: packet type declaration
-+ *
-+ *    Add a protocol handler to the networking stack. The passed &packet_type
-+ *    is linked into kernel lists and may not be freed until it has been
-+ *    removed from the kernel lists.
-+ *
-+ *    This call does not sleep therefore it can not 
-+ *    guarantee all CPU's that are in middle of receiving packets
-+ *    will see the new packet type (until the next received packet).
-+ */
-+
-+void dev_add_pack(struct packet_type *pt)
-+{
-+      int hash;
-+
-+      spin_lock_bh(&ptype_lock);
-+      if (pt->type == htons(ETH_P_ALL)) {
-+              netdev_nit++;
-+              list_add_rcu(&pt->list, &ptype_all);
-+      } else {
-+              hash = ntohs(pt->type) & 15;
-+              list_add_rcu(&pt->list, &ptype_base[hash]);
-+      }
-+      spin_unlock_bh(&ptype_lock);
-+}
-+
-+extern void linkwatch_run_queue(void);
-+
-+
-+
-+/**
-+ *    __dev_remove_pack        - remove packet handler
-+ *    @pt: packet type declaration
-+ *
-+ *    Remove a protocol handler that was previously added to the kernel
-+ *    protocol handlers by dev_add_pack(). The passed &packet_type is removed
-+ *    from the kernel lists and can be freed or reused once this function
-+ *    returns. 
-+ *
-+ *      The packet type might still be in use by receivers
-+ *    and must not be freed until after all the CPU's have gone
-+ *    through a quiescent state.
-+ */
-+void __dev_remove_pack(struct packet_type *pt)
-+{
-+      struct list_head *head;
-+      struct packet_type *pt1;
-+
-+      spin_lock_bh(&ptype_lock);
-+
-+      if (pt->type == htons(ETH_P_ALL)) {
-+              netdev_nit--;
-+              head = &ptype_all;
-+      } else
-+              head = &ptype_base[ntohs(pt->type) & 15];
-+
-+      list_for_each_entry(pt1, head, list) {
-+              if (pt == pt1) {
-+                      list_del_rcu(&pt->list);
-+                      goto out;
-+              }
-+      }
-+
-+      printk(KERN_WARNING "dev_remove_pack: %p not found.\n", pt);
-+out:
-+      spin_unlock_bh(&ptype_lock);
-+}
-+/**
-+ *    dev_remove_pack  - remove packet handler
-+ *    @pt: packet type declaration
-+ *
-+ *    Remove a protocol handler that was previously added to the kernel
-+ *    protocol handlers by dev_add_pack(). The passed &packet_type is removed
-+ *    from the kernel lists and can be freed or reused once this function
-+ *    returns.
-+ *
-+ *    This call sleeps to guarantee that no CPU is looking at the packet
-+ *    type after return.
-+ */
-+void dev_remove_pack(struct packet_type *pt)
-+{
-+      __dev_remove_pack(pt);
-+      
-+      synchronize_net();
-+}
-+
-+/******************************************************************************
-+
-+                    Device Boot-time Settings Routines
-+
-+*******************************************************************************/
-+
-+/* Boot time configuration table */
-+static struct netdev_boot_setup dev_boot_setup[NETDEV_BOOT_SETUP_MAX];
-+
-+/**
-+ *    netdev_boot_setup_add   - add new setup entry
-+ *    @name: name of the device
-+ *    @map: configured settings for the device
-+ *
-+ *    Adds new setup entry to the dev_boot_setup list.  The function
-+ *    returns 0 on error and 1 on success.  This is a generic routine to
-+ *    all netdevices.
-+ */
-+static int netdev_boot_setup_add(char *name, struct ifmap *map)
-+{
-+      struct netdev_boot_setup *s;
-+      int i;
-+
-+      s = dev_boot_setup;
-+      for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
-+              if (s[i].name[0] == '\0' || s[i].name[0] == ' ') {
-+                      memset(s[i].name, 0, sizeof(s[i].name));
-+                      strcpy(s[i].name, name);
-+                      memcpy(&s[i].map, map, sizeof(s[i].map));
-+                      break;
-+              }
-+      }
-+
-+      return i >= NETDEV_BOOT_SETUP_MAX ? 0 : 1;
-+}
-+
-+/**
-+ *    netdev_boot_setup_check - check boot time settings
-+ *    @dev: the netdevice
-+ *
-+ *    Check boot time settings for the device.
-+ *    The found settings are set for the device to be used
-+ *    later in the device probing.
-+ *    Returns 0 if no settings found, 1 if they are.
-+ */
-+int netdev_boot_setup_check(struct net_device *dev)
-+{
-+      struct netdev_boot_setup *s = dev_boot_setup;
-+      int i;
-+
-+      for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
-+              if (s[i].name[0] != '\0' && s[i].name[0] != ' ' &&
-+                  !strncmp(dev->name, s[i].name, strlen(s[i].name))) {
-+                      dev->irq        = s[i].map.irq;
-+                      dev->base_addr  = s[i].map.base_addr;
-+                      dev->mem_start  = s[i].map.mem_start;
-+                      dev->mem_end    = s[i].map.mem_end;
-+                      return 1;
-+              }
-+      }
-+      return 0;
-+}
-+
-+
-+/**
-+ *    netdev_boot_base        - get address from boot time settings
-+ *    @prefix: prefix for network device
-+ *    @unit: id for network device
-+ *
-+ *    Check boot time settings for the base address of device.
-+ *    The found settings are set for the device to be used
-+ *    later in the device probing.
-+ *    Returns 0 if no settings found.
-+ */
-+unsigned long netdev_boot_base(const char *prefix, int unit)
-+{
-+      const struct netdev_boot_setup *s = dev_boot_setup;
-+      char name[IFNAMSIZ];
-+      int i;
-+
-+      sprintf(name, "%s%d", prefix, unit);
-+
-+      /*
-+       * If device already registered then return base of 1
-+       * to indicate not to probe for this interface
-+       */
-+      if (__dev_get_by_name(name))
-+              return 1;
-+
-+      for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++)
-+              if (!strcmp(name, s[i].name))
-+                      return s[i].map.base_addr;
-+      return 0;
-+}
-+
-+/*
-+ * Saves at boot time configured settings for any netdevice.
-+ */
-+int __init netdev_boot_setup(char *str)
-+{
-+      int ints[5];
-+      struct ifmap map;
-+
-+      str = get_options(str, ARRAY_SIZE(ints), ints);
-+      if (!str || !*str)
-+              return 0;
-+
-+      /* Save settings */
-+      memset(&map, 0, sizeof(map));
-+      if (ints[0] > 0)
-+              map.irq = ints[1];
-+      if (ints[0] > 1)
-+              map.base_addr = ints[2];
-+      if (ints[0] > 2)
-+              map.mem_start = ints[3];
-+      if (ints[0] > 3)
-+              map.mem_end = ints[4];
-+
-+      /* Add new entry to the list */
-+      return netdev_boot_setup_add(str, &map);
-+}
-+
-+__setup("netdev=", netdev_boot_setup);
-+
-+/*******************************************************************************
-+
-+                          Device Interface Subroutines
-+
-+*******************************************************************************/
-+
-+/**
-+ *    __dev_get_by_name       - find a device by its name
-+ *    @name: name to find
-+ *
-+ *    Find an interface by name. Must be called under RTNL semaphore
-+ *    or @dev_base_lock. If the name is found a pointer to the device
-+ *    is returned. If the name is not found then %NULL is returned. The
-+ *    reference counters are not incremented so the caller must be
-+ *    careful with locks.
-+ */
-+
-+struct net_device *__dev_get_by_name(const char *name)
-+{
-+      struct hlist_node *p;
-+
-+      hlist_for_each(p, dev_name_hash(name)) {
-+              struct net_device *dev
-+                      = hlist_entry(p, struct net_device, name_hlist);
-+              if (!strncmp(dev->name, name, IFNAMSIZ))
-+                      return dev;
-+      }
-+      return NULL;
-+}
-+
-+/**
-+ *    dev_get_by_name         - find a device by its name
-+ *    @name: name to find
-+ *
-+ *    Find an interface by name. This can be called from any
-+ *    context and does its own locking. The returned handle has
-+ *    the usage count incremented and the caller must use dev_put() to
-+ *    release it when it is no longer needed. %NULL is returned if no
-+ *    matching device is found.
-+ */
-+
-+struct net_device *dev_get_by_name(const char *name)
-+{
-+      struct net_device *dev;
-+
-+      read_lock(&dev_base_lock);
-+      dev = __dev_get_by_name(name);
-+      if (dev)
-+              dev_hold(dev);
-+      read_unlock(&dev_base_lock);
-+      return dev;
-+}
-+
-+/**
-+ *    __dev_get_by_index - find a device by its ifindex
-+ *    @ifindex: index of device
-+ *
-+ *    Search for an interface by index. Returns %NULL if the device
-+ *    is not found or a pointer to the device. The device has not
-+ *    had its reference counter increased so the caller must be careful
-+ *    about locking. The caller must hold either the RTNL semaphore
-+ *    or @dev_base_lock.
-+ */
-+
-+struct net_device *__dev_get_by_index(int ifindex)
-+{
-+      struct hlist_node *p;
-+
-+      hlist_for_each(p, dev_index_hash(ifindex)) {
-+              struct net_device *dev
-+                      = hlist_entry(p, struct net_device, index_hlist);
-+              if (dev->ifindex == ifindex)
-+                      return dev;
-+      }
-+      return NULL;
-+}
-+
-+
-+/**
-+ *    dev_get_by_index - find a device by its ifindex
-+ *    @ifindex: index of device
-+ *
-+ *    Search for an interface by index. Returns NULL if the device
-+ *    is not found or a pointer to the device. The device returned has
-+ *    had a reference added and the pointer is safe until the user calls
-+ *    dev_put to indicate they have finished with it.
-+ */
-+
-+struct net_device *dev_get_by_index(int ifindex)
-+{
-+      struct net_device *dev;
-+
-+      read_lock(&dev_base_lock);
-+      dev = __dev_get_by_index(ifindex);
-+      if (dev)
-+              dev_hold(dev);
-+      read_unlock(&dev_base_lock);
-+      return dev;
-+}
-+
-+/**
-+ *    dev_getbyhwaddr - find a device by its hardware address
-+ *    @type: media type of device
-+ *    @ha: hardware address
-+ *
-+ *    Search for an interface by MAC address. Returns NULL if the device
-+ *    is not found or a pointer to the device. The caller must hold the
-+ *    rtnl semaphore. The returned device has not had its ref count increased
-+ *    and the caller must therefore be careful about locking
-+ *
-+ *    BUGS:
-+ *    If the API was consistent this would be __dev_get_by_hwaddr
-+ */
-+
-+struct net_device *dev_getbyhwaddr(unsigned short type, char *ha)
-+{
-+      struct net_device *dev;
-+
-+      ASSERT_RTNL();
-+
-+      for (dev = dev_base; dev; dev = dev->next)
-+              if (dev->type == type &&
-+                  !memcmp(dev->dev_addr, ha, dev->addr_len))
-+                      break;
-+      return dev;
-+}
-+
-+struct net_device *dev_getfirstbyhwtype(unsigned short type)
-+{
-+      struct net_device *dev;
-+
-+      rtnl_lock();
-+      for (dev = dev_base; dev; dev = dev->next) {
-+              if (dev->type == type) {
-+                      dev_hold(dev);
-+                      break;
-+              }
-+      }
-+      rtnl_unlock();
-+      return dev;
-+}
-+
-+EXPORT_SYMBOL(dev_getfirstbyhwtype);
-+
-+/**
-+ *    dev_get_by_flags - find any device with given flags
-+ *    @if_flags: IFF_* values
-+ *    @mask: bitmask of bits in if_flags to check
-+ *
-+ *    Search for any interface with the given flags. Returns NULL if a device
-+ *    is not found or a pointer to the device. The device returned has 
-+ *    had a reference added and the pointer is safe until the user calls
-+ *    dev_put to indicate they have finished with it.
-+ */
-+
-+struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mask)
-+{
-+      struct net_device *dev;
-+
-+      read_lock(&dev_base_lock);
-+      for (dev = dev_base; dev != NULL; dev = dev->next) {
-+              if (((dev->flags ^ if_flags) & mask) == 0) {
-+                      dev_hold(dev);
-+                      break;
-+              }
-+      }
-+      read_unlock(&dev_base_lock);
-+      return dev;
-+}
-+
-+/**
-+ *    dev_valid_name - check if name is okay for network device
-+ *    @name: name string
-+ *
-+ *    Network device names need to be valid file names to
-+ *    to allow sysfs to work
-+ */
-+static int dev_valid_name(const char *name)
-+{
-+      return !(*name == '\0' 
-+               || !strcmp(name, ".")
-+               || !strcmp(name, "..")
-+               || strchr(name, '/'));
-+}
-+
-+/**
-+ *    dev_alloc_name - allocate a name for a device
-+ *    @dev: device
-+ *    @name: name format string
-+ *
-+ *    Passed a format string - eg "lt%d" it will try and find a suitable
-+ *    id. Not efficient for many devices, not called a lot. The caller
-+ *    must hold the dev_base or rtnl lock while allocating the name and
-+ *    adding the device in order to avoid duplicates. Returns the number
-+ *    of the unit assigned or a negative errno code.
-+ */
-+
-+int dev_alloc_name(struct net_device *dev, const char *name)
-+{
-+      int i = 0;
-+      char buf[IFNAMSIZ];
-+      const char *p;
-+      const int max_netdevices = 8*PAGE_SIZE;
-+      long *inuse;
-+      struct net_device *d;
-+
-+      p = strnchr(name, IFNAMSIZ-1, '%');
-+      if (p) {
-+              /*
-+               * Verify the string as this thing may have come from
-+               * the user.  There must be either one "%d" and no other "%"
-+               * characters.
-+               */
-+              if (p[1] != 'd' || strchr(p + 2, '%'))
-+                      return -EINVAL;
-+
-+              /* Use one page as a bit array of possible slots */
-+              inuse = (long *) get_zeroed_page(GFP_ATOMIC);
-+              if (!inuse)
-+                      return -ENOMEM;
-+
-+              for (d = dev_base; d; d = d->next) {
-+                      if (!sscanf(d->name, name, &i))
-+                              continue;
-+                      if (i < 0 || i >= max_netdevices)
-+                              continue;
-+
-+                      /*  avoid cases where sscanf is not exact inverse of printf */
-+                      snprintf(buf, sizeof(buf), name, i);
-+                      if (!strncmp(buf, d->name, IFNAMSIZ))
-+                              set_bit(i, inuse);
-+              }
-+
-+              i = find_first_zero_bit(inuse, max_netdevices);
-+              free_page((unsigned long) inuse);
-+      }
-+
-+      snprintf(buf, sizeof(buf), name, i);
-+      if (!__dev_get_by_name(buf)) {
-+              strlcpy(dev->name, buf, IFNAMSIZ);
-+              return i;
-+      }
-+
-+      /* It is possible to run out of possible slots
-+       * when the name is long and there isn't enough space left
-+       * for the digits, or if all bits are used.
-+       */
-+      return -ENFILE;
-+}
-+
-+
-+/**
-+ *    dev_change_name - change name of a device
-+ *    @dev: device
-+ *    @newname: name (or format string) must be at least IFNAMSIZ
-+ *
-+ *    Change name of a device, can pass format strings "eth%d".
-+ *    for wildcarding.
-+ */
-+int dev_change_name(struct net_device *dev, char *newname)
-+{
-+      int err = 0;
-+
-+      ASSERT_RTNL();
-+
-+      if (dev->flags & IFF_UP)
-+              return -EBUSY;
-+
-+      if (!dev_valid_name(newname))
-+              return -EINVAL;
-+
-+      if (strchr(newname, '%')) {
-+              err = dev_alloc_name(dev, newname);
-+              if (err < 0)
-+                      return err;
-+              strcpy(newname, dev->name);
-+      }
-+      else if (__dev_get_by_name(newname))
-+              return -EEXIST;
-+      else
-+              strlcpy(dev->name, newname, IFNAMSIZ);
-+
-+      err = class_device_rename(&dev->class_dev, dev->name);
-+      if (!err) {
-+              hlist_del(&dev->name_hlist);
-+              hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
-+              notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
-+      }
-+
-+      return err;
-+}
-+
-+/**
-+ *    netdev_features_change - device changes fatures
-+ *    @dev: device to cause notification
-+ *
-+ *    Called to indicate a device has changed features.
-+ */
-+void netdev_features_change(struct net_device *dev)
-+{
-+      notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
-+}
-+EXPORT_SYMBOL(netdev_features_change);
-+
-+/**
-+ *    netdev_state_change - device changes state
-+ *    @dev: device to cause notification
-+ *
-+ *    Called to indicate a device has changed state. This function calls
-+ *    the notifier chains for netdev_chain and sends a NEWLINK message
-+ *    to the routing socket.
-+ */
-+void netdev_state_change(struct net_device *dev)
-+{
-+      if (dev->flags & IFF_UP) {
-+              notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev);
-+              rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
-+      }
-+}
-+
-+/**
-+ *    dev_load        - load a network module
-+ *    @name: name of interface
-+ *
-+ *    If a network interface is not present and the process has suitable
-+ *    privileges this function loads the module. If module loading is not
-+ *    available in this kernel then it becomes a nop.
-+ */
-+
-+void dev_load(const char *name)
-+{
-+      struct net_device *dev;  
-+
-+      read_lock(&dev_base_lock);
-+      dev = __dev_get_by_name(name);
-+      read_unlock(&dev_base_lock);
-+
-+      if (!dev && capable(CAP_SYS_MODULE))
-+              request_module("%s", name);
-+}
-+
-+static int default_rebuild_header(struct sk_buff *skb)
-+{
-+      printk(KERN_DEBUG "%s: default_rebuild_header called -- BUG!\n",
-+             skb->dev ? skb->dev->name : "NULL!!!");
-+      kfree_skb(skb);
-+      return 1;
-+}
-+
-+
-+/**
-+ *    dev_open        - prepare an interface for use.
-+ *    @dev:   device to open
-+ *
-+ *    Takes a device from down to up state. The device's private open
-+ *    function is invoked and then the multicast lists are loaded. Finally
-+ *    the device is moved into the up state and a %NETDEV_UP message is
-+ *    sent to the netdev notifier chain.
-+ *
-+ *    Calling this function on an active interface is a nop. On a failure
-+ *    a negative errno code is returned.
-+ */
-+int dev_open(struct net_device *dev)
-+{
-+      int ret = 0;
-+
-+      /*
-+       *      Is it already up?
-+       */
-+
-+      if (dev->flags & IFF_UP)
-+              return 0;
-+
-+      /*
-+       *      Is it even present?
-+       */
-+      if (!netif_device_present(dev))
-+              return -ENODEV;
-+
-+      /*
-+       *      Call device private open method
-+       */
-+      set_bit(__LINK_STATE_START, &dev->state);
-+      if (dev->open) {
-+              ret = dev->open(dev);
-+              if (ret)
-+                      clear_bit(__LINK_STATE_START, &dev->state);
-+      }
-+
-+      /*
-+       *      If it went open OK then:
-+       */
-+
-+      if (!ret) {
-+              /*
-+               *      Set the flags.
-+               */
-+              dev->flags |= IFF_UP;
-+
-+              /*
-+               *      Initialize multicasting status
-+               */
-+              dev_mc_upload(dev);
-+
-+              /*
-+               *      Wakeup transmit queue engine
-+               */
-+              dev_activate(dev);
-+
-+              /*
-+               *      ... and announce new interface.
-+               */
-+              notifier_call_chain(&netdev_chain, NETDEV_UP, dev);
-+      }
-+      return ret;
-+}
-+
-+/**
-+ *    dev_close - shutdown an interface.
-+ *    @dev: device to shutdown
-+ *
-+ *    This function moves an active device into down state. A
-+ *    %NETDEV_GOING_DOWN is sent to the netdev notifier chain. The device
-+ *    is then deactivated and finally a %NETDEV_DOWN is sent to the notifier
-+ *    chain.
-+ */
-+int dev_close(struct net_device *dev)
-+{
-+      if (!(dev->flags & IFF_UP))
-+              return 0;
-+
-+      /*
-+       *      Tell people we are going down, so that they can
-+       *      prepare to death, when device is still operating.
-+       */
-+      notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev);
-+
-+      dev_deactivate(dev);
-+
-+      clear_bit(__LINK_STATE_START, &dev->state);
-+
-+      /* Synchronize to scheduled poll. We cannot touch poll list,
-+       * it can be even on different cpu. So just clear netif_running(),
-+       * and wait when poll really will happen. Actually, the best place
-+       * for this is inside dev->stop() after device stopped its irq
-+       * engine, but this requires more changes in devices. */
-+
-+      smp_mb__after_clear_bit(); /* Commit netif_running(). */
-+      while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
-+              /* No hurry. */
-+              current->state = TASK_INTERRUPTIBLE;
-+              schedule_timeout(1);
-+      }
-+
-+      /*
-+       *      Call the device specific close. This cannot fail.
-+       *      Only if device is UP
-+       *
-+       *      We allow it to be called even after a DETACH hot-plug
-+       *      event.
-+       */
-+      if (dev->stop)
-+              dev->stop(dev);
-+
-+      /*
-+       *      Device is now down.
-+       */
-+
-+      dev->flags &= ~IFF_UP;
-+
-+      /*
-+       * Tell people we are down
-+       */
-+      notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);
-+
-+      return 0;
-+}
-+
-+
-+/*
-+ *    Device change register/unregister. These are not inline or static
-+ *    as we export them to the world.
-+ */
-+
-+/**
-+ *    register_netdevice_notifier - register a network notifier block
-+ *    @nb: notifier
-+ *
-+ *    Register a notifier to be called when network device events occur.
-+ *    The notifier passed is linked into the kernel structures and must
-+ *    not be reused until it has been unregistered. A negative errno code
-+ *    is returned on a failure.
-+ *
-+ *    When registered all registration and up events are replayed
-+ *    to the new notifier to allow device to have a race free 
-+ *    view of the network device list.
-+ */
-+
-+int register_netdevice_notifier(struct notifier_block *nb)
-+{
-+      struct net_device *dev;
-+      int err;
-+
-+      rtnl_lock();
-+      err = notifier_chain_register(&netdev_chain, nb);
-+      if (!err) {
-+              for (dev = dev_base; dev; dev = dev->next) {
-+                      nb->notifier_call(nb, NETDEV_REGISTER, dev);
-+
-+                      if (dev->flags & IFF_UP) 
-+                              nb->notifier_call(nb, NETDEV_UP, dev);
-+              }
-+      }
-+      rtnl_unlock();
-+      return err;
-+}
-+
-+/**
-+ *    unregister_netdevice_notifier - unregister a network notifier block
-+ *    @nb: notifier
-+ *
-+ *    Unregister a notifier previously registered by
-+ *    register_netdevice_notifier(). The notifier is unlinked into the
-+ *    kernel structures and may then be reused. A negative errno code
-+ *    is returned on a failure.
-+ */
-+
-+int unregister_netdevice_notifier(struct notifier_block *nb)
-+{
-+      return notifier_chain_unregister(&netdev_chain, nb);
-+}
-+
-+/**
-+ *    call_netdevice_notifiers - call all network notifier blocks
-+ *      @val: value passed unmodified to notifier function
-+ *      @v:   pointer passed unmodified to notifier function
-+ *
-+ *    Call all network notifier blocks.  Parameters and return value
-+ *    are as for notifier_call_chain().
-+ */
-+
-+int call_netdevice_notifiers(unsigned long val, void *v)
-+{
-+      return notifier_call_chain(&netdev_chain, val, v);
-+}
-+
-+/* When > 0 there are consumers of rx skb time stamps */
-+static atomic_t netstamp_needed = ATOMIC_INIT(0);
-+
-+void net_enable_timestamp(void)
-+{
-+      atomic_inc(&netstamp_needed);
-+}
-+
-+void net_disable_timestamp(void)
-+{
-+      atomic_dec(&netstamp_needed);
-+}
-+
-+static inline void net_timestamp(struct timeval *stamp)
-+{
-+      if (atomic_read(&netstamp_needed))
-+              do_gettimeofday(stamp);
-+      else {
-+              stamp->tv_sec = 0;
-+              stamp->tv_usec = 0;
-+      }
-+}
-+
-+/*
-+ *    Support routine. Sends outgoing frames to any network
-+ *    taps currently in use.
-+ */
-+
-+void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
-+{
-+      struct packet_type *ptype;
-+      net_timestamp(&skb->stamp);
-+
-+      rcu_read_lock();
-+      list_for_each_entry_rcu(ptype, &ptype_all, list) {
-+              /* Never send packets back to the socket
-+               * they originated from - MvS (miquels@drinkel.ow.org)
-+               */
-+              if ((ptype->dev == dev || !ptype->dev) &&
-+                  (ptype->af_packet_priv == NULL ||
-+                   (struct sock *)ptype->af_packet_priv != skb->sk)) {
-+                      struct sk_buff *skb2= skb_clone(skb, GFP_ATOMIC);
-+                      if (!skb2)
-+                              break;
-+
-+                      /* skb->nh should be correctly
-+                         set by sender, so that the second statement is
-+                         just protection against buggy protocols.
-+                       */
-+                      skb2->mac.raw = skb2->data;
-+
-+                      if (skb2->nh.raw < skb2->data ||
-+                          skb2->nh.raw > skb2->tail) {
-+                              if (net_ratelimit())
-+                                      printk(KERN_CRIT "protocol %04x is "
-+                                             "buggy, dev %s\n",
-+                                             skb2->protocol, dev->name);
-+                              skb2->nh.raw = skb2->data;
-+                      }
-+
-+                      skb2->h.raw = skb2->nh.raw;
-+                      skb2->pkt_type = PACKET_OUTGOING;
-+                      ptype->func(skb2, skb->dev, ptype);
-+              }
-+      }
-+      rcu_read_unlock();
-+}
-+
-+/*
-+ * Invalidate hardware checksum when packet is to be mangled, and
-+ * complete checksum manually on outgoing path.
-+ */
-+int skb_checksum_help(struct sk_buff *skb, int inward)
-+{
-+      unsigned int csum;
-+      int ret = 0, offset = skb->h.raw - skb->data;
-+
-+      if (inward) {
-+              skb->ip_summed = CHECKSUM_NONE;
-+              goto out;
-+      }
-+
-+      if (skb_cloned(skb)) {
-+              ret = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-+              if (ret)
-+                      goto out;
-+      }
-+
-+      if (offset > (int)skb->len)
-+              BUG();
-+      csum = skb_checksum(skb, offset, skb->len-offset, 0);
-+
-+      offset = skb->tail - skb->h.raw;
-+      if (offset <= 0)
-+              BUG();
-+      if (skb->csum + 2 > offset)
-+              BUG();
-+
-+      *(u16*)(skb->h.raw + skb->csum) = csum_fold(csum);
-+      skb->ip_summed = CHECKSUM_NONE;
-+out:  
-+      return ret;
-+}
-+
-+#ifdef CONFIG_HIGHMEM
-+/* Actually, we should eliminate this check as soon as we know, that:
-+ * 1. IOMMU is present and allows to map all the memory.
-+ * 2. No high memory really exists on this machine.
-+ */
-+
-+static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
-+{
-+      int i;
-+
-+      if (dev->features & NETIF_F_HIGHDMA)
-+              return 0;
-+
-+      for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-+              if (PageHighMem(skb_shinfo(skb)->frags[i].page))
-+                      return 1;
-+
-+      return 0;
-+}
-+#else
-+#define illegal_highdma(dev, skb)     (0)
-+#endif
-+
-+extern void skb_release_data(struct sk_buff *);
-+
-+/* Keep head the same: replace data */
-+int __skb_linearize(struct sk_buff *skb, int gfp_mask)
-+{
-+      unsigned int size;
-+      u8 *data;
-+      long offset;
-+      struct skb_shared_info *ninfo;
-+      int headerlen = skb->data - skb->head;
-+      int expand = (skb->tail + skb->data_len) - skb->end;
-+
-+      if (skb_shared(skb))
-+              BUG();
-+
-+      if (expand <= 0)
-+              expand = 0;
-+
-+      size = skb->end - skb->head + expand;
-+      size = SKB_DATA_ALIGN(size);
-+      data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
-+      if (!data)
-+              return -ENOMEM;
-+
-+      /* Copy entire thing */
-+      if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
-+              BUG();
-+
-+      /* Set up shinfo */
-+      ninfo = (struct skb_shared_info*)(data + size);
-+      atomic_set(&ninfo->dataref, 1);
-+      ninfo->tso_size = skb_shinfo(skb)->tso_size;
-+      ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
-+      ninfo->nr_frags = 0;
-+      ninfo->frag_list = NULL;
-+
-+      /* Offset between the two in bytes */
-+      offset = data - skb->head;
-+
-+      /* Free old data. */
-+      skb_release_data(skb);
-+
-+      skb->head = data;
-+      skb->end  = data + size;
-+
-+      /* Set up new pointers */
-+      skb->h.raw   += offset;
-+      skb->nh.raw  += offset;
-+      skb->mac.raw += offset;
-+      skb->tail    += offset;
-+      skb->data    += offset;
-+
-+      /* We are no longer a clone, even if we were. */
-+      skb->cloned    = 0;
-+
-+      skb->tail     += skb->data_len;
-+      skb->data_len  = 0;
-+      return 0;
-+}
-+
-+#define HARD_TX_LOCK(dev, cpu) {                      \
-+      if ((dev->features & NETIF_F_LLTX) == 0) {      \
-+              spin_lock(&dev->xmit_lock);             \
-+              dev->xmit_lock_owner = cpu;             \
-+      }                                               \
-+}
-+
-+#define HARD_TX_UNLOCK(dev) {                         \
-+      if ((dev->features & NETIF_F_LLTX) == 0) {      \
-+              dev->xmit_lock_owner = -1;              \
-+              spin_unlock(&dev->xmit_lock);           \
-+      }                                               \
-+}
-+
-+/**
-+ *    dev_queue_xmit - transmit a buffer
-+ *    @skb: buffer to transmit
-+ *
-+ *    Queue a buffer for transmission to a network device. The caller must
-+ *    have set the device and priority and built the buffer before calling
-+ *    this function. The function can be called from an interrupt.
-+ *
-+ *    A negative errno code is returned on a failure. A success does not
-+ *    guarantee the frame will be transmitted as it may be dropped due
-+ *    to congestion or traffic shaping.
-+ *
-+ * -----------------------------------------------------------------------------------
-+ *      I notice this method can also return errors from the queue disciplines,
-+ *      including NET_XMIT_DROP, which is a positive value.  So, errors can also
-+ *      be positive.
-+ *
-+ *      Regardless of the return value, the skb is consumed, so it is currently
-+ *      difficult to retry a send to this method.  (You can bump the ref count
-+ *      before sending to hold a reference for retry if you are careful.)
-+ *
-+ *      When calling this method, interrupts MUST be enabled.  This is because
-+ *      the BH enable code must have IRQs enabled so that it will not deadlock.
-+ *          --BLG
-+ */
-+
-+int dev_queue_xmit(struct sk_buff *skb)
-+{
-+      struct net_device *dev = skb->dev;
-+      struct Qdisc *q;
-+      int rc = -ENOMEM;
-+
-+      if (skb_shinfo(skb)->frag_list &&
-+          !(dev->features & NETIF_F_FRAGLIST) &&
-+          __skb_linearize(skb, GFP_ATOMIC))
-+              goto out_kfree_skb;
-+
-+      /* Fragmented skb is linearized if device does not support SG,
-+       * or if at least one of fragments is in highmem and device
-+       * does not support DMA from it.
-+       */
-+      if (skb_shinfo(skb)->nr_frags &&
-+          (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
-+          __skb_linearize(skb, GFP_ATOMIC))
-+              goto out_kfree_skb;
-+
-+      /* If packet is not checksummed and device does not support
-+       * checksumming for this protocol, complete checksumming here.
-+       */
-+      if (skb->ip_summed == CHECKSUM_HW &&
-+          (!(dev->features & (NETIF_F_HW_CSUM | NETIF_F_NO_CSUM)) &&
-+           (!(dev->features & NETIF_F_IP_CSUM) ||
-+            skb->protocol != htons(ETH_P_IP))))
-+              if (skb_checksum_help(skb, 0))
-+                      goto out_kfree_skb;
-+
-+      /* Disable soft irqs for various locks below. Also 
-+       * stops preemption for RCU. 
-+       */
-+      local_bh_disable(); 
-+
-+      /* Updates of qdisc are serialized by queue_lock. 
-+       * The struct Qdisc which is pointed to by qdisc is now a 
-+       * rcu structure - it may be accessed without acquiring 
-+       * a lock (but the structure may be stale.) The freeing of the
-+       * qdisc will be deferred until it's known that there are no 
-+       * more references to it.
-+       * 
-+       * If the qdisc has an enqueue function, we still need to 
-+       * hold the queue_lock before calling it, since queue_lock
-+       * also serializes access to the device queue.
-+       */
-+
-+      q = rcu_dereference(dev->qdisc);
-+#ifdef CONFIG_NET_CLS_ACT
-+      skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS);
-+#endif
-+      if (q->enqueue) {
-+              /* Grab device queue */
-+              spin_lock(&dev->queue_lock);
-+
-+              rc = q->enqueue(skb, q);
-+
-+              qdisc_run(dev);
-+
-+              spin_unlock(&dev->queue_lock);
-+              rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
-+              goto out;
-+      }
-+
-+      /* The device has no queue. Common case for software devices:
-+         loopback, all the sorts of tunnels...
-+
-+         Really, it is unlikely that xmit_lock protection is necessary here.
-+         (f.e. loopback and IP tunnels are clean ignoring statistics
-+         counters.)
-+         However, it is possible, that they rely on protection
-+         made by us here.
-+
-+         Check this and shot the lock. It is not prone from deadlocks.
-+         Either shot noqueue qdisc, it is even simpler 8)
-+       */
-+      if (dev->flags & IFF_UP) {
-+              int cpu = smp_processor_id(); /* ok because BHs are off */
-+
-+              if (dev->xmit_lock_owner != cpu) {
-+
-+                      HARD_TX_LOCK(dev, cpu);
-+
-+                      if (!netif_queue_stopped(dev)) {
-+                              if (netdev_nit)
-+                                      dev_queue_xmit_nit(skb, dev);
-+
-+                              rc = 0;
-+                              if (!dev->hard_start_xmit(skb, dev)) {
-+                                      HARD_TX_UNLOCK(dev);
-+                                      goto out;
-+                              }
-+                      }
-+                      HARD_TX_UNLOCK(dev);
-+                      if (net_ratelimit())
-+                              printk(KERN_CRIT "Virtual device %s asks to "
-+                                     "queue packet!\n", dev->name);
-+              } else {
-+                      /* Recursion is detected! It is possible,
-+                       * unfortunately */
-+                      if (net_ratelimit())
-+                              printk(KERN_CRIT "Dead loop on virtual device "
-+                                     "%s, fix it urgently!\n", dev->name);
-+              }
-+      }
-+
-+      rc = -ENETDOWN;
-+      local_bh_enable();
-+
-+out_kfree_skb:
-+      kfree_skb(skb);
-+      return rc;
-+out:
-+      local_bh_enable();
-+      return rc;
-+}
-+
-+
-+/*=======================================================================
-+                      Receiver routines
-+  =======================================================================*/
-+
-+int netdev_max_backlog = 300;
-+int weight_p = 64;            /* old backlog weight */
-+/* These numbers are selected based on intuition and some
-+ * experimentatiom, if you have more scientific way of doing this
-+ * please go ahead and fix things.
-+ */
-+int no_cong_thresh = 10;
-+int no_cong = 20;
-+int lo_cong = 100;
-+int mod_cong = 290;
-+
-+DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, };
-+
-+
-+static void get_sample_stats(int cpu)
-+{
-+#ifdef RAND_LIE
-+      unsigned long rd;
-+      int rq;
-+#endif
-+      struct softnet_data *sd = &per_cpu(softnet_data, cpu);
-+      int blog = sd->input_pkt_queue.qlen;
-+      int avg_blog = sd->avg_blog;
-+
-+      avg_blog = (avg_blog >> 1) + (blog >> 1);
-+
-+      if (avg_blog > mod_cong) {
-+              /* Above moderate congestion levels. */
-+              sd->cng_level = NET_RX_CN_HIGH;
-+#ifdef RAND_LIE
-+              rd = net_random();
-+              rq = rd % netdev_max_backlog;
-+              if (rq < avg_blog) /* unlucky bastard */
-+                      sd->cng_level = NET_RX_DROP;
-+#endif
-+      } else if (avg_blog > lo_cong) {
-+              sd->cng_level = NET_RX_CN_MOD;
-+#ifdef RAND_LIE
-+              rd = net_random();
-+              rq = rd % netdev_max_backlog;
-+                      if (rq < avg_blog) /* unlucky bastard */
-+                              sd->cng_level = NET_RX_CN_HIGH;
-+#endif
-+      } else if (avg_blog > no_cong)
-+              sd->cng_level = NET_RX_CN_LOW;
-+      else  /* no congestion */
-+              sd->cng_level = NET_RX_SUCCESS;
-+
-+      sd->avg_blog = avg_blog;
-+}
-+
-+#ifdef OFFLINE_SAMPLE
-+static void sample_queue(unsigned long dummy)
-+{
-+/* 10 ms 0r 1ms -- i don't care -- JHS */
-+      int next_tick = 1;
-+      int cpu = smp_processor_id();
-+
-+      get_sample_stats(cpu);
-+      next_tick += jiffies;
-+      mod_timer(&samp_timer, next_tick);
-+}
-+#endif
-+
-+
-+/**
-+ *    netif_rx        -       post buffer to the network code
-+ *    @skb: buffer to post
-+ *
-+ *    This function receives a packet from a device driver and queues it for
-+ *    the upper (protocol) levels to process.  It always succeeds. The buffer
-+ *    may be dropped during processing for congestion control or by the
-+ *    protocol layers.
-+ *
-+ *    return values:
-+ *    NET_RX_SUCCESS  (no congestion)
-+ *    NET_RX_CN_LOW   (low congestion)
-+ *    NET_RX_CN_MOD   (moderate congestion)
-+ *    NET_RX_CN_HIGH  (high congestion)
-+ *    NET_RX_DROP     (packet was dropped)
-+ *
-+ */
-+
-+int netif_rx(struct sk_buff *skb)
-+{
-+      int this_cpu;
-+      struct softnet_data *queue;
-+      unsigned long flags;
-+
-+      /* if netpoll wants it, pretend we never saw it */
-+      if (netpoll_rx(skb))
-+              return NET_RX_DROP;
-+
-+      if (!skb->stamp.tv_sec)
-+              net_timestamp(&skb->stamp);
-+
-+      /*
-+       * The code is rearranged so that the path is the most
-+       * short when CPU is congested, but is still operating.
-+       */
-+      local_irq_save(flags);
-+      this_cpu = smp_processor_id();
-+      queue = &__get_cpu_var(softnet_data);
-+
-+      __get_cpu_var(netdev_rx_stat).total++;
-+      if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
-+              if (queue->input_pkt_queue.qlen) {
-+                      if (queue->throttle)
-+                              goto drop;
-+
-+enqueue:
-+                      dev_hold(skb->dev);
-+                      __skb_queue_tail(&queue->input_pkt_queue, skb);
-+#ifndef OFFLINE_SAMPLE
-+                      get_sample_stats(this_cpu);
-+#endif
-+                      local_irq_restore(flags);
-+                      return queue->cng_level;
-+              }
-+
-+              if (queue->throttle)
-+                      queue->throttle = 0;
-+
-+              netif_rx_schedule(&queue->backlog_dev);
-+              goto enqueue;
-+      }
-+
-+      if (!queue->throttle) {
-+              queue->throttle = 1;
-+              __get_cpu_var(netdev_rx_stat).throttled++;
-+      }
-+
-+drop:
-+      __get_cpu_var(netdev_rx_stat).dropped++;
-+      local_irq_restore(flags);
-+
-+      kfree_skb(skb);
-+      return NET_RX_DROP;
-+}
-+
-+int netif_rx_ni(struct sk_buff *skb)
-+{
-+      int err;
-+
-+      preempt_disable();
-+      err = netif_rx(skb);
-+      if (local_softirq_pending())
-+              do_softirq();
-+      preempt_enable();
-+
-+      return err;
-+}
-+
-+EXPORT_SYMBOL(netif_rx_ni);
-+
-+static __inline__ void skb_bond(struct sk_buff *skb)
-+{
-+      struct net_device *dev = skb->dev;
-+
-+      if (dev->master) {
-+              skb->real_dev = skb->dev;
-+              skb->dev = dev->master;
-+      }
-+}
-+
-+static void net_tx_action(struct softirq_action *h)
-+{
-+      struct softnet_data *sd = &__get_cpu_var(softnet_data);
-+
-+      if (sd->completion_queue) {
-+              struct sk_buff *clist;
-+
-+              local_irq_disable();
-+              clist = sd->completion_queue;
-+              sd->completion_queue = NULL;
-+              local_irq_enable();
-+
-+              while (clist) {
-+                      struct sk_buff *skb = clist;
-+                      clist = clist->next;
-+
-+                      BUG_TRAP(!atomic_read(&skb->users));
-+                      __kfree_skb(skb);
-+              }
-+      }
-+
-+      if (sd->output_queue) {
-+              struct net_device *head;
-+
-+              local_irq_disable();
-+              head = sd->output_queue;
-+              sd->output_queue = NULL;
-+              local_irq_enable();
-+
-+              while (head) {
-+                      struct net_device *dev = head;
-+                      head = head->next_sched;
-+
-+                      smp_mb__before_clear_bit();
-+                      clear_bit(__LINK_STATE_SCHED, &dev->state);
-+
-+                      if (spin_trylock(&dev->queue_lock)) {
-+                              qdisc_run(dev);
-+                              spin_unlock(&dev->queue_lock);
-+                      } else {
-+                              netif_schedule(dev);
-+                      }
-+              }
-+      }
-+}
-+
-+static __inline__ int deliver_skb(struct sk_buff *skb,
-+                                struct packet_type *pt_prev)
-+{
-+      atomic_inc(&skb->users);
-+      return pt_prev->func(skb, skb->dev, pt_prev);
-+}
-+
-+#if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE)
-+int (*br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff **pskb);
-+struct net_bridge;
-+struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
-+                                              unsigned char *addr);
-+void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
-+
-+static __inline__ int handle_bridge(struct sk_buff **pskb,
-+                                  struct packet_type **pt_prev, int *ret)
-+{
-+      struct net_bridge_port *port;
-+
-+      if ((*pskb)->pkt_type == PACKET_LOOPBACK ||
-+          (port = rcu_dereference((*pskb)->dev->br_port)) == NULL)
-+              return 0;
-+
-+      if (*pt_prev) {
-+              *ret = deliver_skb(*pskb, *pt_prev);
-+              *pt_prev = NULL;
-+      } 
-+      
-+      return br_handle_frame_hook(port, pskb);
-+}
-+#else
-+#define handle_bridge(skb, pt_prev, ret)      (0)
-+#endif
-+
-+#ifdef CONFIG_NET_CLS_ACT
-+/* TODO: Maybe we should just force sch_ingress to be compiled in
-+ * when CONFIG_NET_CLS_ACT is? otherwise some useless instructions
-+ * a compare and 2 stores extra right now if we dont have it on
-+ * but have CONFIG_NET_CLS_ACT
-+ * NOTE: This doesnt stop any functionality; if you dont have 
-+ * the ingress scheduler, you just cant add policies on ingress.
-+ *
-+ */
-+static int ing_filter(struct sk_buff *skb) 
-+{
-+      struct Qdisc *q;
-+      struct net_device *dev = skb->dev;
-+      int result = TC_ACT_OK;
-+      
-+      if (dev->qdisc_ingress) {
-+              __u32 ttl = (__u32) G_TC_RTTL(skb->tc_verd);
-+              if (MAX_RED_LOOP < ttl++) {
-+                      printk("Redir loop detected Dropping packet (%s->%s)\n",
-+                              skb->input_dev?skb->input_dev->name:"??",skb->dev->name);
-+                      return TC_ACT_SHOT;
-+              }
-+
-+              skb->tc_verd = SET_TC_RTTL(skb->tc_verd,ttl);
-+
-+              skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS);
-+              if (NULL == skb->input_dev) {
-+                      skb->input_dev = skb->dev;
-+                      printk("ing_filter:  fixed  %s out %s\n",skb->input_dev->name,skb->dev->name);
-+              }
-+              spin_lock(&dev->ingress_lock);
-+              if ((q = dev->qdisc_ingress) != NULL)
-+                      result = q->enqueue(skb, q);
-+              spin_unlock(&dev->ingress_lock);
-+
-+      }
-+
-+      return result;
-+}
-+#endif
-+
-+int netif_receive_skb(struct sk_buff *skb)
-+{
-+      struct packet_type *ptype, *pt_prev;
-+      int ret = NET_RX_DROP;
-+      unsigned short type;
-+
-+      /* if we've gotten here through NAPI, check netpoll */
-+      if (skb->dev->poll && netpoll_rx(skb))
-+              return NET_RX_DROP;
-+
-+      if (!skb->stamp.tv_sec)
-+              net_timestamp(&skb->stamp);
-+
-+      skb_bond(skb);
-+
-+      __get_cpu_var(netdev_rx_stat).total++;
-+
-+      skb->h.raw = skb->nh.raw = skb->data;
-+      skb->mac_len = skb->nh.raw - skb->mac.raw;
-+
-+      pt_prev = NULL;
-+
-+      rcu_read_lock();
-+
-+#ifdef CONFIG_NET_CLS_ACT
-+      if (skb->tc_verd & TC_NCLS) {
-+              skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
-+              goto ncls;
-+      }
-+#endif
-+
-+      list_for_each_entry_rcu(ptype, &ptype_all, list) {
-+              if (!ptype->dev || ptype->dev == skb->dev) {
-+                      if (pt_prev) 
-+                              ret = deliver_skb(skb, pt_prev);
-+                      pt_prev = ptype;
-+              }
-+      }
-+
-+#ifdef CONFIG_NET_CLS_ACT
-+      if (pt_prev) {
-+              ret = deliver_skb(skb, pt_prev);
-+              pt_prev = NULL; /* noone else should process this after*/
-+      } else {
-+              skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
-+      }
-+
-+      ret = ing_filter(skb);
-+
-+      if (ret == TC_ACT_SHOT || (ret == TC_ACT_STOLEN)) {
-+              kfree_skb(skb);
-+              goto out;
-+      }
-+
-+      skb->tc_verd = 0;
-+ncls:
-+#endif
-+
-+      handle_diverter(skb);
-+
-+      if (handle_bridge(&skb, &pt_prev, &ret))
-+              goto out;
-+
-+      type = skb->protocol;
-+      list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {
-+              if (ptype->type == type &&
-+                  (!ptype->dev || ptype->dev == skb->dev)) {
-+                      if (pt_prev) 
-+                              ret = deliver_skb(skb, pt_prev);
-+                      pt_prev = ptype;
-+              }
-+      }
-+
-+      if (pt_prev) {
-+              ret = pt_prev->func(skb, skb->dev, pt_prev);
-+      } else {
-+              kfree_skb(skb);
-+              /* Jamal, now you will not able to escape explaining
-+               * me how you were going to use this. :-)
-+               */
-+              ret = NET_RX_DROP;
-+      }
-+
-+out:
-+      rcu_read_unlock();
-+      return ret;
-+}
-+
-+static int process_backlog(struct net_device *backlog_dev, int *budget)
-+{
-+      int work = 0;
-+      int quota = min(backlog_dev->quota, *budget);
-+      struct softnet_data *queue = &__get_cpu_var(softnet_data);
-+      unsigned long start_time = jiffies;
-+
-+      backlog_dev->weight = weight_p;
-+      for (;;) {
-+              struct sk_buff *skb;
-+              struct net_device *dev;
-+
-+              local_irq_disable();
-+              skb = __skb_dequeue(&queue->input_pkt_queue);
-+              if (!skb)
-+                      goto job_done;
-+              local_irq_enable();
-+
-+              dev = skb->dev;
-+
-+              netif_receive_skb(skb);
-+
-+              dev_put(dev);
-+
-+              work++;
-+
-+              if (work >= quota || jiffies - start_time > 1)
-+                      break;
-+
-+      }
-+
-+      backlog_dev->quota -= work;
-+      *budget -= work;
-+      return -1;
-+
-+job_done:
-+      backlog_dev->quota -= work;
-+      *budget -= work;
-+
-+      list_del(&backlog_dev->poll_list);
-+      smp_mb__before_clear_bit();
-+      netif_poll_enable(backlog_dev);
-+
-+      if (queue->throttle)
-+              queue->throttle = 0;
-+      local_irq_enable();
-+      return 0;
-+}
-+
-+static void net_rx_action(struct softirq_action *h)
-+{
-+      struct softnet_data *queue = &__get_cpu_var(softnet_data);
-+      unsigned long start_time = jiffies;
-+      int budget = netdev_max_backlog;
-+
-+      
-+      local_irq_disable();
-+
-+      while (!list_empty(&queue->poll_list)) {
-+              struct net_device *dev;
-+
-+              if (budget <= 0 || jiffies - start_time > 1)
-+                      goto softnet_break;
-+
-+              local_irq_enable();
-+
-+              dev = list_entry(queue->poll_list.next,
-+                               struct net_device, poll_list);
-+              netpoll_poll_lock(dev);
-+
-+              if (dev->quota <= 0 || dev->poll(dev, &budget)) {
-+                      netpoll_poll_unlock(dev);
-+                      local_irq_disable();
-+                      list_del(&dev->poll_list);
-+                      list_add_tail(&dev->poll_list, &queue->poll_list);
-+                      if (dev->quota < 0)
-+                              dev->quota += dev->weight;
-+                      else
-+                              dev->quota = dev->weight;
-+              } else {
-+                      netpoll_poll_unlock(dev);
-+                      dev_put(dev);
-+                      local_irq_disable();
-+              }
-+      }
-+out:
-+      local_irq_enable();
-+      return;
-+
-+softnet_break:
-+      __get_cpu_var(netdev_rx_stat).time_squeeze++;
-+      __raise_softirq_irqoff(NET_RX_SOFTIRQ);
-+      goto out;
-+}
-+
-+static gifconf_func_t * gifconf_list [NPROTO];
-+
-+/**
-+ *    register_gifconf        -       register a SIOCGIF handler
-+ *    @family: Address family
-+ *    @gifconf: Function handler
-+ *
-+ *    Register protocol dependent address dumping routines. The handler
-+ *    that is passed must not be freed or reused until it has been replaced
-+ *    by another handler.
-+ */
-+int register_gifconf(unsigned int family, gifconf_func_t * gifconf)
-+{
-+      if (family >= NPROTO)
-+              return -EINVAL;
-+      gifconf_list[family] = gifconf;
-+      return 0;
-+}
-+
-+
-+/*
-+ *    Map an interface index to its name (SIOCGIFNAME)
-+ */
-+
-+/*
-+ *    We need this ioctl for efficient implementation of the
-+ *    if_indextoname() function required by the IPv6 API.  Without
-+ *    it, we would have to search all the interfaces to find a
-+ *    match.  --pb
-+ */
-+
-+static int dev_ifname(struct ifreq __user *arg)
-+{
-+      struct net_device *dev;
-+      struct ifreq ifr;
-+
-+      /*
-+       *      Fetch the caller's info block.
-+       */
-+
-+      if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
-+              return -EFAULT;
-+
-+      read_lock(&dev_base_lock);
-+      dev = __dev_get_by_index(ifr.ifr_ifindex);
-+      if (!dev) {
-+              read_unlock(&dev_base_lock);
-+              return -ENODEV;
-+      }
-+
-+      strcpy(ifr.ifr_name, dev->name);
-+      read_unlock(&dev_base_lock);
-+
-+      if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
-+              return -EFAULT;
-+      return 0;
-+}
-+
-+/*
-+ *    Perform a SIOCGIFCONF call. This structure will change
-+ *    size eventually, and there is nothing I can do about it.
-+ *    Thus we will need a 'compatibility mode'.
-+ */
-+
-+static int dev_ifconf(char __user *arg)
-+{
-+      struct ifconf ifc;
-+      struct net_device *dev;
-+      char __user *pos;
-+      int len;
-+      int total;
-+      int i;
-+
-+      /*
-+       *      Fetch the caller's info block.
-+       */
-+
-+      if (copy_from_user(&ifc, arg, sizeof(struct ifconf)))
-+              return -EFAULT;
-+
-+      pos = ifc.ifc_buf;
-+      len = ifc.ifc_len;
-+
-+      /*
-+       *      Loop over the interfaces, and write an info block for each.
-+       */
-+
-+      total = 0;
-+      for (dev = dev_base; dev; dev = dev->next) {
-+              for (i = 0; i < NPROTO; i++) {
-+                      if (gifconf_list[i]) {
-+                              int done;
-+                              if (!pos)
-+                                      done = gifconf_list[i](dev, NULL, 0);
-+                              else
-+                                      done = gifconf_list[i](dev, pos + total,
-+                                                             len - total);
-+                              if (done < 0)
-+                                      return -EFAULT;
-+                              total += done;
-+                      }
-+              }
-+      }
-+
-+      /*
-+       *      All done.  Write the updated control block back to the caller.
-+       */
-+      ifc.ifc_len = total;
-+
-+      /*
-+       *      Both BSD and Solaris return 0 here, so we do too.
-+       */
-+      return copy_to_user(arg, &ifc, sizeof(struct ifconf)) ? -EFAULT : 0;
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+/*
-+ *    This is invoked by the /proc filesystem handler to display a device
-+ *    in detail.
-+ */
-+static __inline__ struct net_device *dev_get_idx(loff_t pos)
-+{
-+      struct net_device *dev;
-+      loff_t i;
-+
-+      for (i = 0, dev = dev_base; dev && i < pos; ++i, dev = dev->next);
-+
-+      return i == pos ? dev : NULL;
-+}
-+
-+void *dev_seq_start(struct seq_file *seq, loff_t *pos)
-+{
-+      read_lock(&dev_base_lock);
-+      return *pos ? dev_get_idx(*pos - 1) : SEQ_START_TOKEN;
-+}
-+
-+void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-+{
-+      ++*pos;
-+      return v == SEQ_START_TOKEN ? dev_base : ((struct net_device *)v)->next;
-+}
-+
-+void dev_seq_stop(struct seq_file *seq, void *v)
-+{
-+      read_unlock(&dev_base_lock);
-+}
-+
-+static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
-+{
-+      if (dev->get_stats) {
-+              struct net_device_stats *stats = dev->get_stats(dev);
-+
-+              seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu "
-+                              "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
-+                         dev->name, stats->rx_bytes, stats->rx_packets,
-+                         stats->rx_errors,
-+                         stats->rx_dropped + stats->rx_missed_errors,
-+                         stats->rx_fifo_errors,
-+                         stats->rx_length_errors + stats->rx_over_errors +
-+                           stats->rx_crc_errors + stats->rx_frame_errors,
-+                         stats->rx_compressed, stats->multicast,
-+                         stats->tx_bytes, stats->tx_packets,
-+                         stats->tx_errors, stats->tx_dropped,
-+                         stats->tx_fifo_errors, stats->collisions,
-+                         stats->tx_carrier_errors +
-+                           stats->tx_aborted_errors +
-+                           stats->tx_window_errors +
-+                           stats->tx_heartbeat_errors,
-+                         stats->tx_compressed);
-+      } else
-+              seq_printf(seq, "%6s: No statistics available.\n", dev->name);
-+}
-+
-+/*
-+ *    Called from the PROCfs module. This now uses the new arbitrary sized
-+ *    /proc/net interface to create /proc/net/dev
-+ */
-+static int dev_seq_show(struct seq_file *seq, void *v)
-+{
-+      if (v == SEQ_START_TOKEN)
-+              seq_puts(seq, "Inter-|   Receive                            "
-+                            "                    |  Transmit\n"
-+                            " face |bytes    packets errs drop fifo frame "
-+                            "compressed multicast|bytes    packets errs "
-+                            "drop fifo colls carrier compressed\n");
-+      else
-+              dev_seq_printf_stats(seq, v);
-+      return 0;
-+}
-+
-+static struct netif_rx_stats *softnet_get_online(loff_t *pos)
-+{
-+      struct netif_rx_stats *rc = NULL;
-+
-+      while (*pos < NR_CPUS)
-+              if (cpu_online(*pos)) {
-+                      rc = &per_cpu(netdev_rx_stat, *pos);
-+                      break;
-+              } else
-+                      ++*pos;
-+      return rc;
-+}
-+
-+static void *softnet_seq_start(struct seq_file *seq, loff_t *pos)
-+{
-+      return softnet_get_online(pos);
-+}
-+
-+static void *softnet_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-+{
-+      ++*pos;
-+      return softnet_get_online(pos);
-+}
-+
-+static void softnet_seq_stop(struct seq_file *seq, void *v)
-+{
-+}
-+
-+static int softnet_seq_show(struct seq_file *seq, void *v)
-+{
-+      struct netif_rx_stats *s = v;
-+
-+      seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
-+                 s->total, s->dropped, s->time_squeeze, s->throttled,
-+                 s->fastroute_hit, s->fastroute_success, s->fastroute_defer,
-+                 s->fastroute_deferred_out,
-+#if 0
-+                 s->fastroute_latency_reduction
-+#else
-+                 s->cpu_collision
-+#endif
-+                );
-+      return 0;
-+}
-+
-+static struct seq_operations dev_seq_ops = {
-+      .start = dev_seq_start,
-+      .next  = dev_seq_next,
-+      .stop  = dev_seq_stop,
-+      .show  = dev_seq_show,
-+};
-+
-+static int dev_seq_open(struct inode *inode, struct file *file)
-+{
-+      return seq_open(file, &dev_seq_ops);
-+}
-+
-+static struct file_operations dev_seq_fops = {
-+      .owner   = THIS_MODULE,
-+      .open    = dev_seq_open,
-+      .read    = seq_read,
-+      .llseek  = seq_lseek,
-+      .release = seq_release,
-+};
-+
-+static struct seq_operations softnet_seq_ops = {
-+      .start = softnet_seq_start,
-+      .next  = softnet_seq_next,
-+      .stop  = softnet_seq_stop,
-+      .show  = softnet_seq_show,
-+};
-+
-+static int softnet_seq_open(struct inode *inode, struct file *file)
-+{
-+      return seq_open(file, &softnet_seq_ops);
-+}
-+
-+static struct file_operations softnet_seq_fops = {
-+      .owner   = THIS_MODULE,
-+      .open    = softnet_seq_open,
-+      .read    = seq_read,
-+      .llseek  = seq_lseek,
-+      .release = seq_release,
-+};
-+
-+#ifdef WIRELESS_EXT
-+extern int wireless_proc_init(void);
-+#else
-+#define wireless_proc_init() 0
-+#endif
-+
-+static int __init dev_proc_init(void)
-+{
-+      int rc = -ENOMEM;
-+
-+      if (!proc_net_fops_create("dev", S_IRUGO, &dev_seq_fops))
-+              goto out;
-+      if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
-+              goto out_dev;
-+      if (wireless_proc_init())
-+              goto out_softnet;
-+      rc = 0;
-+out:
-+      return rc;
-+out_softnet:
-+      proc_net_remove("softnet_stat");
-+out_dev:
-+      proc_net_remove("dev");
-+      goto out;
-+}
-+#else
-+#define dev_proc_init() 0
-+#endif        /* CONFIG_PROC_FS */
-+
-+
-+/**
-+ *    netdev_set_master       -       set up master/slave pair
-+ *    @slave: slave device
-+ *    @master: new master device
-+ *
-+ *    Changes the master device of the slave. Pass %NULL to break the
-+ *    bonding. The caller must hold the RTNL semaphore. On a failure
-+ *    a negative errno code is returned. On success the reference counts
-+ *    are adjusted, %RTM_NEWLINK is sent to the routing socket and the
-+ *    function returns zero.
-+ */
-+int netdev_set_master(struct net_device *slave, struct net_device *master)
-+{
-+      struct net_device *old = slave->master;
-+
-+      ASSERT_RTNL();
-+
-+      if (master) {
-+              if (old)
-+                      return -EBUSY;
-+              dev_hold(master);
-+      }
-+
-+      slave->master = master;
-+      
-+      synchronize_net();
-+
-+      if (old)
-+              dev_put(old);
-+
-+      if (master)
-+              slave->flags |= IFF_SLAVE;
-+      else
-+              slave->flags &= ~IFF_SLAVE;
-+
-+      rtmsg_ifinfo(RTM_NEWLINK, slave, IFF_SLAVE);
-+      return 0;
-+}
-+
-+/**
-+ *    dev_set_promiscuity     - update promiscuity count on a device
-+ *    @dev: device
-+ *    @inc: modifier
-+ *
-+ *    Add or remove promsicuity from a device. While the count in the device
-+ *    remains above zero the interface remains promiscuous. Once it hits zero
-+ *    the device reverts back to normal filtering operation. A negative inc
-+ *    value is used to drop promiscuity on the device.
-+ */
-+void dev_set_promiscuity(struct net_device *dev, int inc)
-+{
-+      unsigned short old_flags = dev->flags;
-+
-+      dev->flags |= IFF_PROMISC;
-+      if ((dev->promiscuity += inc) == 0)
-+              dev->flags &= ~IFF_PROMISC;
-+      if (dev->flags ^ old_flags) {
-+              dev_mc_upload(dev);
-+              printk(KERN_INFO "device %s %s promiscuous mode\n",
-+                     dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
-+                                                             "left");
-+      }
-+}
-+
-+/**
-+ *    dev_set_allmulti        - update allmulti count on a device
-+ *    @dev: device
-+ *    @inc: modifier
-+ *
-+ *    Add or remove reception of all multicast frames to a device. While the
-+ *    count in the device remains above zero the interface remains listening
-+ *    to all interfaces. Once it hits zero the device reverts back to normal
-+ *    filtering operation. A negative @inc value is used to drop the counter
-+ *    when releasing a resource needing all multicasts.
-+ */
-+
-+void dev_set_allmulti(struct net_device *dev, int inc)
-+{
-+      unsigned short old_flags = dev->flags;
-+
-+      dev->flags |= IFF_ALLMULTI;
-+      if ((dev->allmulti += inc) == 0)
-+              dev->flags &= ~IFF_ALLMULTI;
-+      if (dev->flags ^ old_flags)
-+              dev_mc_upload(dev);
-+}
-+
-+unsigned dev_get_flags(const struct net_device *dev)
-+{
-+      unsigned flags;
-+
-+      flags = (dev->flags & ~(IFF_PROMISC |
-+                              IFF_ALLMULTI |
-+                              IFF_RUNNING)) | 
-+              (dev->gflags & (IFF_PROMISC |
-+                              IFF_ALLMULTI));
-+
-+      if (netif_running(dev) && netif_carrier_ok(dev))
-+              flags |= IFF_RUNNING;
-+
-+      return flags;
-+}
-+
-+int dev_change_flags(struct net_device *dev, unsigned flags)
-+{
-+      int ret;
-+      int old_flags = dev->flags;
-+
-+      /*
-+       *      Set the flags on our device.
-+       */
-+
-+      dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP |
-+                             IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL |
-+                             IFF_AUTOMEDIA)) |
-+                   (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC |
-+                                  IFF_ALLMULTI));
-+
-+      /*
-+       *      Load in the correct multicast list now the flags have changed.
-+       */
-+
-+      dev_mc_upload(dev);
-+
-+      /*
-+       *      Have we downed the interface. We handle IFF_UP ourselves
-+       *      according to user attempts to set it, rather than blindly
-+       *      setting it.
-+       */
-+
-+      ret = 0;
-+      if ((old_flags ^ flags) & IFF_UP) {     /* Bit is different  ? */
-+              ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev);
-+
-+              if (!ret)
-+                      dev_mc_upload(dev);
-+      }
-+
-+      if (dev->flags & IFF_UP &&
-+          ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
-+                                        IFF_VOLATILE)))
-+              notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev);
-+
-+      if ((flags ^ dev->gflags) & IFF_PROMISC) {
-+              int inc = (flags & IFF_PROMISC) ? +1 : -1;
-+              dev->gflags ^= IFF_PROMISC;
-+              dev_set_promiscuity(dev, inc);
-+      }
-+
-+      /* NOTE: order of synchronization of IFF_PROMISC and IFF_ALLMULTI
-+         is important. Some (broken) drivers set IFF_PROMISC, when
-+         IFF_ALLMULTI is requested not asking us and not reporting.
-+       */
-+      if ((flags ^ dev->gflags) & IFF_ALLMULTI) {
-+              int inc = (flags & IFF_ALLMULTI) ? +1 : -1;
-+              dev->gflags ^= IFF_ALLMULTI;
-+              dev_set_allmulti(dev, inc);
-+      }
-+
-+      if (old_flags ^ dev->flags)
-+              rtmsg_ifinfo(RTM_NEWLINK, dev, old_flags ^ dev->flags);
-+
-+      return ret;
-+}
-+
-+int dev_set_mtu(struct net_device *dev, int new_mtu)
-+{
-+      int err;
-+
-+      if (new_mtu == dev->mtu)
-+              return 0;
-+
-+      /*      MTU must be positive.    */
-+      if (new_mtu < 0)
-+              return -EINVAL;
-+
-+      if (!netif_device_present(dev))
-+              return -ENODEV;
-+
-+      err = 0;
-+      if (dev->change_mtu)
-+              err = dev->change_mtu(dev, new_mtu);
-+      else
-+              dev->mtu = new_mtu;
-+      if (!err && dev->flags & IFF_UP)
-+              notifier_call_chain(&netdev_chain,
-+                                  NETDEV_CHANGEMTU, dev);
-+      return err;
-+}
-+
-+int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
-+{
-+      int err;
-+
-+      if (!dev->set_mac_address)
-+              return -EOPNOTSUPP;
-+      if (sa->sa_family != dev->type)
-+              return -EINVAL;
-+      if (!netif_device_present(dev))
-+              return -ENODEV;
-+      err = dev->set_mac_address(dev, sa);
-+      if (!err)
-+              notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev);
-+      return err;
-+}
-+
-+/*
-+ *    Perform the SIOCxIFxxx calls.
-+ */
-+static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
-+{
-+      int err;
-+      struct net_device *dev = __dev_get_by_name(ifr->ifr_name);
-+
-+      if (!dev)
-+              return -ENODEV;
-+
-+      switch (cmd) {
-+              case SIOCGIFFLAGS:      /* Get interface flags */
-+                      ifr->ifr_flags = dev_get_flags(dev);
-+                      return 0;
-+
-+              case SIOCSIFFLAGS:      /* Set interface flags */
-+                      return dev_change_flags(dev, ifr->ifr_flags);
-+
-+              case SIOCGIFMETRIC:     /* Get the metric on the interface
-+                                         (currently unused) */
-+                      ifr->ifr_metric = 0;
-+                      return 0;
-+
-+              case SIOCSIFMETRIC:     /* Set the metric on the interface
-+                                         (currently unused) */
-+                      return -EOPNOTSUPP;
-+
-+              case SIOCGIFMTU:        /* Get the MTU of a device */
-+                      ifr->ifr_mtu = dev->mtu;
-+                      return 0;
-+
-+              case SIOCSIFMTU:        /* Set the MTU of a device */
-+                      return dev_set_mtu(dev, ifr->ifr_mtu);
-+
-+              case SIOCGIFHWADDR:
-+                      if (!dev->addr_len)
-+                              memset(ifr->ifr_hwaddr.sa_data, 0, sizeof ifr->ifr_hwaddr.sa_data);
-+                      else
-+                              memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
-+                                     min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
-+                      ifr->ifr_hwaddr.sa_family = dev->type;
-+                      return 0;
-+
-+              case SIOCSIFHWADDR:
-+                      return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
-+
-+              case SIOCSIFHWBROADCAST:
-+                      if (ifr->ifr_hwaddr.sa_family != dev->type)
-+                              return -EINVAL;
-+                      memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
-+                             min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
-+                      notifier_call_chain(&netdev_chain,
-+                                          NETDEV_CHANGEADDR, dev);
-+                      return 0;
-+
-+              case SIOCGIFMAP:
-+                      ifr->ifr_map.mem_start = dev->mem_start;
-+                      ifr->ifr_map.mem_end   = dev->mem_end;
-+                      ifr->ifr_map.base_addr = dev->base_addr;
-+                      ifr->ifr_map.irq       = dev->irq;
-+                      ifr->ifr_map.dma       = dev->dma;
-+                      ifr->ifr_map.port      = dev->if_port;
-+                      return 0;
-+
-+              case SIOCSIFMAP:
-+                      if (dev->set_config) {
-+                              if (!netif_device_present(dev))
-+                                      return -ENODEV;
-+                              return dev->set_config(dev, &ifr->ifr_map);
-+                      }
-+                      return -EOPNOTSUPP;
-+
-+              case SIOCADDMULTI:
-+                      if (!dev->set_multicast_list ||
-+                          ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
-+                              return -EINVAL;
-+                      if (!netif_device_present(dev))
-+                              return -ENODEV;
-+                      return dev_mc_add(dev, ifr->ifr_hwaddr.sa_data,
-+                                        dev->addr_len, 1);
-+
-+              case SIOCDELMULTI:
-+                      if (!dev->set_multicast_list ||
-+                          ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
-+                              return -EINVAL;
-+                      if (!netif_device_present(dev))
-+                              return -ENODEV;
-+                      return dev_mc_delete(dev, ifr->ifr_hwaddr.sa_data,
-+                                           dev->addr_len, 1);
-+
-+              case SIOCGIFINDEX:
-+                      ifr->ifr_ifindex = dev->ifindex;
-+                      return 0;
-+
-+              case SIOCGIFTXQLEN:
-+                      ifr->ifr_qlen = dev->tx_queue_len;
-+                      return 0;
-+
-+              case SIOCSIFTXQLEN:
-+                      if (ifr->ifr_qlen < 0)
-+                              return -EINVAL;
-+                      dev->tx_queue_len = ifr->ifr_qlen;
-+                      return 0;
-+
-+              case SIOCSIFNAME:
-+                      ifr->ifr_newname[IFNAMSIZ-1] = '\0';
-+                      return dev_change_name(dev, ifr->ifr_newname);
-+
-+              /*
-+               *      Unknown or private ioctl
-+               */
-+
-+              default:
-+                      if ((cmd >= SIOCDEVPRIVATE &&
-+                          cmd <= SIOCDEVPRIVATE + 15) ||
-+                          cmd == SIOCBONDENSLAVE ||
-+                          cmd == SIOCBONDRELEASE ||
-+                          cmd == SIOCBONDSETHWADDR ||
-+                          cmd == SIOCBONDSLAVEINFOQUERY ||
-+                          cmd == SIOCBONDINFOQUERY ||
-+                          cmd == SIOCBONDCHANGEACTIVE ||
-+                          cmd == SIOCGMIIPHY ||
-+                          cmd == SIOCGMIIREG ||
-+                          cmd == SIOCSMIIREG ||
-+                          cmd == SIOCBRADDIF ||
-+                          cmd == SIOCBRDELIF ||
-+                          cmd == SIOCWANDEV) {
-+                              err = -EOPNOTSUPP;
-+                              if (dev->do_ioctl) {
-+                                      if (netif_device_present(dev))
-+                                              err = dev->do_ioctl(dev, ifr,
-+                                                                  cmd);
-+                                      else
-+                                              err = -ENODEV;
-+                              }
-+                      } else
-+                              err = -EINVAL;
-+
-+      }
-+      return err;
-+}
-+
-+/*
-+ *    This function handles all "interface"-type I/O control requests. The actual
-+ *    'doing' part of this is dev_ifsioc above.
-+ */
-+
-+/**
-+ *    dev_ioctl       -       network device ioctl
-+ *    @cmd: command to issue
-+ *    @arg: pointer to a struct ifreq in user space
-+ *
-+ *    Issue ioctl functions to devices. This is normally called by the
-+ *    user space syscall interfaces but can sometimes be useful for
-+ *    other purposes. The return value is the return from the syscall if
-+ *    positive or a negative errno code on error.
-+ */
-+
-+int dev_ioctl(unsigned int cmd, void __user *arg)
-+{
-+      struct ifreq ifr;
-+      int ret;
-+      char *colon;
-+
-+      /* One special case: SIOCGIFCONF takes ifconf argument
-+         and requires shared lock, because it sleeps writing
-+         to user space.
-+       */
-+
-+      if (cmd == SIOCGIFCONF) {
-+              rtnl_shlock();
-+              ret = dev_ifconf((char __user *) arg);
-+              rtnl_shunlock();
-+              return ret;
-+      }
-+      if (cmd == SIOCGIFNAME)
-+              return dev_ifname((struct ifreq __user *)arg);
-+
-+      if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
-+              return -EFAULT;
-+
-+      ifr.ifr_name[IFNAMSIZ-1] = 0;
-+
-+      colon = strchr(ifr.ifr_name, ':');
-+      if (colon)
-+              *colon = 0;
-+
-+      /*
-+       *      See which interface the caller is talking about.
-+       */
-+
-+      switch (cmd) {
-+              /*
-+               *      These ioctl calls:
-+               *      - can be done by all.
-+               *      - atomic and do not require locking.
-+               *      - return a value
-+               */
-+              case SIOCGIFFLAGS:
-+              case SIOCGIFMETRIC:
-+              case SIOCGIFMTU:
-+              case SIOCGIFHWADDR:
-+              case SIOCGIFSLAVE:
-+              case SIOCGIFMAP:
-+              case SIOCGIFINDEX:
-+              case SIOCGIFTXQLEN:
-+                      dev_load(ifr.ifr_name);
-+                      read_lock(&dev_base_lock);
-+                      ret = dev_ifsioc(&ifr, cmd);
-+                      read_unlock(&dev_base_lock);
-+                      if (!ret) {
-+                              if (colon)
-+                                      *colon = ':';
-+                              if (copy_to_user(arg, &ifr,
-+                                               sizeof(struct ifreq)))
-+                                      ret = -EFAULT;
-+                      }
-+                      return ret;
-+
-+              case SIOCETHTOOL:
-+                      dev_load(ifr.ifr_name);
-+                      rtnl_lock();
-+                      ret = dev_ethtool(&ifr);
-+                      rtnl_unlock();
-+                      if (!ret) {
-+                              if (colon)
-+                                      *colon = ':';
-+                              if (copy_to_user(arg, &ifr,
-+                                               sizeof(struct ifreq)))
-+                                      ret = -EFAULT;
-+                      }
-+                      return ret;
-+
-+              /*
-+               *      These ioctl calls:
-+               *      - require superuser power.
-+               *      - require strict serialization.
-+               *      - return a value
-+               */
-+              case SIOCGMIIPHY:
-+              case SIOCGMIIREG:
-+              case SIOCSIFNAME:
-+                      if (!capable(CAP_NET_ADMIN))
-+                              return -EPERM;
-+                      dev_load(ifr.ifr_name);
-+                      rtnl_lock();
-+                      ret = dev_ifsioc(&ifr, cmd);
-+                      rtnl_unlock();
-+                      if (!ret) {
-+                              if (colon)
-+                                      *colon = ':';
-+                              if (copy_to_user(arg, &ifr,
-+                                               sizeof(struct ifreq)))
-+                                      ret = -EFAULT;
-+                      }
-+                      return ret;
-+
-+              /*
-+               *      These ioctl calls:
-+               *      - require superuser power.
-+               *      - require strict serialization.
-+               *      - do not return a value
-+               */
-+              case SIOCSIFFLAGS:
-+              case SIOCSIFMETRIC:
-+              case SIOCSIFMTU:
-+              case SIOCSIFMAP:
-+              case SIOCSIFHWADDR:
-+              case SIOCSIFSLAVE:
-+              case SIOCADDMULTI:
-+              case SIOCDELMULTI:
-+              case SIOCSIFHWBROADCAST:
-+              case SIOCSIFTXQLEN:
-+              case SIOCSMIIREG:
-+              case SIOCBONDENSLAVE:
-+              case SIOCBONDRELEASE:
-+              case SIOCBONDSETHWADDR:
-+              case SIOCBONDSLAVEINFOQUERY:
-+              case SIOCBONDINFOQUERY:
-+              case SIOCBONDCHANGEACTIVE:
-+              case SIOCBRADDIF:
-+              case SIOCBRDELIF:
-+                      if (!capable(CAP_NET_ADMIN))
-+                              return -EPERM;
-+                      dev_load(ifr.ifr_name);
-+                      rtnl_lock();
-+                      ret = dev_ifsioc(&ifr, cmd);
-+                      rtnl_unlock();
-+                      return ret;
-+
-+              case SIOCGIFMEM:
-+                      /* Get the per device memory space. We can add this but
-+                       * currently do not support it */
-+              case SIOCSIFMEM:
-+                      /* Set the per device memory buffer space.
-+                       * Not applicable in our case */
-+              case SIOCSIFLINK:
-+                      return -EINVAL;
-+
-+              /*
-+               *      Unknown or private ioctl.
-+               */
-+              default:
-+                      if (cmd == SIOCWANDEV ||
-+                          (cmd >= SIOCDEVPRIVATE &&
-+                           cmd <= SIOCDEVPRIVATE + 15)) {
-+                              dev_load(ifr.ifr_name);
-+                              rtnl_lock();
-+                              ret = dev_ifsioc(&ifr, cmd);
-+                              rtnl_unlock();
-+                              if (!ret && copy_to_user(arg, &ifr,
-+                                                       sizeof(struct ifreq)))
-+                                      ret = -EFAULT;
-+                              return ret;
-+                      }
-+#ifdef WIRELESS_EXT
-+                      /* Take care of Wireless Extensions */
-+                      if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
-+                              /* If command is `set a parameter', or
-+                               * `get the encoding parameters', check if
-+                               * the user has the right to do it */
-+                              if (IW_IS_SET(cmd) || cmd == SIOCGIWENCODE) {
-+                                      if (!capable(CAP_NET_ADMIN))
-+                                              return -EPERM;
-+                              }
-+                              dev_load(ifr.ifr_name);
-+                              rtnl_lock();
-+                              /* Follow me in net/core/wireless.c */
-+                              ret = wireless_process_ioctl(&ifr, cmd);
-+                              rtnl_unlock();
-+                              if (IW_IS_GET(cmd) &&
-+                                  copy_to_user(arg, &ifr,
-+                                               sizeof(struct ifreq)))
-+                                      ret = -EFAULT;
-+                              return ret;
-+                      }
-+#endif        /* WIRELESS_EXT */
-+                      return -EINVAL;
-+      }
-+}
-+
-+
-+/**
-+ *    dev_new_index   -       allocate an ifindex
-+ *
-+ *    Returns a suitable unique value for a new device interface
-+ *    number.  The caller must hold the rtnl semaphore or the
-+ *    dev_base_lock to be sure it remains unique.
-+ */
-+static int dev_new_index(void)
-+{
-+      static int ifindex;
-+      for (;;) {
-+              if (++ifindex <= 0)
-+                      ifindex = 1;
-+              if (!__dev_get_by_index(ifindex))
-+                      return ifindex;
-+      }
-+}
-+
-+static int dev_boot_phase = 1;
-+
-+/* Delayed registration/unregisteration */
-+static DEFINE_SPINLOCK(net_todo_list_lock);
-+static struct list_head net_todo_list = LIST_HEAD_INIT(net_todo_list);
-+
-+static inline void net_set_todo(struct net_device *dev)
-+{
-+      spin_lock(&net_todo_list_lock);
-+      list_add_tail(&dev->todo_list, &net_todo_list);
-+      spin_unlock(&net_todo_list_lock);
-+}
-+
-+/**
-+ *    register_netdevice      - register a network device
-+ *    @dev: device to register
-+ *
-+ *    Take a completed network device structure and add it to the kernel
-+ *    interfaces. A %NETDEV_REGISTER message is sent to the netdev notifier
-+ *    chain. 0 is returned on success. A negative errno code is returned
-+ *    on a failure to set up the device, or if the name is a duplicate.
-+ *
-+ *    Callers must hold the rtnl semaphore. You may want
-+ *    register_netdev() instead of this.
-+ *
-+ *    BUGS:
-+ *    The locking appears insufficient to guarantee two parallel registers
-+ *    will not get the same name.
-+ */
-+
-+int register_netdevice(struct net_device *dev)
-+{
-+      struct hlist_head *head;
-+      struct hlist_node *p;
-+      int ret;
-+
-+      BUG_ON(dev_boot_phase);
-+      ASSERT_RTNL();
-+
-+      /* When net_device's are persistent, this will be fatal. */
-+      BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
-+
-+      spin_lock_init(&dev->queue_lock);
-+      spin_lock_init(&dev->xmit_lock);
-+      dev->xmit_lock_owner = -1;
-+#ifdef CONFIG_NET_CLS_ACT
-+      spin_lock_init(&dev->ingress_lock);
-+#endif
-+
-+      ret = alloc_divert_blk(dev);
-+      if (ret)
-+              goto out;
-+
-+      dev->iflink = -1;
-+
-+      /* Init, if this function is available */
-+      if (dev->init) {
-+              ret = dev->init(dev);
-+              if (ret) {
-+                      if (ret > 0)
-+                              ret = -EIO;
-+                      goto out_err;
-+              }
-+      }
-+ 
-+      if (!dev_valid_name(dev->name)) {
-+              ret = -EINVAL;
-+              goto out_err;
-+      }
-+
-+      dev->ifindex = dev_new_index();
-+      if (dev->iflink == -1)
-+              dev->iflink = dev->ifindex;
-+
-+      /* Check for existence of name */
-+      head = dev_name_hash(dev->name);
-+      hlist_for_each(p, head) {
-+              struct net_device *d
-+                      = hlist_entry(p, struct net_device, name_hlist);
-+              if (!strncmp(d->name, dev->name, IFNAMSIZ)) {
-+                      ret = -EEXIST;
-+                      goto out_err;
-+              }
-+      }
-+
-+      /* Fix illegal SG+CSUM combinations. */
-+      if ((dev->features & NETIF_F_SG) &&
-+          !(dev->features & (NETIF_F_IP_CSUM |
-+                             NETIF_F_NO_CSUM |
-+                             NETIF_F_HW_CSUM))) {
-+              printk("%s: Dropping NETIF_F_SG since no checksum feature.\n",
-+                     dev->name);
-+              dev->features &= ~NETIF_F_SG;
-+      }
-+
-+      /* TSO requires that SG is present as well. */
-+      if ((dev->features & NETIF_F_TSO) &&
-+          !(dev->features & NETIF_F_SG)) {
-+              printk("%s: Dropping NETIF_F_TSO since no SG feature.\n",
-+                     dev->name);
-+              dev->features &= ~NETIF_F_TSO;
-+      }
-+
-+      /*
-+       *      nil rebuild_header routine,
-+       *      that should be never called and used as just bug trap.
-+       */
-+
-+      if (!dev->rebuild_header)
-+              dev->rebuild_header = default_rebuild_header;
-+
-+      /*
-+       *      Default initial state at registry is that the
-+       *      device is present.
-+       */
-+
-+      set_bit(__LINK_STATE_PRESENT, &dev->state);
-+
-+      dev->next = NULL;
-+      dev_init_scheduler(dev);
-+      write_lock_bh(&dev_base_lock);
-+      *dev_tail = dev;
-+      dev_tail = &dev->next;
-+      hlist_add_head(&dev->name_hlist, head);
-+      hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex));
-+      dev_hold(dev);
-+      dev->reg_state = NETREG_REGISTERING;
-+      write_unlock_bh(&dev_base_lock);
-+
-+      /* Notify protocols, that a new device appeared. */
-+      notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
-+
-+      /* Finish registration after unlock */
-+      net_set_todo(dev);
-+      ret = 0;
-+
-+out:
-+      return ret;
-+out_err:
-+      free_divert_blk(dev);
-+      goto out;
-+}
-+
-+/**
-+ *    register_netdev - register a network device
-+ *    @dev: device to register
-+ *
-+ *    Take a completed network device structure and add it to the kernel
-+ *    interfaces. A %NETDEV_REGISTER message is sent to the netdev notifier
-+ *    chain. 0 is returned on success. A negative errno code is returned
-+ *    on a failure to set up the device, or if the name is a duplicate.
-+ *
-+ *    This is a wrapper around register_netdev that takes the rtnl semaphore
-+ *    and expands the device name if you passed a format string to
-+ *    alloc_netdev.
-+ */
-+int register_netdev(struct net_device *dev)
-+{
-+      int err;
-+
-+      rtnl_lock();
-+
-+      /*
-+       * If the name is a format string the caller wants us to do a
-+       * name allocation.
-+       */
-+      if (strchr(dev->name, '%')) {
-+              err = dev_alloc_name(dev, dev->name);
-+              if (err < 0)
-+                      goto out;
-+      }
-+      
-+      /*
-+       * Back compatibility hook. Kill this one in 2.5
-+       */
-+      if (dev->name[0] == 0 || dev->name[0] == ' ') {
-+              err = dev_alloc_name(dev, "eth%d");
-+              if (err < 0)
-+                      goto out;
-+      }
-+
-+      err = register_netdevice(dev);
-+out:
-+      rtnl_unlock();
-+      return err;
-+}
-+EXPORT_SYMBOL(register_netdev);
-+
-+/*
-+ * netdev_wait_allrefs - wait until all references are gone.
-+ *
-+ * This is called when unregistering network devices.
-+ *
-+ * Any protocol or device that holds a reference should register
-+ * for netdevice notification, and cleanup and put back the
-+ * reference if they receive an UNREGISTER event.
-+ * We can get stuck here if buggy protocols don't correctly
-+ * call dev_put. 
-+ */
-+static void netdev_wait_allrefs(struct net_device *dev)
-+{
-+      unsigned long rebroadcast_time, warning_time;
-+
-+      rebroadcast_time = warning_time = jiffies;
-+      while (atomic_read(&dev->refcnt) != 0) {
-+              if (time_after(jiffies, rebroadcast_time + 1 * HZ)) {
-+                      rtnl_shlock();
-+
-+                      /* Rebroadcast unregister notification */
-+                      notifier_call_chain(&netdev_chain,
-+                                          NETDEV_UNREGISTER, dev);
-+
-+                      if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
-+                                   &dev->state)) {
-+                              /* We must not have linkwatch events
-+                               * pending on unregister. If this
-+                               * happens, we simply run the queue
-+                               * unscheduled, resulting in a noop
-+                               * for this device.
-+                               */
-+                              linkwatch_run_queue();
-+                      }
-+
-+                      rtnl_shunlock();
-+
-+                      rebroadcast_time = jiffies;
-+              }
-+
-+              msleep(250);
-+
-+              if (time_after(jiffies, warning_time + 10 * HZ)) {
-+                      printk(KERN_EMERG "unregister_netdevice: "
-+                             "waiting for %s to become free. Usage "
-+                             "count = %d\n",
-+                             dev->name, atomic_read(&dev->refcnt));
-+                      warning_time = jiffies;
-+              }
-+      }
-+}
-+
-+/* The sequence is:
-+ *
-+ *    rtnl_lock();
-+ *    ...
-+ *    register_netdevice(x1);
-+ *    register_netdevice(x2);
-+ *    ...
-+ *    unregister_netdevice(y1);
-+ *    unregister_netdevice(y2);
-+ *      ...
-+ *    rtnl_unlock();
-+ *    free_netdev(y1);
-+ *    free_netdev(y2);
-+ *
-+ * We are invoked by rtnl_unlock() after it drops the semaphore.
-+ * This allows us to deal with problems:
-+ * 1) We can create/delete sysfs objects which invoke hotplug
-+ *    without deadlocking with linkwatch via keventd.
-+ * 2) Since we run with the RTNL semaphore not held, we can sleep
-+ *    safely in order to wait for the netdev refcnt to drop to zero.
-+ */
-+static DECLARE_MUTEX(net_todo_run_mutex);
-+void netdev_run_todo(void)
-+{
-+      struct list_head list = LIST_HEAD_INIT(list);
-+      int err;
-+
-+
-+      /* Need to guard against multiple cpu's getting out of order. */
-+      down(&net_todo_run_mutex);
-+
-+      /* Not safe to do outside the semaphore.  We must not return
-+       * until all unregister events invoked by the local processor
-+       * have been completed (either by this todo run, or one on
-+       * another cpu).
-+       */
-+      if (list_empty(&net_todo_list))
-+              goto out;
-+
-+      /* Snapshot list, allow later requests */
-+      spin_lock(&net_todo_list_lock);
-+      list_splice_init(&net_todo_list, &list);
-+      spin_unlock(&net_todo_list_lock);
-+              
-+      while (!list_empty(&list)) {
-+              struct net_device *dev
-+                      = list_entry(list.next, struct net_device, todo_list);
-+              list_del(&dev->todo_list);
-+
-+              switch(dev->reg_state) {
-+              case NETREG_REGISTERING:
-+                      err = netdev_register_sysfs(dev);
-+                      if (err)
-+                              printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
-+                                     dev->name, err);
-+                      dev->reg_state = NETREG_REGISTERED;
-+                      break;
-+
-+              case NETREG_UNREGISTERING:
-+                      netdev_unregister_sysfs(dev);
-+                      dev->reg_state = NETREG_UNREGISTERED;
-+
-+                      netdev_wait_allrefs(dev);
-+
-+                      /* paranoia */
-+                      BUG_ON(atomic_read(&dev->refcnt));
-+                      BUG_TRAP(!dev->ip_ptr);
-+                      BUG_TRAP(!dev->ip6_ptr);
-+                      BUG_TRAP(!dev->dn_ptr);
-+
-+
-+                      /* It must be the very last action, 
-+                       * after this 'dev' may point to freed up memory.
-+                       */
-+                      if (dev->destructor)
-+                              dev->destructor(dev);
-+                      break;
-+
-+              default:
-+                      printk(KERN_ERR "network todo '%s' but state %d\n",
-+                             dev->name, dev->reg_state);
-+                      break;
-+              }
-+      }
-+
-+out:
-+      up(&net_todo_run_mutex);
-+}
-+
-+/**
-+ *    alloc_netdev - allocate network device
-+ *    @sizeof_priv:   size of private data to allocate space for
-+ *    @name:          device name format string
-+ *    @setup:         callback to initialize device
-+ *
-+ *    Allocates a struct net_device with private data area for driver use
-+ *    and performs basic initialization.
-+ */
-+struct net_device *alloc_netdev(int sizeof_priv, const char *name,
-+              void (*setup)(struct net_device *))
-+{
-+      void *p;
-+      struct net_device *dev;
-+      int alloc_size;
-+
-+      /* ensure 32-byte alignment of both the device and private area */
-+      alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST;
-+      alloc_size += sizeof_priv + NETDEV_ALIGN_CONST;
-+
-+      p = kmalloc(alloc_size, GFP_KERNEL);
-+      if (!p) {
-+              printk(KERN_ERR "alloc_dev: Unable to allocate device.\n");
-+              return NULL;
-+      }
-+      memset(p, 0, alloc_size);
-+
-+      dev = (struct net_device *)
-+              (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
-+      dev->padded = (char *)dev - (char *)p;
-+
-+      if (sizeof_priv)
-+              dev->priv = netdev_priv(dev);
-+
-+      setup(dev);
-+      strcpy(dev->name, name);
-+      return dev;
-+}
-+EXPORT_SYMBOL(alloc_netdev);
-+
-+/**
-+ *    free_netdev - free network device
-+ *    @dev: device
-+ *
-+ *    This function does the last stage of destroying an allocated device 
-+ *    interface. The reference to the device object is released.  
-+ *    If this is the last reference then it will be freed.
-+ */
-+void free_netdev(struct net_device *dev)
-+{
-+#ifdef CONFIG_SYSFS
-+      /*  Compatiablity with error handling in drivers */
-+      if (dev->reg_state == NETREG_UNINITIALIZED) {
-+              kfree((char *)dev - dev->padded);
-+              return;
-+      }
-+
-+      BUG_ON(dev->reg_state != NETREG_UNREGISTERED);
-+      dev->reg_state = NETREG_RELEASED;
-+
-+      /* will free via class release */
-+      class_device_put(&dev->class_dev);
-+#else
-+      kfree((char *)dev - dev->padded);
-+#endif
-+}
-+ 
-+/* Synchronize with packet receive processing. */
-+void synchronize_net(void) 
-+{
-+      might_sleep();
-+      synchronize_rcu();
-+}
-+
-+/**
-+ *    unregister_netdevice - remove device from the kernel
-+ *    @dev: device
-+ *
-+ *    This function shuts down a device interface and removes it
-+ *    from the kernel tables. On success 0 is returned, on a failure
-+ *    a negative errno code is returned.
-+ *
-+ *    Callers must hold the rtnl semaphore.  You may want
-+ *    unregister_netdev() instead of this.
-+ */
-+
-+int unregister_netdevice(struct net_device *dev)
-+{
-+      struct net_device *d, **dp;
-+
-+      BUG_ON(dev_boot_phase);
-+      ASSERT_RTNL();
-+
-+      /* Some devices call without registering for initialization unwind. */
-+      if (dev->reg_state == NETREG_UNINITIALIZED) {
-+              printk(KERN_DEBUG "unregister_netdevice: device %s/%p never "
-+                                "was registered\n", dev->name, dev);
-+              return -ENODEV;
-+      }
-+
-+      BUG_ON(dev->reg_state != NETREG_REGISTERED);
-+
-+      /* If device is running, close it first. */
-+      if (dev->flags & IFF_UP)
-+              dev_close(dev);
-+
-+      /* And unlink it from device chain. */
-+      for (dp = &dev_base; (d = *dp) != NULL; dp = &d->next) {
-+              if (d == dev) {
-+                      write_lock_bh(&dev_base_lock);
-+                      hlist_del(&dev->name_hlist);
-+                      hlist_del(&dev->index_hlist);
-+                      if (dev_tail == &dev->next)
-+                              dev_tail = dp;
-+                      *dp = d->next;
-+                      write_unlock_bh(&dev_base_lock);
-+                      break;
-+              }
-+      }
-+      if (!d) {
-+              printk(KERN_ERR "unregister net_device: '%s' not found\n",
-+                     dev->name);
-+              return -ENODEV;
-+      }
-+
-+      dev->reg_state = NETREG_UNREGISTERING;
-+
-+      synchronize_net();
-+
-+      /* Shutdown queueing discipline. */
-+      dev_shutdown(dev);
-+
-+      
-+      /* Notify protocols, that we are about to destroy
-+         this device. They should clean all the things.
-+      */
-+      notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
-+      
-+      /*
-+       *      Flush the multicast chain
-+       */
-+      dev_mc_discard(dev);
-+
-+      if (dev->uninit)
-+              dev->uninit(dev);
-+
-+      /* Notifier chain MUST detach us from master device. */
-+      BUG_TRAP(!dev->master);
-+
-+      free_divert_blk(dev);
-+
-+      /* Finish processing unregister after unlock */
-+      net_set_todo(dev);
-+
-+      synchronize_net();
-+
-+      dev_put(dev);
-+      return 0;
-+}
-+
-+/**
-+ *    unregister_netdev - remove device from the kernel
-+ *    @dev: device
-+ *
-+ *    This function shuts down a device interface and removes it
-+ *    from the kernel tables. On success 0 is returned, on a failure
-+ *    a negative errno code is returned.
-+ *
-+ *    This is just a wrapper for unregister_netdevice that takes
-+ *    the rtnl semaphore.  In general you want to use this and not
-+ *    unregister_netdevice.
-+ */
-+void unregister_netdev(struct net_device *dev)
-+{
-+      rtnl_lock();
-+      unregister_netdevice(dev);
-+      rtnl_unlock();
-+}
-+
-+EXPORT_SYMBOL(unregister_netdev);
-+
-+#ifdef CONFIG_HOTPLUG_CPU
-+static int dev_cpu_callback(struct notifier_block *nfb,
-+                          unsigned long action,
-+                          void *ocpu)
-+{
-+      struct sk_buff **list_skb;
-+      struct net_device **list_net;
-+      struct sk_buff *skb;
-+      unsigned int cpu, oldcpu = (unsigned long)ocpu;
-+      struct softnet_data *sd, *oldsd;
-+
-+      if (action != CPU_DEAD)
-+              return NOTIFY_OK;
-+
-+      local_irq_disable();
-+      cpu = smp_processor_id();
-+      sd = &per_cpu(softnet_data, cpu);
-+      oldsd = &per_cpu(softnet_data, oldcpu);
-+
-+      /* Find end of our completion_queue. */
-+      list_skb = &sd->completion_queue;
-+      while (*list_skb)
-+              list_skb = &(*list_skb)->next;
-+      /* Append completion queue from offline CPU. */
-+      *list_skb = oldsd->completion_queue;
-+      oldsd->completion_queue = NULL;
-+
-+      /* Find end of our output_queue. */
-+      list_net = &sd->output_queue;
-+      while (*list_net)
-+              list_net = &(*list_net)->next_sched;
-+      /* Append output queue from offline CPU. */
-+      *list_net = oldsd->output_queue;
-+      oldsd->output_queue = NULL;
-+
-+      raise_softirq_irqoff(NET_TX_SOFTIRQ);
-+      local_irq_enable();
-+
-+      /* Process offline CPU's input_pkt_queue */
-+      while ((skb = __skb_dequeue(&oldsd->input_pkt_queue)))
-+              netif_rx(skb);
-+
-+      return NOTIFY_OK;
-+}
-+#endif /* CONFIG_HOTPLUG_CPU */
-+
-+
-+/*
-+ *    Initialize the DEV module. At boot time this walks the device list and
-+ *    unhooks any devices that fail to initialise (normally hardware not
-+ *    present) and leaves us with a valid list of present and active devices.
-+ *
-+ */
-+
-+/*
-+ *       This is called single threaded during boot, so no need
-+ *       to take the rtnl semaphore.
-+ */
-+static int __init net_dev_init(void)
-+{
-+      int i, rc = -ENOMEM;
-+
-+      BUG_ON(!dev_boot_phase);
-+
-+      net_random_init();
-+
-+      if (dev_proc_init())
-+              goto out;
-+
-+      if (netdev_sysfs_init())
-+              goto out;
-+
-+      INIT_LIST_HEAD(&ptype_all);
-+      for (i = 0; i < 16; i++) 
-+              INIT_LIST_HEAD(&ptype_base[i]);
-+
-+      for (i = 0; i < ARRAY_SIZE(dev_name_head); i++)
-+              INIT_HLIST_HEAD(&dev_name_head[i]);
-+
-+      for (i = 0; i < ARRAY_SIZE(dev_index_head); i++)
-+              INIT_HLIST_HEAD(&dev_index_head[i]);
-+
-+      /*
-+       *      Initialise the packet receive queues.
-+       */
-+
-+      for (i = 0; i < NR_CPUS; i++) {
-+              struct softnet_data *queue;
-+
-+              queue = &per_cpu(softnet_data, i);
-+              skb_queue_head_init(&queue->input_pkt_queue);
-+              queue->throttle = 0;
-+              queue->cng_level = 0;
-+              queue->avg_blog = 10; /* arbitrary non-zero */
-+              queue->completion_queue = NULL;
-+              INIT_LIST_HEAD(&queue->poll_list);
-+              set_bit(__LINK_STATE_START, &queue->backlog_dev.state);
-+              queue->backlog_dev.weight = weight_p;
-+              queue->backlog_dev.poll = process_backlog;
-+              atomic_set(&queue->backlog_dev.refcnt, 1);
-+      }
-+
-+#ifdef OFFLINE_SAMPLE
-+      samp_timer.expires = jiffies + (10 * HZ);
-+      add_timer(&samp_timer);
-+#endif
-+
-+      dev_boot_phase = 0;
-+
-+      open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
-+      open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL);
-+
-+      hotcpu_notifier(dev_cpu_callback, 0);
-+      dst_init();
-+      dev_mcast_init();
-+      rc = 0;
-+out:
-+      return rc;
-+}
-+
-+subsys_initcall(net_dev_init);
-+
-+EXPORT_SYMBOL(__dev_get_by_index);
-+EXPORT_SYMBOL(__dev_get_by_name);
-+EXPORT_SYMBOL(__dev_remove_pack);
-+EXPORT_SYMBOL(__skb_linearize);
-+EXPORT_SYMBOL(dev_add_pack);
-+EXPORT_SYMBOL(dev_alloc_name);
-+EXPORT_SYMBOL(dev_close);
-+EXPORT_SYMBOL(dev_get_by_flags);
-+EXPORT_SYMBOL(dev_get_by_index);
-+EXPORT_SYMBOL(dev_get_by_name);
-+EXPORT_SYMBOL(dev_ioctl);
-+EXPORT_SYMBOL(dev_open);
-+EXPORT_SYMBOL(dev_queue_xmit);
-+EXPORT_SYMBOL(dev_remove_pack);
-+EXPORT_SYMBOL(dev_set_allmulti);
-+EXPORT_SYMBOL(dev_set_promiscuity);
-+EXPORT_SYMBOL(dev_change_flags);
-+EXPORT_SYMBOL(dev_set_mtu);
-+EXPORT_SYMBOL(dev_set_mac_address);
-+EXPORT_SYMBOL(free_netdev);
-+EXPORT_SYMBOL(netdev_boot_setup_check);
-+EXPORT_SYMBOL(netdev_set_master);
-+EXPORT_SYMBOL(netdev_state_change);
-+EXPORT_SYMBOL(netif_receive_skb);
-+EXPORT_SYMBOL(netif_rx);
-+EXPORT_SYMBOL(register_gifconf);
-+EXPORT_SYMBOL(register_netdevice);
-+EXPORT_SYMBOL(register_netdevice_notifier);
-+EXPORT_SYMBOL(skb_checksum_help);
-+EXPORT_SYMBOL(synchronize_net);
-+EXPORT_SYMBOL(unregister_netdevice);
-+EXPORT_SYMBOL(unregister_netdevice_notifier);
-+EXPORT_SYMBOL(net_enable_timestamp);
-+EXPORT_SYMBOL(net_disable_timestamp);
-+EXPORT_SYMBOL(dev_get_flags);
-+
-+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-+EXPORT_SYMBOL(br_handle_frame_hook);
-+EXPORT_SYMBOL(br_fdb_get_hook);
-+EXPORT_SYMBOL(br_fdb_put_hook);
-+#endif
-+
-+#ifdef CONFIG_KMOD
-+EXPORT_SYMBOL(dev_load);
-+#endif
-+
-+EXPORT_PER_CPU_SYMBOL(softnet_data);
-diff --unified --recursive --new-file linux-2.6.12.5/net/ring/Kconfig linux-2.6.12.5-1-686-smp-ring3/net/ring/Kconfig
---- linux-2.6.12.5/net/ring/Kconfig    1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-1-686-smp-ring3/net/ring/Kconfig    2005-10-22 23:50:45.539482000 +0200
-@@ -0,0 +1,14 @@
-+config RING
-+      tristate "PF_RING sockets (EXPERIMENTAL)"
-+      depends on EXPERIMENTAL
-+      ---help---
-+        PF_RING socket family, optimized for packet capture.
-+          If a PF_RING socket is bound to an adapter (via the bind() system
-+          call), such adapter will be used in read-only mode until the socket
-+          is destroyed. Whenever an incoming packet is received from the adapter
-+          it will not passed to upper layers, but instead it is copied to a ring
-+          buffer, which in turn is exported to user space applications via mmap.
-+          Please refer to http://luca.ntop.org/Ring.pdf for more.
-+
-+        Say N unless you know what you are doing.
-+
-diff --unified --recursive --new-file linux-2.6.12.5/net/ring/Makefile linux-2.6.12.5-1-686-smp-ring3/net/ring/Makefile
---- linux-2.6.12.5/net/ring/Makefile   1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-1-686-smp-ring3/net/ring/Makefile   2005-10-22 23:50:45.051451500 +0200
-@@ -0,0 +1,7 @@
-+#
-+# Makefile for the ring driver.
-+#
-+
-+obj-m += ring.o
-+
-+ring-objs := ring_packet.o
-diff --unified --recursive --new-file linux-2.6.12.5/net/ring/ring_packet.c linux-2.6.12.5-1-686-smp-ring3/net/ring/ring_packet.c
---- linux-2.6.12.5/net/ring/ring_packet.c      1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-1-686-smp-ring3/net/ring/ring_packet.c      2005-10-22 23:50:45.159458250 +0200
-@@ -0,0 +1,1592 @@
-+/*
-+ *
-+ * (C) 2004-05 - Luca Deri <deri@ntop.org>
-+ *
-+ * This code includes patches courtesy of
-+ * - Jeff Randall <jrandall@nexvu.com>
-+ * - Helmut Manck <helmut.manck@secunet.com>
-+ * - Brad Doctor <bdoctor@ps-ax.com>
-+ *
-+ */
-+
-+/* FIX: add an entry inside the /proc filesystem */
-+
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/in.h>
-+#include <linux/in6.h>
-+#include <linux/init.h>
-+#include <linux/filter.h>
-+#include <linux/ring.h>
-+#include <linux/ip.h>
-+#include <linux/tcp.h>
-+#include <linux/udp.h>
-+#include <linux/list.h>
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+#include <net/xfrm.h>
-+#else
-+#include <linux/poll.h>
-+#endif
-+#include <net/sock.h>
-+#include <asm/io.h>   /* needed for virt_to_phys() */
-+
-+/* #define RING_DEBUG */
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11))
-+static inline int remap_page_range(struct vm_area_struct *vma,
-+                                 unsigned long uvaddr,
-+                                 unsigned long paddr,
-+                                 unsigned long size,
-+                                 pgprot_t prot) {
-+  return(remap_pfn_range(vma, uvaddr, paddr >> PAGE_SHIFT,
-+                       size, prot));
-+}
-+#endif
-+
-+/* ************************************************* */
-+
-+#define CLUSTER_LEN       8
-+
-+struct ring_cluster {
-+  u_short             cluster_id; /* 0 = no cluster */
-+  u_short             num_cluster_elements;
-+  enum cluster_type   hashing_mode;
-+  u_short             hashing_id;
-+  struct sock         *sk[CLUSTER_LEN];
-+  struct ring_cluster *next;      /* NULL = last element of the cluster */
-+};
-+
-+/* ************************************************* */
-+
-+struct ring_element {
-+  struct list_head  list;
-+  struct sock      *sk;
-+};
-+
-+/* ************************************************* */
-+
-+struct ring_opt {
-+  struct net_device *ring_netdev;
-+
-+  /* Cluster */
-+  u_short cluster_id; /* 0 = no cluster */
-+
-+  /* Reflector */
-+  struct net_device *reflector_dev;
-+
-+  /* Packet buffers */
-+  unsigned long order;
-+
-+  /* Ring Slots */
-+  unsigned long ring_memory;
-+  FlowSlotInfo *slots_info; /* Basically it points to ring_memory */
-+  char *ring_slots;  /* Basically it points to ring_memory
-+                      +sizeof(FlowSlotInfo) */
-+
-+  /* Packet Sampling */
-+  u_int pktToSample, sample_rate;
-+
-+  /* BPF Filter */
-+  struct sk_filter *bpfFilter;
-+
-+  /* Locks */
-+  atomic_t num_ring_slots_waiters;
-+  wait_queue_head_t ring_slots_waitqueue;
-+  rwlock_t ring_index_lock;
-+
-+  /* Indexes (Internal) */
-+  u_int insert_page_id, insert_slot_id;
-+};
-+
-+/* ************************************************* */
-+
-+/* List of all ring sockets. */
-+static struct list_head ring_table;
-+
-+/* List of all clusters */
-+static struct ring_cluster *ring_cluster_list;
-+
-+static rwlock_t ring_mgmt_lock = RW_LOCK_UNLOCKED;
-+
-+/* ********************************** */
-+
-+/* Forward */
-+static struct proto_ops ring_ops;
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11))
-+static struct proto ring_proto;
-+#endif
-+
-+static int skb_ring_handler(struct sk_buff *skb, u_char recv_packet,
-+                          u_char real_skb);
-+static int buffer_ring_handler(struct net_device *dev, char *data, int len);
-+static int remove_from_cluster(struct sock *sock, struct ring_opt *pfr);
-+
-+/* Extern */
-+
-+/* ********************************** */
-+
-+/* Defaults */
-+static u_int bucket_len = 128, num_slots = 4096, sample_rate = 1,
-+  transparent_mode = 0, enable_tx_capture = 0;
-+
-+MODULE_PARM(bucket_len, "i");
-+MODULE_PARM_DESC(bucket_len, "Number of ring buckets");
-+MODULE_PARM(num_slots,  "i");
-+MODULE_PARM_DESC(num_slots,  "Number of ring slots");
-+MODULE_PARM(sample_rate, "i");
-+MODULE_PARM_DESC(sample_rate, "Ring packet sample rate");
-+MODULE_PARM(transparent_mode, "i");
-+MODULE_PARM_DESC(transparent_mode,
-+               "Set to 1 to set transparent mode "
-+               "(slower but backwards compatible)");
-+MODULE_PARM(enable_tx_capture, "i");
-+MODULE_PARM_DESC(enable_tx_capture, "Set to 1 to capture outgoing packets");
-+
-+/* ********************************** */
-+
-+#define MIN_QUEUED_PKTS      64
-+#define MAX_QUEUE_LOOPS      64
-+
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+#define ring_sk_datatype(__sk) ((struct ring_opt *)__sk)
-+#define ring_sk(__sk) ((__sk)->sk_protinfo)
-+#else
-+#define ring_sk_datatype(a) (a)
-+#define ring_sk(__sk) ((__sk)->protinfo.pf_ring)
-+#endif
-+
-+/*
-+  int dev_queue_xmit(struct sk_buff *skb)
-+  skb->dev;
-+  struct net_device *dev_get_by_name(const char *name)
-+*/
-+
-+/* ********************************** */
-+
-+static void ring_sock_destruct(struct sock *sk) {
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+  skb_queue_purge(&sk->sk_receive_queue);
-+
-+  if (!sock_flag(sk, SOCK_DEAD)) {
-+#if defined(RING_DEBUG)
-+    printk("Attempt to release alive ring socket: %p\n", sk);
-+#endif
-+    return;
-+  }
-+
-+  BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc));
-+  BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc));
-+#else
-+
-+  BUG_TRAP(atomic_read(&sk->rmem_alloc)==0);
-+  BUG_TRAP(atomic_read(&sk->wmem_alloc)==0);
-+
-+  if (!sk->dead) {
-+#if defined(RING_DEBUG)
-+    printk("Attempt to release alive ring socket: %p\n", sk);
-+#endif
-+    return;
-+  }
-+#endif
-+
-+  kfree(ring_sk(sk));
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
-+  MOD_DEC_USE_COUNT;
-+#endif
-+}
-+
-+/* ********************************** */
-+/*
-+ * ring_insert()
-+ *
-+ * store the sk in a new element and add it
-+ * to the head of the list.
-+ */
-+static inline void ring_insert(struct sock *sk) {
-+  struct ring_element *next;
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: ring_insert()\n");
-+#endif
-+
-+  next = kmalloc(sizeof(struct ring_element), GFP_ATOMIC);
-+  if(next != NULL) {
-+    next->sk = sk;
-+    write_lock_irq(&ring_mgmt_lock);
-+    list_add(&next->list, &ring_table);
-+    write_unlock_irq(&ring_mgmt_lock);
-+  } else {
-+    if (net_ratelimit())
-+      printk("RING: could not kmalloc slot!!\n");
-+  }
-+}
-+
-+/* ********************************** */
-+/*
-+ * ring_remove()
-+ *
-+ * For each of the elements in the list:
-+ *  - check if this is the element we want to delete
-+ *  - if it is, remove it from the list, and free it.
-+ *
-+ * stop when we find the one we're looking for (break),
-+ * or when we reach the end of the list.
-+ */
-+static inline void ring_remove(struct sock *sk) {
-+  struct list_head *ptr;
-+  struct ring_element *entry;
-+
-+
-+  for(ptr = ring_table.next; ptr != &ring_table; ptr = ptr->next) {
-+    entry = list_entry(ptr, struct ring_element, list);
-+
-+    if(entry->sk == sk) {
-+      write_lock_irq(&ring_mgmt_lock);
-+      list_del(ptr);
-+      kfree(ptr);
-+      write_unlock_irq(&ring_mgmt_lock);
-+      break;
-+    }
-+  }
-+
-+}
-+
-+/* ********************************** */
-+
-+static u_int32_t num_queued_pkts(struct ring_opt *pfr) {
-+
-+  if(pfr->ring_slots != NULL) {
-+
-+    u_int32_t tot_insert = pfr->slots_info->insert_idx,
-+#if defined(RING_DEBUG)
-+      tot_read = pfr->slots_info->tot_read, tot_pkts;
-+#else
-+    tot_read = pfr->slots_info->tot_read;
-+#endif
-+
-+    if(tot_insert >= tot_read) {
-+#if defined(RING_DEBUG)
-+      tot_pkts = tot_insert-tot_read;
-+#endif
-+      return(tot_insert-tot_read);
-+    } else {
-+#if defined(RING_DEBUG)
-+      tot_pkts = ((u_int32_t)-1)+tot_insert-tot_read;
-+#endif
-+      return(((u_int32_t)-1)+tot_insert-tot_read);
-+    }
-+
-+#if defined(RING_DEBUG)
-+    printk("-> num_queued_pkts=%d [tot_insert=%d][tot_read=%d]\n",
-+         tot_pkts, tot_insert, tot_read);
-+#endif
-+
-+  } else
-+    return(0);
-+}
-+
-+/* ********************************** */
-+
-+static inline FlowSlot* get_insert_slot(struct ring_opt *pfr) {
-+#if defined(RING_DEBUG)
-+  printk("get_insert_slot(%d)\n", pfr->slots_info->insert_idx);
-+#endif
-+
-+  if(pfr->ring_slots != NULL) {
-+    FlowSlot *slot = (FlowSlot*)&(pfr->ring_slots[pfr->slots_info->insert_idx
-+                                                *pfr->slots_info->slot_len]);
-+    return(slot);
-+  } else
-+    return(NULL);
-+}
-+
-+/* ********************************** */
-+
-+static inline FlowSlot* get_remove_slot(struct ring_opt *pfr) {
-+#if defined(RING_DEBUG)
-+  printk("get_remove_slot(%d)\n", pfr->slots_info->remove_idx);
-+#endif
-+
-+  if(pfr->ring_slots != NULL)
-+    return((FlowSlot*)&(pfr->ring_slots[pfr->slots_info->remove_idx*
-+                                      pfr->slots_info->slot_len]));
-+  else
-+    return(NULL);
-+}
-+
-+/* ********************************** */
-+
-+static void add_skb_to_ring(struct sk_buff *skb,
-+                          struct ring_opt *pfr,
-+                          u_char recv_packet,
-+                          u_char real_skb /* 1=skb 0=faked skb */) {
-+  FlowSlot *theSlot;
-+  int idx, displ;
-+
-+  if(recv_packet) {
-+    /* Hack for identifying a packet received by the e1000 */
-+    if(real_skb) {
-+      displ = SKB_DISPLACEMENT;
-+    } else
-+      displ = 0; /* Received by the e1000 wrapper */
-+  } else
-+    displ = 0;
-+
-+  write_lock(&pfr->ring_index_lock);
-+  pfr->slots_info->tot_pkts++;
-+  write_unlock(&pfr->ring_index_lock);
-+
-+  /* BPF Filtering (from af_packet.c) */
-+  if(pfr->bpfFilter != NULL) {
-+    unsigned res = 1, len;
-+
-+    len = skb->len-skb->data_len;
-+
-+    write_lock(&pfr->ring_index_lock);
-+    skb->data -= displ;
-+    res = sk_run_filter(skb, pfr->bpfFilter->insns, pfr->bpfFilter->len);
-+    skb->data += displ;
-+    write_unlock(&pfr->ring_index_lock);
-+
-+    if(res == 0) {
-+      /* Filter failed */
-+
-+#if defined(RING_DEBUG)
-+      printk("add_skb_to_ring(skb): Filter failed [len=%d][tot=%llu]"
-+           "[insertIdx=%d][pkt_type=%d][cloned=%d]\n",
-+           (int)skb->len, pfr->slots_info->tot_pkts,
-+           pfr->slots_info->insert_idx,
-+           skb->pkt_type, skb->cloned);
-+#endif
-+
-+      return;
-+    }
-+  }
-+
-+  /* ************************** */
-+
-+  if(pfr->sample_rate > 1) {
-+    if(pfr->pktToSample == 0) {
-+      write_lock(&pfr->ring_index_lock);
-+      pfr->pktToSample = pfr->sample_rate;
-+      write_unlock(&pfr->ring_index_lock);
-+    } else {
-+      write_lock(&pfr->ring_index_lock);
-+      pfr->pktToSample--;
-+      write_unlock(&pfr->ring_index_lock);
-+
-+#if defined(RING_DEBUG)
-+      printk("add_skb_to_ring(skb): sampled packet [len=%d]"
-+           "[tot=%llu][insertIdx=%d][pkt_type=%d][cloned=%d]\n",
-+           (int)skb->len, pfr->slots_info->tot_pkts,
-+           pfr->slots_info->insert_idx,
-+           skb->pkt_type, skb->cloned);
-+#endif
-+      return;
-+    }
-+  }
-+
-+  /* ************************************* */
-+
-+  if((pfr->reflector_dev != NULL)
-+     && (!netif_queue_stopped(pfr->reflector_dev))) {
-+    int cpu = smp_processor_id();
-+
-+    /* increase reference counter so that this skb is not freed */
-+    atomic_inc(&skb->users);
-+
-+    skb->data -= displ;
-+
-+    /* send it */
-+    if (pfr->reflector_dev->xmit_lock_owner != cpu) {
-+      spin_lock_bh(&pfr->reflector_dev->xmit_lock);
-+      pfr->reflector_dev->xmit_lock_owner = cpu;
-+      spin_unlock_bh(&pfr->reflector_dev->xmit_lock);
-+
-+      if (pfr->reflector_dev->hard_start_xmit(skb,
-+                                            pfr->reflector_dev) == 0) {
-+        spin_lock_bh(&pfr->reflector_dev->xmit_lock);
-+      pfr->reflector_dev->xmit_lock_owner = -1;
-+      skb->data += displ;
-+      spin_unlock_bh(&pfr->reflector_dev->xmit_lock);
-+#if defined(RING_DEBUG)
-+      printk("++ hard_start_xmit succeeded\n");
-+#endif
-+      return; /* OK */
-+      }
-+
-+      spin_lock_bh(&pfr->reflector_dev->xmit_lock);
-+      pfr->reflector_dev->xmit_lock_owner = -1;
-+      spin_unlock_bh(&pfr->reflector_dev->xmit_lock);
-+    }
-+
-+#if defined(RING_DEBUG)
-+    printk("++ hard_start_xmit failed\n");
-+#endif
-+    skb->data += displ;
-+    return; /* -ENETDOWN */
-+  }
-+
-+  /* ************************************* */
-+
-+#if defined(RING_DEBUG)
-+  printk("add_skb_to_ring(skb) [len=%d][tot=%llu][insertIdx=%d]"
-+       "[pkt_type=%d][cloned=%d]\n",
-+       (int)skb->len, pfr->slots_info->tot_pkts,
-+       pfr->slots_info->insert_idx,
-+       skb->pkt_type, skb->cloned);
-+#endif
-+
-+  idx = pfr->slots_info->insert_idx;
-+  theSlot = get_insert_slot(pfr);
-+
-+  if((theSlot != NULL) && (theSlot->slot_state == 0)) {
-+    struct pcap_pkthdr *hdr;
-+    unsigned int bucketSpace;
-+    char *bucket;
-+
-+    /* Update Index */
-+    idx++;
-+
-+    if(idx == pfr->slots_info->tot_slots) {
-+      write_lock(&pfr->ring_index_lock);
-+      pfr->slots_info->insert_idx = 0;
-+      write_unlock(&pfr->ring_index_lock);
-+    } else {
-+      write_lock(&pfr->ring_index_lock);
-+      pfr->slots_info->insert_idx = idx;
-+      write_unlock(&pfr->ring_index_lock);
-+    }
-+
-+    bucketSpace = pfr->slots_info->slot_len
-+#ifdef RING_MAGIC
-+      - sizeof(u_char)
-+#endif
-+      - sizeof(u_char)  /* flowSlot.slot_state */
-+      - sizeof(struct pcap_pkthdr)
-+      - 1 /* 10 */ /* safe boundary */;
-+
-+    bucket = &theSlot->bucket;
-+    hdr = (struct pcap_pkthdr*)bucket;
-+
-+    if(skb->stamp.tv_sec == 0) do_gettimeofday(&skb->stamp);
-+
-+    hdr->ts.tv_sec = skb->stamp.tv_sec, hdr->ts.tv_usec = skb->stamp.tv_usec;
-+    hdr->caplen    = skb->len+displ;
-+
-+    if(hdr->caplen > bucketSpace)
-+      hdr->caplen = bucketSpace;
-+
-+    hdr->len = skb->len+displ;
-+    memcpy(&bucket[sizeof(struct pcap_pkthdr)],
-+         skb->data-displ, hdr->caplen);
-+
-+#if defined(RING_DEBUG)
-+    {
-+      static unsigned int lastLoss = 0;
-+
-+      if(pfr->slots_info->tot_lost
-+       && (lastLoss != pfr->slots_info->tot_lost)) {
-+      printk("add_skb_to_ring(%d): [bucketSpace=%d]"
-+             "[hdr.caplen=%d][skb->len=%d]"
-+             "[pcap_pkthdr=%d][removeIdx=%d]"
-+             "[loss=%lu][page=%u][slot=%u]\n",
-+             idx-1, bucketSpace, hdr->caplen, skb->len,
-+             sizeof(struct pcap_pkthdr),
-+             pfr->slots_info->remove_idx,
-+             (long unsigned int)pfr->slots_info->tot_lost,
-+             pfr->insert_page_id, pfr->insert_slot_id);
-+
-+      lastLoss = pfr->slots_info->tot_lost;
-+      }
-+    }
-+#endif
-+
-+    write_lock(&pfr->ring_index_lock);
-+    pfr->slots_info->tot_insert++;
-+    theSlot->slot_state = 1;
-+    write_unlock(&pfr->ring_index_lock);
-+  } else {
-+    write_lock(&pfr->ring_index_lock);
-+    pfr->slots_info->tot_lost++;
-+    write_unlock(&pfr->ring_index_lock);
-+
-+#if defined(RING_DEBUG)
-+    printk("add_skb_to_ring(skb): packet lost [loss=%lu]"
-+         "[removeIdx=%u][insertIdx=%u]\n",
-+         (long unsigned int)pfr->slots_info->tot_lost,
-+         pfr->slots_info->remove_idx, pfr->slots_info->insert_idx);
-+#endif
-+  }
-+
-+  /* wakeup in case of poll() */
-+  if(waitqueue_active(&pfr->ring_slots_waitqueue))
-+    wake_up_interruptible(&pfr->ring_slots_waitqueue);
-+}
-+
-+/* ********************************** */
-+
-+static u_int hash_skb(struct ring_cluster *cluster_ptr,
-+                    struct sk_buff *skb, u_char recv_packet) {
-+  u_int idx;
-+  int displ;
-+  struct iphdr *ip;
-+
-+  if(cluster_ptr->hashing_mode == cluster_round_robin) {
-+    idx = cluster_ptr->hashing_id++;
-+  } else {
-+    /* Per-flow clustering */
-+    if(skb->len > sizeof(struct iphdr)+sizeof(struct tcphdr)) {
-+      if(recv_packet)
-+      displ = 0;
-+      else
-+      displ = SKB_DISPLACEMENT;
-+
-+      /*
-+      skb->data+displ
-+
-+      Always points to to the IP part of the packet
-+      */
-+
-+      ip = (struct iphdr*)(skb->data+displ);
-+
-+      idx = ip->saddr+ip->daddr+ip->protocol;
-+
-+      if(ip->protocol == IPPROTO_TCP) {
-+      struct tcphdr *tcp = (struct tcphdr*)(skb->data+displ
-+                                            +sizeof(struct iphdr));
-+      idx += tcp->source+tcp->dest;
-+      } else if(ip->protocol == IPPROTO_UDP) {
-+      struct udphdr *udp = (struct udphdr*)(skb->data+displ
-+                                            +sizeof(struct iphdr));
-+      idx += udp->source+udp->dest;
-+      }
-+    } else
-+      idx = skb->len;
-+  }
-+
-+  return(idx % cluster_ptr->num_cluster_elements);
-+}
-+
-+/* ********************************** */
-+
-+static int skb_ring_handler(struct sk_buff *skb,
-+                          u_char recv_packet,
-+                          u_char real_skb /* 1=skb 0=faked skb */) {
-+  struct sock *skElement;
-+  int rc = 0;
-+  struct list_head *ptr;
-+  struct ring_cluster *cluster_ptr;
-+
-+  if((!skb) /* Invalid skb */
-+     || ((!enable_tx_capture) && (!recv_packet))) {
-+    /*
-+      An outgoing packet is about to be sent out
-+      but we decided not to handle transmitted
-+      packets.
-+    */
-+    return(0);
-+  }
-+
-+#if defined(RING_DEBUG)
-+  if(0) {
-+    printk("skb_ring_handler() [len=%d][dev=%s]\n", skb->len,
-+         skb->dev->name == NULL ? "<NULL>" : skb->dev->name);
-+  }
-+#endif
-+
-+  /* [1] Check unclustered sockets */
-+  for (ptr = ring_table.next; ptr != &ring_table; ptr = ptr->next) {
-+    struct ring_opt *pfr;
-+    struct ring_element *entry;
-+
-+    entry = list_entry(ptr, struct ring_element, list);
-+
-+    read_lock(&ring_mgmt_lock);
-+    skElement = entry->sk;
-+    pfr = ring_sk(skElement);
-+    read_unlock(&ring_mgmt_lock);
-+
-+    if((pfr != NULL)
-+       && (pfr->cluster_id == 0 /* No cluster */)
-+       && (pfr->ring_slots != NULL)
-+       && (pfr->ring_netdev == skb->dev)) {
-+      /* We've found the ring where the packet can be stored */
-+      read_lock(&ring_mgmt_lock);
-+      add_skb_to_ring(skb, pfr, recv_packet, real_skb);
-+      read_unlock(&ring_mgmt_lock);
-+
-+      rc = 1; /* Ring found: we've done our job */
-+    }
-+  }
-+
-+  /* [2] Check socket clusters */
-+  cluster_ptr = ring_cluster_list;
-+
-+  while(cluster_ptr != NULL) {
-+    struct ring_opt *pfr;
-+
-+    if(cluster_ptr->num_cluster_elements > 0) {
-+      u_int skb_hash = hash_skb(cluster_ptr, skb, recv_packet);
-+
-+      read_lock(&ring_mgmt_lock);
-+      skElement = cluster_ptr->sk[skb_hash];
-+      read_unlock(&ring_mgmt_lock);
-+
-+      if(skElement != NULL) {
-+      pfr = ring_sk(skElement);
-+
-+      if((pfr != NULL)
-+         && (pfr->ring_slots != NULL)
-+         && (pfr->ring_netdev == skb->dev)) {
-+        /* We've found the ring where the packet can be stored */
-+          read_lock(&ring_mgmt_lock);
-+        add_skb_to_ring(skb, pfr, recv_packet, real_skb);
-+          read_unlock(&ring_mgmt_lock);
-+
-+        rc = 1; /* Ring found: we've done our job */
-+      }
-+      }
-+    }
-+
-+    cluster_ptr = cluster_ptr->next;
-+  }
-+
-+  if(transparent_mode) rc = 0;
-+
-+  if((rc != 0) && real_skb)
-+    dev_kfree_skb(skb); /* Free the skb */
-+
-+  return(rc); /*  0 = packet not handled */
-+}
-+
-+/* ********************************** */
-+
-+struct sk_buff skb;
-+
-+static int buffer_ring_handler(struct net_device *dev,
-+                             char *data, int len) {
-+
-+#if defined(RING_DEBUG)
-+  printk("buffer_ring_handler: [dev=%s][len=%d]\n",
-+       dev->name == NULL ? "<NULL>" : dev->name, len);
-+#endif
-+
-+  skb.dev = dev, skb.len = len, skb.data = data,
-+    skb.data_len = len, skb.stamp.tv_sec = 0; /* Calculate the time */
-+
-+  skb_ring_handler(&skb, 1, 0 /* fake skb */);
-+
-+  return(0);
-+}
-+
-+/* ********************************** */
-+
-+static int ring_create(struct socket *sock, int protocol) {
-+  struct sock *sk;
-+  struct ring_opt *pfr;
-+  int err;
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: ring_create()\n");
-+#endif
-+
-+  /* Are you root, superuser or so ? */
-+  if(!capable(CAP_NET_ADMIN))
-+    return -EPERM;
-+
-+  if(sock->type != SOCK_RAW)
-+    return -ESOCKTNOSUPPORT;
-+
-+  if(protocol != htons(ETH_P_ALL))
-+    return -EPROTONOSUPPORT;
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
-+  MOD_INC_USE_COUNT;
-+#endif
-+
-+  err = -ENOMEM;
-+
-+  // BD: -- broke this out to keep it more simple and clear as to what the
-+  // options are.
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
-+  sk = sk_alloc(PF_RING, GFP_KERNEL, 1, NULL);
-+#endif
-+#endif
-+
-+  // BD: API changed in 2.6.12, ref:
-+  // http://svn.clkao.org/svnweb/linux/revision/?rev=28201
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11))
-+  sk = sk_alloc(PF_RING, GFP_ATOMIC, &ring_proto, 1);
-+#endif
-+
-+  if (sk == NULL)
-+    goto out;
-+
-+  sock->ops = &ring_ops;
-+  sock_init_data(sock, sk);
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
-+  sk_set_owner(sk, THIS_MODULE);
-+#endif
-+#endif
-+
-+  err = -ENOMEM;
-+  ring_sk(sk) = ring_sk_datatype(kmalloc(sizeof(*pfr), GFP_KERNEL));
-+
-+  if (!(pfr = ring_sk(sk))) {
-+    sk_free(sk);
-+    goto out;
-+  }
-+  memset(pfr, 0, sizeof(*pfr));
-+  init_waitqueue_head(&pfr->ring_slots_waitqueue);
-+  pfr->ring_index_lock = RW_LOCK_UNLOCKED;
-+  atomic_set(&pfr->num_ring_slots_waiters, 0);
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+  sk->sk_family       = PF_RING;
-+  sk->sk_destruct     = ring_sock_destruct;
-+#else
-+  sk->family          = PF_RING;
-+  sk->destruct        = ring_sock_destruct;
-+  sk->num             = protocol;
-+#endif
-+
-+  ring_insert(sk);
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: ring_create() - created\n");
-+#endif
-+
-+  return(0);
-+ out:
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
-+  MOD_DEC_USE_COUNT;
-+#endif
-+  return err;
-+}
-+
-+/* *********************************************** */
-+
-+static int ring_release(struct socket *sock)
-+{
-+  struct sock *sk = sock->sk;
-+  struct ring_opt *pfr = ring_sk(sk);
-+
-+  if(!sk)
-+    return 0;
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: called ring_release\n");
-+#endif
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: ring_release entered\n");
-+#endif
-+
-+  ring_remove(sk);
-+
-+  sock_orphan(sk);
-+  sock->sk = NULL;
-+
-+  /* Free the ring buffer */
-+  if(pfr->ring_memory) {
-+    struct page *page, *page_end;
-+
-+    page_end = virt_to_page(pfr->ring_memory + (PAGE_SIZE << pfr->order) - 1);
-+    for(page = virt_to_page(pfr->ring_memory); page <= page_end; page++)
-+      ClearPageReserved(page);
-+
-+    free_pages(pfr->ring_memory, pfr->order);
-+  }
-+
-+  kfree(pfr);
-+  ring_sk(sk) = NULL;
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+  skb_queue_purge(&sk->sk_write_queue);
-+#endif
-+  sock_put(sk);
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: ring_release leaving\n");
-+#endif
-+
-+  return 0;
-+}
-+
-+/* ********************************** */
-+/*
-+ * We create a ring for this socket and bind it to the specified device
-+ */
-+static int packet_ring_bind(struct sock *sk, struct net_device *dev)
-+{
-+  u_int the_slot_len;
-+  u_int32_t tot_mem;
-+  struct ring_opt *pfr = ring_sk(sk);
-+  struct page *page, *page_end;
-+
-+  if(!dev) return(-1);
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: packet_ring_bind(%s) called\n", dev->name);
-+#endif
-+
-+  /* **********************************************
-+
-+  *************************************
-+  *                                   *
-+  *        FlowSlotInfo               *
-+  *                                   *
-+  ************************************* <-+
-+  *        FlowSlot                   *   |
-+  *************************************   |
-+  *        FlowSlot                   *   |
-+  *************************************   +- num_slots
-+  *        FlowSlot                   *   |
-+  *************************************   |
-+  *        FlowSlot                   *   |
-+  ************************************* <-+
-+
-+  ********************************************** */
-+
-+  the_slot_len = sizeof(u_char)    /* flowSlot.slot_state */
-+    + sizeof(u_short) /* flowSlot.slot_len   */
-+    + bucket_len      /* flowSlot.bucket     */;
-+
-+  tot_mem = sizeof(FlowSlotInfo) + num_slots*the_slot_len;
-+
-+  /*
-+    Calculate the value of the order parameter used later.
-+    See http://www.linuxjournal.com/article.php?sid=1133
-+  */
-+  for(pfr->order = 0;(PAGE_SIZE << pfr->order) < tot_mem; pfr->order++)  ;
-+
-+  /*
-+    We now try to allocate the memory as required. If we fail
-+    we try to allocate a smaller amount or memory (hence a
-+    smaller ring).
-+  */
-+  while((pfr->ring_memory = __get_free_pages(GFP_ATOMIC, pfr->order)) == 0)
-+    if(pfr->order-- == 0)
-+      break;
-+
-+  if(pfr->order == 0) {
-+#if defined(RING_DEBUG)
-+    printk("ERROR: not enough memory\n");
-+#endif
-+    return(-1);
-+  } else {
-+#if defined(RING_DEBUG)
-+    printk("RING: succesfully allocated %lu KB [tot_mem=%d][order=%ld]\n",
-+         PAGE_SIZE >> (10 - pfr->order), tot_mem, pfr->order);
-+#endif
-+  }
-+
-+  tot_mem = PAGE_SIZE << pfr->order;
-+  memset((char*)pfr->ring_memory, 0, tot_mem);
-+
-+  /* Now we need to reserve the pages */
-+  page_end = virt_to_page(pfr->ring_memory + (PAGE_SIZE << pfr->order) - 1);
-+  for(page = virt_to_page(pfr->ring_memory); page <= page_end; page++)
-+    SetPageReserved(page);
-+
-+  pfr->slots_info = (FlowSlotInfo*)pfr->ring_memory;
-+  pfr->ring_slots = (char*)(pfr->ring_memory+sizeof(FlowSlotInfo));
-+
-+  pfr->slots_info->version     = RING_FLOWSLOT_VERSION;
-+  pfr->slots_info->slot_len    = the_slot_len;
-+  pfr->slots_info->tot_slots   = (tot_mem-sizeof(FlowSlotInfo))/the_slot_len;
-+  pfr->slots_info->tot_mem     = tot_mem;
-+  pfr->slots_info->sample_rate = sample_rate;
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: allocated %d slots [slot_len=%d][tot_mem=%u]\n",
-+       pfr->slots_info->tot_slots, pfr->slots_info->slot_len,
-+       pfr->slots_info->tot_mem);
-+#endif
-+
-+#ifdef RING_MAGIC
-+  {
-+    int i;
-+
-+    for(i=0; i<pfr->slots_info->tot_slots; i++) {
-+      unsigned long idx = i*pfr->slots_info->slot_len;
-+      FlowSlot *slot = (FlowSlot*)&pfr->ring_slots[idx];
-+      slot->magic = RING_MAGIC_VALUE; slot->slot_state = 0;
-+    }
-+  }
-+#endif
-+
-+  pfr->insert_page_id = 1, pfr->insert_slot_id = 0;
-+
-+  /*
-+    IMPORTANT
-+    Leave this statement here as last one. In fact when
-+    the ring_netdev != NULL the socket is ready to be used.
-+  */
-+  pfr->ring_netdev = dev;
-+
-+  return(0);
-+}
-+
-+/* ************************************* */
-+
-+/* Bind to a device */
-+static int ring_bind(struct socket *sock,
-+                   struct sockaddr *sa, int addr_len)
-+{
-+  struct sock *sk=sock->sk;
-+  struct net_device *dev = NULL;
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: ring_bind() called\n");
-+#endif
-+
-+  /*
-+   *  Check legality
-+   */
-+  if (addr_len != sizeof(struct sockaddr))
-+    return -EINVAL;
-+  if (sa->sa_family != PF_RING)
-+    return -EINVAL;
-+
-+  /* Safety check: add trailing zero if missing */
-+  sa->sa_data[sizeof(sa->sa_data)-1] = '\0';
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: searching device %s\n", sa->sa_data);
-+#endif
-+
-+  if((dev = __dev_get_by_name(sa->sa_data)) == NULL) {
-+#if defined(RING_DEBUG)
-+    printk("RING: search failed\n");
-+#endif
-+    return(-EINVAL);
-+  } else
-+    return(packet_ring_bind(sk, dev));
-+}
-+
-+/* ************************************* */
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+
-+volatile void* virt_to_kseg(volatile void* address) {
-+  pte_t *pte;
-+  pud_t *pud;
-+  unsigned long addr = (unsigned long)address;
-+                     
-+  pud = pud_offset(pgd_offset_k((unsigned long) address),
-+                 (unsigned long) address);
-+
-+  /*
-+     High-memory support courtesy of
-+     Brad Doctor <bdoctor@ps-ax.com>
-+  */
-+#if defined(CONFIG_X86_PAE) && (!defined(CONFIG_NOHIGHMEM))
-+  pte = pte_offset_map(pmd_offset(pud, addr), addr);
-+#else
-+  pte = pmd_offset_map(pud, addr);
-+#endif
-+
-+  return((volatile void*)pte_page(*pte));
-+}
-+
-+#else /* 2.4 */
-+
-+/* http://www.scs.ch/~frey/linux/memorymap.html */
-+volatile void *virt_to_kseg(volatile void *address)
-+{
-+  pgd_t *pgd; pmd_t *pmd; pte_t *ptep, pte;
-+  unsigned long va, ret = 0UL;
-+
-+  va=VMALLOC_VMADDR((unsigned long)address);
-+
-+  /* get the page directory. Use the kernel memory map. */
-+  pgd = pgd_offset_k(va);
-+
-+  /* check whether we found an entry */
-+  if (!pgd_none(*pgd))
-+    {
-+      /* get the page middle directory */
-+      pmd = pmd_offset(pgd, va);
-+      /* check whether we found an entry */
-+      if (!pmd_none(*pmd))
-+      {
-+        /* get a pointer to the page table entry */
-+        ptep = pte_offset(pmd, va);
-+        pte = *ptep;
-+        /* check for a valid page */
-+        if (pte_present(pte))
-+          {
-+            /* get the address the page is refering to */
-+            ret = (unsigned long)page_address(pte_page(pte));
-+            /* add the offset within the page to the page address */
-+            ret |= (va & (PAGE_SIZE -1));
-+          }
-+      }
-+    }
-+  return((volatile void *)ret);
-+}
-+#endif
-+
-+/* ************************************* */
-+
-+static int ring_mmap(struct file *file,
-+                   struct socket *sock,
-+                   struct vm_area_struct *vma)
-+{
-+  struct sock *sk = sock->sk;
-+  struct ring_opt *pfr = ring_sk(sk);
-+  unsigned long size, start;
-+  u_int pagesToMap;
-+  char *ptr;
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: ring_mmap() called\n");
-+#endif
-+
-+  if(pfr->ring_memory == 0) {
-+#if defined(RING_DEBUG)
-+    printk("RING: ring_mmap() failed: mapping area to an unbound socket\n");
-+#endif
-+    return -EINVAL;
-+  }
-+
-+  size = (unsigned long)(vma->vm_end-vma->vm_start);
-+
-+  if(size % PAGE_SIZE) {
-+#if defined(RING_DEBUG)
-+    printk("RING: ring_mmap() failed: len is not multiple of PAGE_SIZE\n");
-+#endif
-+    return(-EINVAL);
-+  }
-+
-+  /* if userspace tries to mmap beyond end of our buffer, fail */
-+  if(size > pfr->slots_info->tot_mem) {
-+#if defined(RING_DEBUG)
-+    printk("proc_mmap() failed: area too large [%ld > %d]\n", size, pfr->slots_info->tot_mem);
-+#endif
-+    return(-EINVAL);
-+  }
-+
-+  pagesToMap = size/PAGE_SIZE;
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: ring_mmap() called. %d pages to map\n", pagesToMap);
-+#endif
-+
-+#if defined(RING_DEBUG)
-+  printk("RING: mmap [slot_len=%d][tot_slots=%d] for ring on device %s\n",
-+       pfr->slots_info->slot_len, pfr->slots_info->tot_slots,
-+       pfr->ring_netdev->name);
-+#endif
-+
-+  /* we do not want to have this area swapped out, lock it */
-+  vma->vm_flags |= VM_LOCKED;
-+  start = vma->vm_start;
-+
-+  /* Ring slots start from page 1 (page 0 is reserved for FlowSlotInfo) */
-+  ptr = (char*)(start+PAGE_SIZE);
-+
-+  if(remap_page_range(
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+                    vma,
-+#endif
-+                    start,
-+                    __pa(pfr->ring_memory),
-+                    PAGE_SIZE*pagesToMap, vma->vm_page_prot)) {
-+#if defined(RING_DEBUG)
-+    printk("remap_page_range() failed\n");
-+#endif
-+    return(-EAGAIN);
-+  }
-+
-+#if defined(RING_DEBUG)
-+  printk("proc_mmap(pagesToMap=%d): success.\n", pagesToMap);
-+#endif
-+
-+  return 0;
-+}
-+
-+/* ************************************* */
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+static int ring_recvmsg(struct kiocb *iocb, struct socket *sock,
-+                      struct msghdr *msg, size_t len, int flags)
-+#else
-+  static int ring_recvmsg(struct socket *sock, struct msghdr *msg, int len,
-+                        int flags, struct scm_cookie *scm)
-+#endif
-+{
-+  FlowSlot* slot;
-+  struct ring_opt *pfr = ring_sk(sock->sk);
-+  u_int32_t queued_pkts, num_loops = 0;
-+
-+#if defined(RING_DEBUG)
-+  printk("ring_recvmsg called\n");
-+#endif
-+
-+  slot = get_remove_slot(pfr);
-+
-+  while((queued_pkts = num_queued_pkts(pfr)) < MIN_QUEUED_PKTS) {
-+    wait_event_interruptible(pfr->ring_slots_waitqueue, 1);
-+
-+#if defined(RING_DEBUG)
-+    printk("-> ring_recvmsg returning %d [queued_pkts=%d][num_loops=%d]\n",
-+         slot->slot_state, queued_pkts, num_loops);
-+#endif
-+
-+    if(queued_pkts > 0) {
-+      if(num_loops++ > MAX_QUEUE_LOOPS)
-+      break;
-+    }
-+  }
-+
-+#if defined(RING_DEBUG)
-+  if(slot != NULL)
-+    printk("ring_recvmsg is returning [queued_pkts=%d][num_loops=%d]\n",
-+         queued_pkts, num_loops);
-+#endif
-+
-+  return(queued_pkts);
-+}
-+
-+/* ************************************* */
-+
-+unsigned int ring_poll(struct file * file,
-+                     struct socket *sock, poll_table *wait)
-+{
-+  FlowSlot* slot;
-+  struct ring_opt *pfr = ring_sk(sock->sk);
-+
-+#if defined(RING_DEBUG)
-+  printk("poll called\n");
-+#endif
-+
-+  slot = get_remove_slot(pfr);
-+
-+  if((slot != NULL) && (slot->slot_state == 0))
-+    poll_wait(file, &pfr->ring_slots_waitqueue, wait);
-+
-+#if defined(RING_DEBUG)
-+  printk("poll returning %d\n", slot->slot_state);
-+#endif
-+
-+  if((slot != NULL) && (slot->slot_state == 1))
-+    return(POLLIN | POLLRDNORM);
-+  else
-+    return(0);
-+}
-+
-+/* ************************************* */
-+
-+int add_to_cluster_list(struct ring_cluster *el,
-+                      struct sock *sock) {
-+
-+  if(el->num_cluster_elements == CLUSTER_LEN)
-+    return(-1); /* Cluster full */
-+
-+  ring_sk_datatype(ring_sk(sock))->cluster_id = el->cluster_id;
-+  el->sk[el->num_cluster_elements] = sock;
-+  el->num_cluster_elements++;
-+  return(0);
-+}
-+
-+/* ************************************* */
-+
-+int remove_from_cluster_list(struct ring_cluster *el,
-+                           struct sock *sock) {
-+  int i, j;
-+
-+  for(i=0; i<CLUSTER_LEN; i++)
-+    if(el->sk[i] == sock) {
-+      el->num_cluster_elements--;
-+
-+      if(el->num_cluster_elements > 0) {
-+      /* The cluster contains other elements */
-+      for(j=i; j<CLUSTER_LEN-1; j++)
-+        el->sk[j] = el->sk[j+1];
-+
-+      el->sk[CLUSTER_LEN-1] = NULL;
-+      } else {
-+      /* Empty cluster */
-+      memset(el->sk, 0, sizeof(el->sk));
-+      }
-+
-+      return(0);
-+    }
-+
-+  return(-1); /* Not found */
-+}
-+
-+/* ************************************* */
-+
-+static int remove_from_cluster(struct sock *sock,
-+                             struct ring_opt *pfr)
-+{
-+  struct ring_cluster *el;
-+
-+#if defined(RING_DEBUG)
-+  printk("--> remove_from_cluster(%d)\n", pfr->cluster_id);
-+#endif
-+
-+  if(pfr->cluster_id == 0 /* 0 = No Cluster */)
-+    return(0); /* Noting to do */
-+
-+  el = ring_cluster_list;
-+
-+  while(el != NULL) {
-+    if(el->cluster_id == pfr->cluster_id) {
-+      return(remove_from_cluster_list(el, sock));
-+    } else
-+      el = el->next;
-+  }
-+
-+  return(-EINVAL); /* Not found */
-+}
-+
-+/* ************************************* */
-+
-+static int add_to_cluster(struct sock *sock,
-+                        struct ring_opt *pfr,
-+                        u_short cluster_id)
-+{
-+  struct ring_cluster *el;
-+
-+#ifndef RING_DEBUG
-+  printk("--> add_to_cluster(%d)\n", cluster_id);
-+#endif
-+
-+  if(cluster_id == 0 /* 0 = No Cluster */) return(-EINVAL);
-+
-+  if(pfr->cluster_id != 0)
-+    remove_from_cluster(sock, pfr);
-+
-+  el = ring_cluster_list;
-+
-+  while(el != NULL) {
-+    if(el->cluster_id == cluster_id) {
-+      return(add_to_cluster_list(el, sock));
-+    } else
-+      el = el->next;
-+  }
-+
-+  /* There's no existing cluster. We need to create one */
-+  if((el = kmalloc(sizeof(struct ring_cluster), GFP_KERNEL)) == NULL)
-+    return(-ENOMEM);
-+
-+  el->cluster_id = cluster_id;
-+  el->num_cluster_elements = 1;
-+  el->hashing_mode = cluster_per_flow; /* Default */
-+  el->hashing_id   = 0;
-+
-+  memset(el->sk, 0, sizeof(el->sk));
-+  el->sk[0] = sock;
-+  el->next = ring_cluster_list;
-+  ring_cluster_list = el;
-+  pfr->cluster_id = cluster_id;
-+
-+  return(0); /* 0 = OK */
-+}
-+
-+/* ************************************* */
-+
-+/* Code taken/inspired from core/sock.c */
-+static int ring_setsockopt(struct socket *sock,
-+                         int level, int optname,
-+                         char *optval, int optlen)
-+{
-+  struct ring_opt *pfr = ring_sk(sock->sk);
-+  int val, found, ret = 0;
-+  u_int cluster_id;
-+  char devName[8];
-+
-+  if((optlen<sizeof(int)) || (pfr == NULL))
-+    return(-EINVAL);
-+
-+  if (get_user(val, (int *)optval))
-+    return -EFAULT;
-+
-+  found = 1;
-+
-+  switch(optname)
-+    {
-+    case SO_ATTACH_FILTER:
-+      ret = -EINVAL;
-+      if (optlen == sizeof(struct sock_fprog)) {
-+      unsigned int fsize;
-+      struct sock_fprog fprog;
-+      struct sk_filter *filter;
-+
-+      ret = -EFAULT;
-+
-+      /*
-+        NOTE
-+
-+        Do not call copy_from_user within a held
-+        splinlock (e.g. ring_mgmt_lock) as this caused
-+        problems when certain debugging was enabled under
-+        2.6.5 -- including hard lockups of the machine.
-+      */
-+      if(copy_from_user(&fprog, optval, sizeof(fprog)))
-+        break;
-+
-+      fsize = sizeof(struct sock_filter) * fprog.len;
-+      filter = kmalloc(fsize, GFP_KERNEL);
-+
-+      if(filter == NULL) {
-+        ret = -ENOMEM;
-+        break;
-+      }
-+
-+      if(copy_from_user(filter->insns, fprog.filter, fsize))
-+        break;
-+
-+      filter->len = fprog.len;
-+
-+      if(sk_chk_filter(filter->insns, filter->len) != 0) {
-+        /* Bad filter specified */
-+        kfree(filter);
-+        pfr->bpfFilter = NULL;
-+        break;
-+      }
-+
-+      /* get the lock, set the filter, release the lock */
-+      write_lock(&ring_mgmt_lock);
-+      pfr->bpfFilter = filter;
-+      write_unlock(&ring_mgmt_lock);
-+      }
-+      ret = 0;
-+      break;
-+
-+    case SO_DETACH_FILTER:
-+      write_lock(&ring_mgmt_lock);
-+      found = 1;
-+      if(pfr->bpfFilter != NULL) {
-+      kfree(pfr->bpfFilter);
-+      pfr->bpfFilter = NULL;
-+      write_unlock(&ring_mgmt_lock);
-+      break;
-+      }
-+      ret = -ENONET;
-+      break;
-+
-+    case SO_ADD_TO_CLUSTER:
-+      if (optlen!=sizeof(val))
-+      return -EINVAL;
-+
-+      if (copy_from_user(&cluster_id, optval, sizeof(cluster_id)))
-+      return -EFAULT;
-+
-+      write_lock(&ring_mgmt_lock);
-+      ret = add_to_cluster(sock->sk, pfr, cluster_id);
-+      write_unlock(&ring_mgmt_lock);
-+      break;
-+
-+    case SO_REMOVE_FROM_CLUSTER:
-+      write_lock(&ring_mgmt_lock);
-+      ret = remove_from_cluster(sock->sk, pfr);
-+      write_unlock(&ring_mgmt_lock);
-+      break;
-+
-+    case SO_SET_REFLECTOR:
-+      if(optlen >= (sizeof(devName)-1))
-+      return -EINVAL;
-+
-+      if(optlen > 0) {
-+      if(copy_from_user(devName, optval, optlen))
-+        return -EFAULT;
-+      }
-+
-+      devName[optlen] = '\0';
-+
-+#if defined(RING_DEBUG)
-+      printk("+++ SO_SET_REFLECTOR(%s)\n", devName);
-+#endif
-+
-+      write_lock(&ring_mgmt_lock);
-+      pfr->reflector_dev = dev_get_by_name(devName);
-+      write_unlock(&ring_mgmt_lock);
-+
-+#if defined(RING_DEBUG)
-+      if(pfr->reflector_dev != NULL)
-+      printk("SO_SET_REFLECTOR(%s): succeded\n", devName);
-+      else
-+      printk("SO_SET_REFLECTOR(%s): device unknown\n", devName);
-+#endif
-+      break;
-+
-+    default:
-+      found = 0;
-+      break;
-+    }
-+
-+  if(found)
-+    return(ret);
-+  else
-+    return(sock_setsockopt(sock, level, optname, optval, optlen));
-+}
-+
-+/* ************************************* */
-+
-+static int ring_ioctl(struct socket *sock,
-+                    unsigned int cmd, unsigned long arg)
-+{
-+  switch(cmd)
-+    {
-+    case SIOCGIFFLAGS:
-+    case SIOCSIFFLAGS:
-+    case SIOCGIFCONF:
-+    case SIOCGIFMETRIC:
-+    case SIOCSIFMETRIC:
-+    case SIOCGIFMEM:
-+    case SIOCSIFMEM:
-+    case SIOCGIFMTU:
-+    case SIOCSIFMTU:
-+    case SIOCSIFLINK:
-+    case SIOCGIFHWADDR:
-+    case SIOCSIFHWADDR:
-+    case SIOCSIFMAP:
-+    case SIOCGIFMAP:
-+    case SIOCSIFSLAVE:
-+    case SIOCGIFSLAVE:
-+    case SIOCGIFINDEX:
-+    case SIOCGIFNAME:
-+    case SIOCGIFCOUNT:
-+    case SIOCSIFHWBROADCAST:
-+      return(dev_ioctl(cmd,(void *) arg));
-+
-+    default:
-+      return -EOPNOTSUPP;
-+    }
-+
-+  return 0;
-+}
-+
-+/* ************************************* */
-+
-+static struct proto_ops ring_ops = {
-+  .family     =       PF_RING,
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+  .owner      =       THIS_MODULE,
-+#endif
-+
-+  /* Operations that make no sense on ring sockets. */
-+  .connect    =       sock_no_connect,
-+  .socketpair =       sock_no_socketpair,
-+  .accept     =       sock_no_accept,
-+  .getname    =       sock_no_getname,
-+  .listen     =       sock_no_listen,
-+  .shutdown   =       sock_no_shutdown,
-+  .sendpage   =       sock_no_sendpage,
-+  .sendmsg    =       sock_no_sendmsg,
-+  .getsockopt =       sock_no_getsockopt,
-+
-+  /* Now the operations that really occur. */
-+  .release    =       ring_release,
-+  .bind               =       ring_bind,
-+  .mmap               =       ring_mmap,
-+  .poll               =       ring_poll,
-+  .setsockopt =       ring_setsockopt,
-+  .ioctl      =       ring_ioctl,
-+  .recvmsg    =       ring_recvmsg,
-+};
-+
-+/* ************************************ */
-+
-+static struct net_proto_family ring_family_ops = {
-+  .family     =       PF_RING,
-+  .create     =       ring_create,
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+  .owner      =       THIS_MODULE,
-+#endif
-+};
-+
-+// BD: API changed in 2.6.12, ref:
-+// http://svn.clkao.org/svnweb/linux/revision/?rev=28201
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11))
-+static struct proto ring_proto = {
-+  .name               =       "PF_RING",
-+  .owner      =       THIS_MODULE,
-+  .obj_size   =       sizeof(struct sock),
-+};
-+#endif
-+
-+/* ************************************ */
-+
-+static void __exit ring_exit(void)
-+{
-+  struct list_head *ptr;
-+  struct ring_element *entry;
-+
-+  for(ptr = ring_table.next; ptr != &ring_table; ptr = ptr->next) {
-+    entry = list_entry(ptr, struct ring_element, list);
-+    kfree(entry);
-+  }
-+
-+  while(ring_cluster_list != NULL) {
-+    struct ring_cluster *next = ring_cluster_list->next;
-+    kfree(ring_cluster_list);
-+    ring_cluster_list = next;
-+  }
-+
-+  set_skb_ring_handler(NULL);
-+  set_buffer_ring_handler(NULL);
-+  sock_unregister(PF_RING);
-+
-+  printk("PF_RING shut down.\n");
-+}
-+
-+/* ************************************ */
-+
-+static int __init ring_init(void)
-+{
-+  printk("Welcome to PF_RING %s\n(C) 2004 L.Deri <deri@ntop.org>\n",
-+       RING_VERSION);
-+
-+  INIT_LIST_HEAD(&ring_table);
-+  ring_cluster_list = NULL;
-+
-+  sock_register(&ring_family_ops);
-+
-+  set_skb_ring_handler(skb_ring_handler);
-+  set_buffer_ring_handler(buffer_ring_handler);
-+
-+  if(get_buffer_ring_handler() != buffer_ring_handler) {
-+    printk("PF_RING: set_buffer_ring_handler FAILED\n");
-+
-+    set_skb_ring_handler(NULL);
-+    set_buffer_ring_handler(NULL);
-+    sock_unregister(PF_RING);
-+    return -1;
-+  } else {
-+    printk("PF_RING: bucket length    %d bytes\n", bucket_len);
-+    printk("PF_RING: ring slots       %d\n", num_slots);
-+    printk("PF_RING: sample rate      %d [1=no sampling]\n", sample_rate);
-+    printk("PF_RING: capture TX       %s\n",
-+         enable_tx_capture ? "Yes [RX+TX]" : "No [RX only]");
-+    printk("PF_RING: transparent mode %s\n",
-+         transparent_mode ? "Yes" : "No");
-+
-+    printk("PF_RING initialized correctly.\n");
-+    return 0;
-+  }
-+}
-+
-+module_init(ring_init);
-+module_exit(ring_exit);
-+MODULE_LICENSE("GPL");
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
-+MODULE_ALIAS_NETPROTO(PF_RING);
-+#endif