diff -bEruN linux-2.4.20-my/drivers/net/Config.in linux-2.4.20-nc/drivers/net/Config.in
--- linux-2.4.20-my/drivers/net/Config.in	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/drivers/net/Config.in	2006-06-02 08:21:26.000000000 -0700
@@ -2,6 +2,7 @@
 # Network device configuration
 #
 
+source drivers/net/hnd/Config.in
 source drivers/net/arcnet/Config.in
 
 tristate 'Dummy net driver support' CONFIG_DUMMY
diff -bEruN linux-2.4.20-my/drivers/net/ctmisc/Makefile linux-2.4.20-nc/drivers/net/ctmisc/Makefile
--- linux-2.4.20-my/drivers/net/ctmisc/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/ctmisc/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,27 @@
+#  Copyright 2001, Cybertan Corporation
+#  All Rights Reserved.
+#  
+#  This is UNPUBLISHED PROPRIETARY SOURCE CODE of Cybertan Corporation;
+#  the contents of this file may not be disclosed to third parties, copied or
+#  duplicated in any form, in whole or in part, without the prior written
+#  permission of Cybertan Corporation.
+#
+#
+# $Id: Makefile,v 1.2 2004/11/12 04:26:43 honor Exp $
+#
+
+O_TARGET	:= ctmisc.o
+
+MISC_OBJS	:= misc.o flash.o
+
+export-objs	:= flash.o
+obj-y		+= $(MISC_OBJS)
+obj-m		:= $(O_TARGET)
+
+SRCBASE		:= $(TOPDIR)/../..
+EXTRA_CFLAGS	+= -I$(SRCBASE)/include
+
+vpath %.c $(SRCBASE)/shared
+
+include $(TOPDIR)/Rules.make
+
diff -bEruN linux-2.4.20-my/drivers/net/diag/Makefile linux-2.4.20-nc/drivers/net/diag/Makefile
--- linux-2.4.20-my/drivers/net/diag/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/diag/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,27 @@
+#  Copyright 2001, Cybertan Corporation
+#  All Rights Reserved.
+#  
+#  This is UNPUBLISHED PROPRIETARY SOURCE CODE of Cybertan Corporation;
+#  the contents of this file may not be disclosed to third parties, copied or
+#  duplicated in any form, in whole or in part, without the prior written
+#  permission of Cybertan Corporation.
+#
+#
+# $Id: Makefile,v 1.1 2003/07/09 14:09:58 honor Exp $
+#
+
+O_TARGET	:= diag.o
+
+MAC_OBJS	:= diag_led.o
+
+export-objs	:= 
+obj-y		:= $(MAC_OBJS)
+obj-m		:= $(O_TARGET)
+
+SRCBASE		:= $(TOPDIR)/../..
+EXTRA_CFLAGS	+= -I$(SRCBASE)/include
+
+vpath %.c $(SRCBASE)/shared
+
+include $(TOPDIR)/Rules.make
+
diff -bEruN linux-2.4.20-my/drivers/net/et/Makefile linux-2.4.20-nc/drivers/net/et/Makefile
--- linux-2.4.20-my/drivers/net/et/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/et/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,43 @@
+#
+# Makefile for the Broadcom et driver
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+# $Id: Makefile,v 1.1.1.9 2005/03/07 07:30:48 kanki Exp $
+#
+
+O_TARGET	:= et.o
+
+ET_OBJS		:= et_linux.o etc.o
+
+ifeq ($(CONFIG_ET_47XX),y)
+ET_OBJS		+= etc47xx.o etc_robo.o etc_adm.o
+EXTRA_CFLAGS	+= -DBCM47XX_CHOPS -DETROBO -DETADM
+endif
+ifeq ($(CONFIG_ET_4413),y)
+ET_OBJS		+= etc4413.o
+EXTRA_CFLAGS	+= -DBCM4413_CHOPS
+endif
+
+export-objs	:=
+obj-y		:= $(ET_OBJS)
+obj-m		:= $(O_TARGET)
+
+EXTRA_CFLAGS	+= -DDMA
+
+# Search for sources under src/et/sys or objects under src/et/linux
+ifneq ($(wildcard $(SRCBASE)/et/sys),)
+EXTRA_CFLAGS	+= -I$(SRCBASE)/et/sys
+vpath %.c $(SRCBASE)/et/sys $(SRCBASE)/shared
+else
+#obj-y		:= $(foreach obj,$(ET_OBJS),$(SRCBASE)/et/linux/$(obj))
+obj-y		:= $(SRCBASE)/et/linux/et.o
+endif
+
+include $(TOPDIR)/Rules.make
diff -bEruN linux-2.4.20-my/drivers/net/et.4702/Makefile linux-2.4.20-nc/drivers/net/et.4702/Makefile
--- linux-2.4.20-my/drivers/net/et.4702/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/et.4702/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,43 @@
+#  Copyright 2001, Broadcom Corporation
+#  All Rights Reserved.
+#  
+#  This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
+#  the contents of this file may not be disclosed to third parties, copied or
+#  duplicated in any form, in whole or in part, without the prior written
+#  permission of Broadcom Corporation.
+#
+# Makefile for the Broadcom et driver
+#
+# $Id: Makefile,v 1.3 2004/11/17 07:50:40 honor Exp $
+#
+
+O_TARGET	:= 4702et.o
+
+ET_OBJS		:= et_linux.o etc.o
+
+ifeq ($(CONFIG_ET_47XX),y)
+ET_OBJS		+= etc47xx.o etc_robo.o
+EXTRA_CFLAGS	+= -DBCM47XX_CHOPS
+endif
+ifeq ($(CONFIG_ET_4413),y)
+ET_OBJS		+= etc4413.o
+EXTRA_CFLAGS	+= -DBCM4413_CHOPS
+endif
+
+export-objs	:=
+obj-y		:= $(ET_OBJS)
+obj-m		:= $(O_TARGET)
+
+SRCBASE		:= $(TOPDIR)/../..
+EXTRA_CFLAGS	+= -I$(SRCBASE)/include
+EXTRA_CFLAGS	+= -DDMA
+
+# Search for sources under src/et/sys or objects under src/et/linux
+#ifneq ($(wildcard $(SRCBASE)/et.4702/sys),)
+#EXTRA_CFLAGS	+= -I$(SRCBASE)/et.4702/sys
+#vpath %.c $(SRCBASE)/et.4702/sys $(SRCBASE)/shared
+#else
+obj-y		:= $(foreach obj,$(ET_OBJS),$(SRCBASE)/et.4702/linux/$(obj))
+#endif
+
+include $(TOPDIR)/Rules.make
diff -bEruN linux-2.4.20-my/drivers/net/hnd/Config.in linux-2.4.20-nc/drivers/net/hnd/Config.in
--- linux-2.4.20-my/drivers/net/hnd/Config.in	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/hnd/Config.in	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,37 @@
+#
+# Broadcom Home Networking Division (HND) driver configuration
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+
+mainmenu_option next_comment
+comment 'Broadcom HND network devices'
+   tristate 'Broadcom HND network device support' CONFIG_HND $CONFIG_PCI
+   if [ "$CONFIG_HND" != "n" ]; then
+      dep_tristate '  Broadcom InsideLine HPNA support' CONFIG_IL $CONFIG_HND
+      if [ "$CONFIG_IL" != "n" ]; then
+         bool '    Broadcom BCM42xx support' CONFIG_IL_42XX
+         bool '    Broadcom BCM47xx support' CONFIG_IL_47XX
+         int '    LARQ buffer allocation (0 = tiny, 2 = huge)' CONFIG_LARQ_BUF 0
+      fi
+      dep_tristate '  Broadcom 10/100 Ethernet support' CONFIG_ET $CONFIG_HND
+      if [ "$CONFIG_ET" != "n" ]; then
+         bool '    Broadcom BCM4413 support' CONFIG_ET_4413
+         bool '    Broadcom BCM47xx support' CONFIG_ET_47XX
+      fi
+      dep_tristate '  Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL $CONFIG_HND
+      if [ "$CONFIG_WL" != "n" ]; then
+         string '    wl config file name for compile ap obj' CONFIG_WL_AP wlconfig_lx_router_ap 
+         string '    wl config file name for compile sta obj' CONFIG_WL_STA wlconfig_lx_router_sta 
+         string '    wl config file name for compile apsta obj' CONFIG_WL_APSTA wlconfig_lx_router_apsta 
+         string '    wl config file name for compile dngl obj' CONFIG_WL_DNGL wlconfig_lx_router_dongle 
+         string '    link one of above to wl.o' CONFIG_WL_LINK AP 
+      fi
+   fi
+endmenu
diff -bEruN linux-2.4.20-my/drivers/net/hnd/Makefile linux-2.4.20-nc/drivers/net/hnd/Makefile
--- linux-2.4.20-my/drivers/net/hnd/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/hnd/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,76 @@
+#
+# Makefile for Broadcom Home Networking Division (HND) shared driver code
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+# $Id: Makefile,v 1.1.1.9 2005/03/07 07:30:48 kanki Exp $
+#
+
+O_TARGET	:= hnd.o
+
+WLSHARED        := wlconfig_lx_shared
+WLCFGDIR        := $(SRCBASE)/wl/config
+include         $(WLCFGDIR)/$(WLSHARED)
+include         $(WLCFGDIR)/wl.mk
+
+HND_OBJS	:= $(WLFILES:.c=.o)
+
+ifneq ($(CONFIG_BCM947XX),y)
+HND_OBJS	+= nvramstubs.o
+endif
+
+ifdef CONFIG_USB_RNDIS
+EXTRA_CFLAGS += -DCONFIG_USBRNDIS_RETAIL
+endif                                  
+
+export-objs	:= shared_ksyms.o
+obj-y		:= shared_ksyms.o $(HND_OBJS)
+obj-m		:= $(O_TARGET)
+
+vpath %.c $(SRCBASE)/shared $(SRCBASE)/shared/nvram
+
+include $(TOPDIR)/Rules.make
+
+ifeq ($(wildcard $(SRCBASE)/shared/bcmutils.c),)
+bcmutils.o: $(SRCBASE)/shared/linux/bcmutils.o
+	cp $< $@
+endif
+
+ifeq ($(wildcard $(SRCBASE)/shared/hnddma.c),)
+hnddma.o: $(SRCBASE)/shared/linux/hnddma.o
+	cp $< $@
+endif
+
+ifeq ($(wildcard $(SRCBASE)/shared/linux_osl.c),)
+linux_osl.o: $(SRCBASE)/shared/linux/linux_osl.o
+	cp $< $@
+endif
+
+ifeq ($(wildcard $(SRCBASE)/shared/sbutils.c),)
+sbutils.o: $(SRCBASE)/shared/linux/sbutils.o
+	cp $< $@
+endif
+
+ifeq ($(wildcard $(SRCBASE)/shared/bcmsrom.c),)
+bcmsrom.o: $(SRCBASE)/shared/linux/bcmsrom.o
+	cp $< $@
+endif
+
+ifeq ($(wildcard $(SRCBASE)/shared/nvramstubs.c),)
+nvramstubs.o: $(SRCBASE)/shared/linux/nvramstubs.o
+	cp $< $@
+endif
+
+ifeq ($(wildcard $(SRCBASE)/shared/bcmwpa.c),)
+bcmwpa.o: $(SRCBASE)/shared/linux/bcmwpa.o
+	cp $< $@
+endif
+
+shared_ksyms.c: shared_ksyms.sh $(HND_OBJS)
+	sh -e $< $(HND_OBJS) > $@
diff -bEruN linux-2.4.20-my/drivers/net/hnd/shared_ksyms.c linux-2.4.20-nc/drivers/net/hnd/shared_ksyms.c
--- linux-2.4.20-my/drivers/net/hnd/shared_ksyms.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/hnd/shared_ksyms.c	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,123 @@
+#include <linux/config.h>
+#include <linux/module.h>
+extern void dma_attach; EXPORT_SYMBOL(dma_attach);
+extern void dma_detach; EXPORT_SYMBOL(dma_detach);
+extern void dma_fifoloopbackenable; EXPORT_SYMBOL(dma_fifoloopbackenable);
+extern void dma_getnextrxp; EXPORT_SYMBOL(dma_getnextrxp);
+extern void dma_getnexttxp; EXPORT_SYMBOL(dma_getnexttxp);
+extern void dma_getvar; EXPORT_SYMBOL(dma_getvar);
+extern void dma_peeknexttxp; EXPORT_SYMBOL(dma_peeknexttxp);
+extern void dma_rx; EXPORT_SYMBOL(dma_rx);
+extern void dma_rxenable; EXPORT_SYMBOL(dma_rxenable);
+extern void dma_rxenabled; EXPORT_SYMBOL(dma_rxenabled);
+extern void dma_rxfill; EXPORT_SYMBOL(dma_rxfill);
+extern void dma_rxinit; EXPORT_SYMBOL(dma_rxinit);
+extern void dma_rxreclaim; EXPORT_SYMBOL(dma_rxreclaim);
+extern void dma_rxreset; EXPORT_SYMBOL(dma_rxreset);
+extern void dma_rxstopped; EXPORT_SYMBOL(dma_rxstopped);
+extern void dma_tx; EXPORT_SYMBOL(dma_tx);
+extern void dma_txactive; EXPORT_SYMBOL(dma_txactive);
+extern void dma_txblock; EXPORT_SYMBOL(dma_txblock);
+extern void dma_txenabled; EXPORT_SYMBOL(dma_txenabled);
+extern void dma_txfast; EXPORT_SYMBOL(dma_txfast);
+extern void dma_txinit; EXPORT_SYMBOL(dma_txinit);
+extern void dma_txreclaim; EXPORT_SYMBOL(dma_txreclaim);
+extern void dma_txreset; EXPORT_SYMBOL(dma_txreset);
+extern void dma_txresume; EXPORT_SYMBOL(dma_txresume);
+extern void dma_txrotate; EXPORT_SYMBOL(dma_txrotate);
+extern void dma_txstopped; EXPORT_SYMBOL(dma_txstopped);
+extern void dma_txsuspend; EXPORT_SYMBOL(dma_txsuspend);
+extern void dma_txsuspended; EXPORT_SYMBOL(dma_txsuspended);
+extern void dma_txunblock; EXPORT_SYMBOL(dma_txunblock);
+extern void bcm_atoi; EXPORT_SYMBOL(bcm_atoi);
+extern void bcm_ctype; EXPORT_SYMBOL(bcm_ctype);
+extern void bcm_ether_atoe; EXPORT_SYMBOL(bcm_ether_atoe);
+extern void bcm_ether_ntoa; EXPORT_SYMBOL(bcm_ether_ntoa);
+extern void bcm_mdelay; EXPORT_SYMBOL(bcm_mdelay);
+extern void bcm_next_tlv; EXPORT_SYMBOL(bcm_next_tlv);
+extern void bcm_parse_ordered_tlvs; EXPORT_SYMBOL(bcm_parse_ordered_tlvs);
+extern void bcm_parse_tlvs; EXPORT_SYMBOL(bcm_parse_tlvs);
+extern void bcmstrcat; EXPORT_SYMBOL(bcmstrcat);
+extern void bcmstrstr; EXPORT_SYMBOL(bcmstrstr);
+extern void bcm_strtoul; EXPORT_SYMBOL(bcm_strtoul);
+extern void bcm_toupper; EXPORT_SYMBOL(bcm_toupper);
+extern void getgpiopin; EXPORT_SYMBOL(getgpiopin);
+extern void getintvar; EXPORT_SYMBOL(getintvar);
+extern void getvar; EXPORT_SYMBOL(getvar);
+extern void hndcrc16; EXPORT_SYMBOL(hndcrc16);
+extern void hndcrc32; EXPORT_SYMBOL(hndcrc32);
+extern void hndcrc8; EXPORT_SYMBOL(hndcrc8);
+extern void pktcopy; EXPORT_SYMBOL(pktcopy);
+extern void pktdeq; EXPORT_SYMBOL(pktdeq);
+extern void pktdeqtail; EXPORT_SYMBOL(pktdeqtail);
+extern void pktenq; EXPORT_SYMBOL(pktenq);
+extern void pktq_init; EXPORT_SYMBOL(pktq_init);
+extern void pkttotlen; EXPORT_SYMBOL(pkttotlen);
+extern void srom_read; EXPORT_SYMBOL(srom_read);
+extern void srom_var_init; EXPORT_SYMBOL(srom_var_init);
+extern void srom_write; EXPORT_SYMBOL(srom_write);
+extern void sb_attach; EXPORT_SYMBOL(sb_attach);
+extern void sb_base; EXPORT_SYMBOL(sb_base);
+extern void sb_boardtype; EXPORT_SYMBOL(sb_boardtype);
+extern void sb_boardvendor; EXPORT_SYMBOL(sb_boardvendor);
+extern void sb_bus; EXPORT_SYMBOL(sb_bus);
+extern void sb_chip; EXPORT_SYMBOL(sb_chip);
+extern void sb_chipcrev; EXPORT_SYMBOL(sb_chipcrev);
+extern void sb_chippkg; EXPORT_SYMBOL(sb_chippkg);
+extern void sb_chiprev; EXPORT_SYMBOL(sb_chiprev);
+extern void sb_clock; EXPORT_SYMBOL(sb_clock);
+extern void sb_clock_rate; EXPORT_SYMBOL(sb_clock_rate);
+extern void sb_commit; EXPORT_SYMBOL(sb_commit);
+extern void sb_core_disable; EXPORT_SYMBOL(sb_core_disable);
+extern void sb_coreflags; EXPORT_SYMBOL(sb_coreflags);
+extern void sb_coreflagshi; EXPORT_SYMBOL(sb_coreflagshi);
+extern void sb_coreid; EXPORT_SYMBOL(sb_coreid);
+extern void sb_coreidx; EXPORT_SYMBOL(sb_coreidx);
+extern void sb_corelist; EXPORT_SYMBOL(sb_corelist);
+extern void sb_coreregs; EXPORT_SYMBOL(sb_coreregs);
+extern void sb_core_reset; EXPORT_SYMBOL(sb_core_reset);
+extern void sb_corerev; EXPORT_SYMBOL(sb_corerev);
+extern void sb_core_tofixup; EXPORT_SYMBOL(sb_core_tofixup);
+extern void sb_coreunit; EXPORT_SYMBOL(sb_coreunit);
+extern void sb_corevendor; EXPORT_SYMBOL(sb_corevendor);
+extern void sb_detach; EXPORT_SYMBOL(sb_detach);
+extern void sb_gpiocontrol; EXPORT_SYMBOL(sb_gpiocontrol);
+extern void sb_gpioin; EXPORT_SYMBOL(sb_gpioin);
+extern void sb_gpiointmask; EXPORT_SYMBOL(sb_gpiointmask);
+extern void sb_gpiointpolarity; EXPORT_SYMBOL(sb_gpiointpolarity);
+extern void sb_gpioout; EXPORT_SYMBOL(sb_gpioout);
+extern void sb_gpioouten; EXPORT_SYMBOL(sb_gpioouten);
+extern void sb_gpiosetcore; EXPORT_SYMBOL(sb_gpiosetcore);
+extern void sb_iscoreup; EXPORT_SYMBOL(sb_iscoreup);
+extern void sb_kattach; EXPORT_SYMBOL(sb_kattach);
+extern void sb_osh; EXPORT_SYMBOL(sb_osh);
+extern void sb_pcirev; EXPORT_SYMBOL(sb_pcirev);
+extern void sb_pci_setup; EXPORT_SYMBOL(sb_pci_setup);
+extern void sb_pcmcia_init; EXPORT_SYMBOL(sb_pcmcia_init);
+extern void sb_pcmciarev; EXPORT_SYMBOL(sb_pcmciarev);
+extern void sb_pwrctl_clk; EXPORT_SYMBOL(sb_pwrctl_clk);
+extern void sb_pwrctl_fast_pwrup_delay; EXPORT_SYMBOL(sb_pwrctl_fast_pwrup_delay);
+extern void sb_pwrctl_init; EXPORT_SYMBOL(sb_pwrctl_init);
+extern void sb_pwrctl_slowclk; EXPORT_SYMBOL(sb_pwrctl_slowclk);
+extern void sb_pwrctl_xtal; EXPORT_SYMBOL(sb_pwrctl_xtal);
+extern void sb_register_intr_callback; EXPORT_SYMBOL(sb_register_intr_callback);
+extern void sb_setcore; EXPORT_SYMBOL(sb_setcore);
+extern void sb_setcoreidx; EXPORT_SYMBOL(sb_setcoreidx);
+extern void sb_size; EXPORT_SYMBOL(sb_size);
+extern void sb_watchdog; EXPORT_SYMBOL(sb_watchdog);
+extern void osl_attach; EXPORT_SYMBOL(osl_attach);
+extern void osl_detach; EXPORT_SYMBOL(osl_detach);
+extern void osl_dma_alloc_consistent; EXPORT_SYMBOL(osl_dma_alloc_consistent);
+extern void osl_dma_free_consistent; EXPORT_SYMBOL(osl_dma_free_consistent);
+extern void osl_dma_map; EXPORT_SYMBOL(osl_dma_map);
+extern void osl_dma_unmap; EXPORT_SYMBOL(osl_dma_unmap);
+extern void osl_malloc; EXPORT_SYMBOL(osl_malloc);
+extern void osl_malloced; EXPORT_SYMBOL(osl_malloced);
+extern void osl_malloc_failed; EXPORT_SYMBOL(osl_malloc_failed);
+extern void osl_mfree; EXPORT_SYMBOL(osl_mfree);
+extern void osl_pci_read_config; EXPORT_SYMBOL(osl_pci_read_config);
+extern void osl_pci_write_config; EXPORT_SYMBOL(osl_pci_write_config);
+extern void osl_pcmcia_read_attr; EXPORT_SYMBOL(osl_pcmcia_read_attr);
+extern void osl_pcmcia_write_attr; EXPORT_SYMBOL(osl_pcmcia_write_attr);
+extern void osl_pktfree; EXPORT_SYMBOL(osl_pktfree);
+extern void osl_pktget; EXPORT_SYMBOL(osl_pktget);
diff -bEruN linux-2.4.20-my/drivers/net/hnd/shared_ksyms.sh linux-2.4.20-nc/drivers/net/hnd/shared_ksyms.sh
--- linux-2.4.20-my/drivers/net/hnd/shared_ksyms.sh	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/hnd/shared_ksyms.sh	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# Copyright 2005, Broadcom Corporation      
+# All Rights Reserved.      
+#       
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY      
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM      
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS      
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.      
+#
+# $Id: shared_ksyms.sh,v 1.1.1.7 2005/03/07 07:30:48 kanki Exp $
+#
+
+cat <<EOF
+#include <linux/config.h>
+#include <linux/module.h>
+EOF
+
+for file in $* ; do
+    ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p'
+done
diff -bEruN linux-2.4.20-my/drivers/net/il/Makefile linux-2.4.20-nc/drivers/net/il/Makefile
--- linux-2.4.20-my/drivers/net/il/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/il/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,51 @@
+#
+# Makefile for the Broadcom il driver
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+# $Id: Makefile,v 1.1.1.8 2005/03/07 07:30:48 kanki Exp $
+#
+
+O_TARGET	:= il.o
+
+IL_OBJS		:= il_linux.o ilc.o cert.o plarq.o pe_select_maxse.o
+
+ifeq ($(CONFIG_IL_47XX),y)
+IL_OBJS		+= ilc47xx.o
+EXTRA_CFLAGS	+= -DBCM47XX_CHOPS
+endif
+ifeq ($(CONFIG_IL_42XX),y)
+IL_OBJS		+= ilc42xx.o
+EXTRA_CFLAGS	+= -DBCM42XX_CHOPS
+endif
+
+export-objs	:=
+obj-y		:= $(IL_OBJS)
+obj-m		:= $(O_TARGET)
+
+EXTRA_CFLAGS	+= -DDMA -DIL_CERT -DIL_PROTOS
+
+ifneq ($(CONFIG_BRIDGE),n)
+EXTRA_CFLAGS	+= -DIL_BRIDGE
+endif
+
+ifeq ($(CONFIG_LARQ_BUF),0)
+EXTRA_CFLAGS	+= -DLARQ_TINY
+endif
+
+# Search for sources under src/il/sys or objects under src/il/linux
+ifneq ($(wildcard $(SRCBASE)/il/sys),)
+EXTRA_CFLAGS	+= -I$(SRCBASE)/il/sys
+vpath %.c $(SRCBASE)/il/sys $(SRCBASE)/shared
+else
+#obj-y		:= $(foreach obj,$(IL_OBJS),$(SRCBASE)/il/linux/$(obj))
+obj-y		:= $(SRCBASE)/il/linux/il.o
+endif
+
+include $(TOPDIR)/Rules.make
diff -bEruN linux-2.4.20-my/drivers/net/Makefile linux-2.4.20-nc/drivers/net/Makefile
--- linux-2.4.20-my/drivers/net/Makefile	2006-06-02 07:55:18.000000000 -0700
+++ linux-2.4.20-nc/drivers/net/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -2,6 +2,10 @@
 #
 # Makefile for the Linux network (ethercard) device drivers.
 #
+#SRCBASE=../../../../
+ifneq ($(wildcard $(SRCBASE)/cy_conf.mak),)
+  include $(SRCBASE)/cy_conf.mak
+endif
 
 obj-y           :=
 obj-m           :=
@@ -21,6 +25,19 @@
 list-multi	:=	rcpci.o
 rcpci-objs	:=	rcpci45.o rclanmtl.o
 
+#subdir-m += mac
+subdir-m += diag
+#subdir-m += ext_io
+#subdir-m += ctmisc
+
+ifeq ($(CONFIG_HW_QOS),y)
+subdir-m += port_based_qos
+else
+	ifeq ($(CONFIG_PERFORMANCE),y)
+	subdir-m += port_based_qos
+	endif
+endif
+
 ifeq ($(CONFIG_TULIP),y)
   obj-y += tulip/tulip.o
 endif
@@ -265,6 +282,36 @@
 endif
 endif
 
+#
+# Broadcom HND devices
+#
+
+ifdef CONFIG_HND
+subdir-$(CONFIG_HND) += hnd
+endif
+ifdef CONFIG_ET
+#subdir-$(CONFIG_ET) += et.4702
+#subdir-$(CONFIG_ET) += et
+endif
+ifdef CONFIG_IL
+subdir-$(CONFIG_IL) += il
+endif
+ifdef CONFIG_WL
+subdir-$(CONFIG_WL) += wl
+endif
+ifeq ($(CONFIG_HND),y)
+  obj-y += hnd/hnd.o
+endif
+ifeq ($(CONFIG_ET),y)
+  obj-y += et/et.o
+endif
+ifeq ($(CONFIG_IL),y)
+  obj-y += il/il.o
+endif
+ifeq ($(CONFIG_WL),y)
+  obj-y += wl/wl.o
+endif
+
 include $(TOPDIR)/Rules.make
 
 clean:
diff -bEruN linux-2.4.20-my/drivers/net/port_based_qos/Atan.c linux-2.4.20-nc/drivers/net/port_based_qos/Atan.c
--- linux-2.4.20-my/drivers/net/port_based_qos/Atan.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/port_based_qos/Atan.c	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,177 @@
+#include "Atan.h"
+#include "c47xx.h"
+
+extern void conf_gpio(int x);
+
+/*----------------------------------------------------------------------------
+Write specified data to eeprom
+entry:	*src	= pointer to specified data to write
+		len		= number of short(2 bytes) to be written
+*/
+void write_eeprom( short RegNumber, unsigned short *data, int len )
+{
+    int i2;
+    unsigned short s_addr, s_data;
+    unsigned short *src;
+
+    src = data;
+    SetEEpromToSendState();
+//  the write enable(WEN) instruction must be executed before any device
+//  programming can be done
+
+    s_data = 0x04c0;
+    SendAddrToEEprom(s_data); //00000001 0011000000B
+    SetCSToLowForEEprom();
+
+    s_addr = 0x0500 | (RegNumber & 0x0ff); //00000001 01dddddddd
+    s_data = *src;
+
+    for (i2 = len; i2 > 0 ; i2 --)
+    {
+      SendAddrToEEprom(s_addr); //00000001 01dddddd
+      SendDataToEEprom(s_data); //dddddddd dddddddd
+      SetCSToLowForEEprom();
+      SetCSToLowForEEprom();
+      //WriteWait();     
+      s_addr ++;
+      src ++;
+      s_data = *src;
+    }
+//  after all data has been written to EEprom , the write disable(WDS) 
+//  instruction must be executed
+    SetCSToHighForEEprom();
+    s_data = 0x0400;
+    SendAddrToEEprom(s_data); //00000001 00000000B
+    SetCSToLowForEEprom();
+    SetCSToLowForEEprom();
+}
+
+void SetEEpromToSendState()
+{
+  conf_gpio(0x0);
+  conf_gpio(0x0);
+  conf_gpio(B_ECS);
+  conf_gpio(B_ECS);
+  
+//  ;cs     __--   ,bit 2
+//  ;sck    ____   ,bit 3
+//  ;di     ____   ,bit 5
+//  ;do     ____   ,bit 4
+//  ;
+}
+
+void ResetEEpromToSendState()
+{
+  conf_gpio(0x0);
+  conf_gpio(0x0);
+  conf_gpio(0x0);
+  conf_gpio(0x0);
+  
+//  ;cs     ____   ,bit 2  
+//  ;sck    ____   ,bit 3
+//  ;di     ____   ,bit 5
+//  ;do     ____   ,bit 4 
+//  ;
+}
+
+void SetCSToLowForEEprom()
+{
+  conf_gpio(0x0);
+  conf_gpio(B_ECK);
+  conf_gpio(B_ECK);
+  conf_gpio(0x0);
+  
+//  ;cs     ____   ,bit 2
+//  ;sck    _--_   ,bit 3
+//  ;di     ____   ,bit 5
+//  ;do     ____   ,bit 4 
+//  ;
+}
+
+void SetCSToHighForEEprom()
+{
+  conf_gpio(B_ECS);
+  conf_gpio(B_ECS|B_ECK);
+  conf_gpio(B_ECS|B_ECK);
+  conf_gpio(B_ECS);
+  
+//  ;cs     ----   ,bit 2
+//  ;sck    _--_   ,bit 3
+//  ;di     ____   ,bit 5
+//  ;do     ____   ,bit 4  
+//  ;
+}
+
+void send_1ToEEprom()
+{
+  conf_gpio(B_ECS|B_EDI);
+  conf_gpio(B_ECS|B_ECK|B_EDI);
+  conf_gpio(B_ECS|B_ECK|B_EDI);
+  conf_gpio(B_ECS|B_EDI);
+  
+//  ;cs     ----   ,bit 2
+//  ;sck    _--_   ,bit 3
+//  ;di     ----   ,bit 5
+//  ;do     ____   ,bit 4
+//  ;       
+}
+
+void send_0ToEEprom()
+{
+  conf_gpio(B_ECS);
+  conf_gpio(B_ECS|B_ECK);
+  conf_gpio(B_ECS|B_ECK);
+  conf_gpio(B_ECS);
+  
+//  ;cs     ----   ,bit 2
+//  ;sck    _--_   ,bit 3
+//  ;di     ____   ,bit 5
+//  ;do     ____   ,bit 4
+//  ;       
+}
+
+#if 0
+void WriteWait()
+{
+  unsigned int status;
+  
+  SetCSToLowForEEprom();
+  SetCSToHighForEEprom();
+  do {
+  	SetCSToHighForEEprom();
+  	//status = ReadGPIOData(EDO);
+  	status = gpio & B_EDO;	// read EDO bit
+  }
+  while (!status);   // wait for write - ready
+  SetCSToLowForEEprom();
+}
+#endif
+
+void SendDataToEEprom(short s_data) 
+{
+  int data_mask;
+  
+  for (data_mask = 0x8000; data_mask != 0; )
+  {
+    if (s_data & data_mask) 
+      send_1ToEEprom();
+    else
+      send_0ToEEprom();  
+    data_mask = data_mask >> 1;
+  }
+}
+
+void SendAddrToEEprom(short s_data) 
+{
+  int data_mask;
+  
+  for (data_mask = 0x0400 ;data_mask != 0; )
+  {
+    if (s_data & data_mask) 
+      send_1ToEEprom();
+    else
+      send_0ToEEprom();  
+    data_mask = data_mask >> 1;
+  }
+}
+
diff -bEruN linux-2.4.20-my/drivers/net/port_based_qos/Atan.h linux-2.4.20-nc/drivers/net/port_based_qos/Atan.h
--- linux-2.4.20-my/drivers/net/port_based_qos/Atan.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/port_based_qos/Atan.h	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,18 @@
+#ifndef _ATAN_H_
+#define _ATAN_H_
+
+#define SINGLECOLOUR				0x1
+#define DUALCOLOUR					0x2
+
+void write_eeprom(short,unsigned short *,int);
+void SetEEpromToSendState(void);
+void ResetEEpromToSendState(void); 
+void SetCSToLowForEEprom(void);
+void SetCSToHighForEEprom(void);  
+void send_1ToEEprom(void);
+void send_0ToEEprom(void);
+//void WriteWait(void);
+void SendAddrToEEprom(short);
+void SendDataToEEprom(short);
+
+#endif
diff -bEruN linux-2.4.20-my/drivers/net/port_based_qos/c47xx.c linux-2.4.20-nc/drivers/net/port_based_qos/c47xx.c
--- linux-2.4.20-my/drivers/net/port_based_qos/c47xx.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/port_based_qos/c47xx.c	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,85 @@
+#include <typedefs.h>
+#include <sbutils.h>
+#include <bcmdevs.h>
+#include <osl.h>
+#include <bcmnvram.h>
+#include <bcmutils.h>
+
+#include <sbpci.h>
+#include <sbchipc.h>
+#include <sbconfig.h>
+#include <sbextif.h>
+#include <sbmips.h>
+#include "c47xx.h"
+extern uint32 sb_gpioouten(void *sbh, uint32 mask, uint32 val);
+extern uint32 sb_gpioout(void *sbh, uint32 mask, uint32 val);
+extern uint32 sb_gpioin(void *sbh);
+extern uint32 sb_gpiointmask(void *sbh, uint32 mask, uint32 val);
+
+#define OUTENMASK	B_RESET|B_ECS|B_ECK|B_EDI
+#define CFGMASK		B_ECS|B_ECK|B_EDI
+#define BIT(x)	(1 << (x))
+#define	ASSERT(exp)		do {} while (0)
+
+void
+conf_gpio(int x)
+{
+	ASSERT(sbh);
+
+	/* Enable all of output pins */
+	sb_gpioouten(sbh, OUTENMASK, OUTENMASK);
+
+	/* We don't want the B_RESET pin changed, unless
+	 * it tries to set the B_RESET pin.
+	 */
+	if (x & B_RESET)
+		sb_gpioout(sbh, OUTENMASK, x);
+	else
+		sb_gpioout(sbh, CFGMASK, x);
+	
+}
+	
+void
+gpio_line_set(int x, unsigned int value)
+{
+	ASSERT(sbh);
+
+	if (value == 1)
+		sb_gpioout(sbh, BIT(x), BIT(x));
+	else if (value == 0)
+		sb_gpioout(sbh, BIT(x), 0);
+}
+
+void
+gpio_line_get(int x, int *value)
+{
+	ASSERT(sbh);
+
+	*value = (sb_gpioin(sbh) >> x) & 0x1;
+}
+
+void
+gpio_line_config_in(int x)
+{
+	ASSERT(sbh);
+	
+	sb_gpioouten(sbh, BIT(x), 0);
+	sb_gpiointmask(sbh, BIT(x), BIT(x));
+}
+
+void
+gpio_line_config_out(int x)
+{
+	ASSERT(sbh);
+
+	sb_gpiointmask(sbh, BIT(x), 0);
+	sb_gpioouten(sbh, BIT(x), BIT(x));
+}
+
+void
+gpio_line_config_out_all(int x)
+{
+	ASSERT(sbh);
+
+	sb_gpioouten(sbh, OUTENMASK, OUTENMASK);
+}
diff -bEruN linux-2.4.20-my/drivers/net/port_based_qos/c47xx.h linux-2.4.20-nc/drivers/net/port_based_qos/c47xx.h
--- linux-2.4.20-my/drivers/net/port_based_qos/c47xx.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/port_based_qos/c47xx.h	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,23 @@
+#ifndef _C47XX_H_
+#define _C47XX_H_
+
+extern void	*bcm947xx_sbh;
+#define sbh bcm947xx_sbh
+
+#define GPIO0	0
+#define GPIO1	1
+#define GPIO2	2
+#define GPIO3	3
+#define GPIO4	4
+#define GPIO5	5
+#define GPIO6	6
+#define GPIO7	7
+#define GPIO8	8
+
+#define B_RESET		1<<GPIO0
+#define B_ECS		1<<GPIO2
+#define B_ECK		1<<GPIO3
+#define B_EDO		1<<GPIO4
+#define B_EDI		1<<GPIO5
+
+#endif
diff -bEruN linux-2.4.20-my/drivers/net/port_based_qos/eeprom.c linux-2.4.20-nc/drivers/net/port_based_qos/eeprom.c
--- linux-2.4.20-my/drivers/net/port_based_qos/eeprom.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/port_based_qos/eeprom.c	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,355 @@
+#include <linux/delay.h>
+
+#define EEDO_PIN	4
+#define EECS_PIN	2
+#define EECK_PIN	3
+#define EEDI_PIN	5
+#define RESET_PIN	0
+
+static void SetCSToLowForEEprom(void);
+//static void SetCSToHighForEEprom(void);
+static void send1ToEEprom(void);
+static void send0ToEEprom(void);
+static void InitSerialInterface(void);
+static void SerialPulse(void);
+static void WriteDataToRegister(unsigned short RegNumber, unsigned short data);
+void ReadDataFromRegister(unsigned short addr, unsigned short *hidata, unsigned short *lodata,int select_count);
+static void WriteDataToEEprom(unsigned short addr, unsigned short data);
+static void WriteCmdToEEprom(unsigned short cmd);
+extern void gpio_line_set(int x, unsigned int value);
+extern void gpio_line_get(int x, int *value);
+extern void gpio_line_config_out(int x);
+extern void gpio_line_config_in(int x);
+extern void gpio_line_config_out_all(void);
+//  ;cs     __--   ,bit 3
+//  ;sck    ____   ,bit 4
+//  ;di     ____   ,bit 5
+//  ;do     ____   ,bit 6
+//  ;
+
+static void SetEEpromToSendState(void)
+{        
+	gpio_line_set(EECS_PIN, 0); 
+        gpio_line_set(EECK_PIN, 0);       
+	gpio_line_set(EEDI_PIN, 1);	
+//	gpio_line_set(EEDO_PIN, 1);    /* high impedance */	
+	
+        mdelay(1);
+        gpio_line_set(EECS_PIN, 1);
+//	gpio_line_set(EEDO_PIN, 1);    /* high impedance */
+}
+
+#if 0
+static void EEpromInit(void)
+{
+	gpio_line_set(EECS_PIN, 0); 
+        gpio_line_set(EECK_PIN, 0);       
+	gpio_line_set(EEDI_PIN, 1);	
+	gpio_line_set(EEDO_PIN, 1);    /* high impedance */	
+	
+        mdelay(1);
+}
+   
+//  ;cs     ____   ,bit 3  
+//  ;sck    ____   ,bit 4
+//  ;di     ____   ,bit 5
+//  ;do     ____   ,bit 6 
+//  ;
+static void ResetEEpromToSendState(void)
+{
+	gpio_line_set(EECS_PIN, 0);
+	gpio_line_set(EEDI_PIN, 0);
+	//gpio_line_set(EEDO_PIN, 0);
+	gpio_line_set(EECK_PIN, 0);
+}
+#endif /* 0 */
+   
+//  ;cs     ____   ,bit 3  
+//  ;sck    _--_   ,bit 4
+//  ;di     ____   ,bit 5
+//  ;do     ____   ,bit 6 
+//  ;
+static void SetCSToLowForEEprom(void)
+{
+        /* minimum tcs is 1us */      
+	gpio_line_set(EECS_PIN, 0);        
+        gpio_line_set(EECS_PIN, 0); 	  
+
+	gpio_line_set(EECK_PIN, 0);
+	gpio_line_set(EECK_PIN, 1);
+	gpio_line_set(EECK_PIN, 1);
+	gpio_line_set(EECK_PIN, 1);
+	gpio_line_set(EECK_PIN, 1);
+	gpio_line_set(EECK_PIN, 0);
+
+	gpio_line_set(EECS_PIN, 1);     
+
+        udelay(10);
+}
+
+#if 0  
+//  ;cs     ----   ,bit 3
+//  ;sck    _--_   ,bit 4
+//  ;di     ____   ,bit 5
+//  ;do     ____   ,bit 6  
+//  ;
+static void SetCSToHighForEEprom(void)
+{
+	gpio_line_set(EECS_PIN, 1);
+	
+        /* min tskh and tskl is 1us */
+	gpio_line_set(EECK_PIN, 1);
+	udelay(2);
+	gpio_line_set(EECK_PIN, 0); 
+}
+#endif /* 0 */
+  
+//  ;cs     ----   ,bit 3
+//  ;sck    _--_   ,bit 4
+//  ;di     ----   ,bit 5
+//  ;do     ____   ,bit 6
+//  ;       
+static void send1ToEEprom(void)
+{	   
+//printf("send1ToEEprom(1)...");
+	gpio_line_set(EEDI_PIN, 1);	    	     
+	    
+	gpio_line_set(EECK_PIN, 0);
+        udelay(1);	    
+	gpio_line_set(EECK_PIN, 1);             
+	gpio_line_set(EECK_PIN, 1);	 
+	gpio_line_set(EECK_PIN, 1);   	
+        udelay(1);
+	gpio_line_set(EECK_PIN, 0);
+}
+
+//  ;cs     ----   ,bit 3
+//  ;sck    _--_   ,bit 4
+//  ;di     ____   ,bit 5
+//  ;do     ____   ,bit 6
+//  ;       
+static void send0ToEEprom(void)
+{
+//printf("send0ToEEprom(0)...");
+	gpio_line_set(EEDI_PIN, 0);	    	     
+	    
+	gpio_line_set(EECK_PIN, 0);	    
+	udelay(1);
+	gpio_line_set(EECK_PIN, 1);             
+	gpio_line_set(EECK_PIN, 1);	 
+	gpio_line_set(EECK_PIN, 1);   	
+	udelay(1);
+	gpio_line_set(EECK_PIN, 0);
+}
+
+static void WriteDataToEEprom(unsigned short addr, unsigned short data) 
+{
+  unsigned short addr_mask, data_mask;
+  
+  SetEEpromToSendState();
+  for (addr_mask = 0x400; addr_mask != 0; )
+  {
+    if (addr & addr_mask) 
+      send1ToEEprom();
+    else
+      send0ToEEprom();  
+    addr_mask = addr_mask >> 1;    
+  }
+  for (data_mask = 0x8000; data_mask != 0; )
+  {
+    if (data & data_mask) 
+      send1ToEEprom();
+    else
+      send0ToEEprom();  
+    data_mask = data_mask >> 1;    
+  }
+  SetCSToLowForEEprom();
+}
+
+static void WriteCmdToEEprom(unsigned short cmd) 
+{
+  unsigned short cmd_mask;
+  
+  SetEEpromToSendState();
+  for (cmd_mask = 0x0400 ;cmd_mask != 0; )
+  {
+    if (cmd & cmd_mask) 
+      send1ToEEprom();
+    else
+      send0ToEEprom();  
+    cmd_mask = cmd_mask >> 1;
+  }
+   SetCSToLowForEEprom();
+}
+
+/*
+ * Write data to configure registers through EEPROM interface, even we do not have
+ * an external EEPROM connectted, ADM6996 got a virtual AT39C66 inside
+ */
+static void WriteDataToRegister(unsigned short RegNumber, unsigned short data)
+{
+    unsigned short cmd, addr;   
+
+    printk("WriteDataToRegister(RegNumber=0x%x, data=0x%x)\n", RegNumber, data);
+   
+//  the write enable(WEN) instruction must be executed before any device
+//  programming can be done
+    cmd = 0x04c0;
+    WriteCmdToEEprom(cmd); //00000001 0011000000B    
+
+    addr = 0x0500 | (RegNumber & 0x0ff); //00000001 01dddddddd   
+    WriteDataToEEprom(addr, data); //00000001 01dddddd
+    
+     
+//  after all data has been written to EEprom , the write disable(WDS) 
+//  instruction must be executed   
+    cmd = 0x0400;
+    WriteCmdToEEprom(cmd); //00000001 00000000B   
+}
+
+static void SerialDelay(int count)
+{        
+     udelay(count);
+}
+
+static void InitSerialInterface(void)
+{
+        gpio_line_set(EECK_PIN, 0);  
+        gpio_line_set(EEDI_PIN, 0);  
+}
+
+static void SerialPulse(void)
+{
+	 gpio_line_set(EECK_PIN, 0);  
+	 gpio_line_set(EECK_PIN, 1);  	
+         SerialDelay(10);
+         gpio_line_set(EECK_PIN, 1);  
+         gpio_line_set(EECK_PIN, 0);  
+}
+/* 
+ * Since there is no EEPROM is our board, read from EEPROM need to obey the timing alike
+ *  MII interface, EECK = MDC, EEDI = MDIO, please refer to section 4.3 of ADM6996 datasheet
+ */
+void ReadDataFromRegister(unsigned short addr, unsigned short *hidata, unsigned short *lodata, int select_count) 
+{
+  	unsigned short addr_mask, data_mask;
+  	int value, i;
+        unsigned char StartBits, Opcode, TAbits;
+	
+	gpio_line_config_out_all();
+	mdelay(1);	
+	/* initialize serial interface */
+        gpio_line_set(EECS_PIN, 0);  
+	InitSerialInterface();        
+
+        /* Preamble, 35 bits */
+        gpio_line_set(EECK_PIN, 0); 
+        gpio_line_set(EEDI_PIN, 1);
+        for (i = 0; i < 35; i++)        
+        {    
+            gpio_line_set(EECK_PIN, 1); 	                
+            SerialDelay(10);
+            gpio_line_set(EECK_PIN, 0); 
+	    SerialDelay(10);
+        }
+ 
+        /* Start bits, 2-bit(01b) */
+        InitSerialInterface();
+        StartBits = 0x01;
+        for (i = 0; i < 2; i++)
+        {
+             value = (StartBits & 2) ? 1 : 0;
+             gpio_line_set(EEDI_PIN, value);  
+             SerialDelay(1);
+             SerialPulse();
+             StartBits <<= 1;
+         }
+          
+         /* Opcode, read = 10b */
+         InitSerialInterface();
+         Opcode = 0x02;
+         for (i = 0; i < 2; i++)
+         {
+             value = (Opcode & 0x02) ? 1 : 0;
+             gpio_line_set(EEDI_PIN, value);  
+	     SerialDelay(1);
+             SerialPulse();
+             Opcode <<= 1;
+         }         
+
+         /* 10 bits register address */
+         /* 1-bit Table Select, 2-bit Device Address, 7-bit Register Address  */         
+         InitSerialInterface();
+	 if (select_count)
+	 	addr = (addr & 0x7f) | 0x200; 
+	 else
+	 	addr = addr & 0x7f ; 
+         for (addr_mask = 0x200; addr_mask != 0; addr_mask >>= 1)
+         {
+             value = (addr & addr_mask) ? 1 : 0;
+             gpio_line_set(EEDI_PIN, value);  
+	     SerialDelay(1);
+             SerialPulse();           
+         }      	
+
+         /* TA, turnaround 2-bit */
+         InitSerialInterface();
+         TAbits = 0x02;	
+          gpio_line_config_in(EEDI_PIN);
+         for (i = 0; i < 2; i++)
+         {
+             gpio_line_set(EECK_PIN, 1);  	     
+	     SerialDelay(4);  	     
+	     gpio_line_get(EEDI_PIN, &value); 
+	     SerialDelay(4);  
+             TAbits <<= 1;            
+	     gpio_line_set(EECK_PIN, 1);
+         }
+ 
+	
+         /* Latch data from serial management EEDI pin */
+         *hidata = 0;
+         gpio_line_set(EECK_PIN, 0);  
+	 for (data_mask = 0x8000; data_mask != 0; data_mask >>= 1)       
+         {
+             SerialDelay(4);             
+             gpio_line_set(EECK_PIN, 1);  
+             gpio_line_get(EEDI_PIN, &value); 
+             if (value)
+             {
+                 *hidata |= data_mask;                 
+	     }
+             gpio_line_set(EECK_PIN, 0); 
+	     SerialDelay(4);
+         }
+	 *lodata = 0;
+         gpio_line_set(EECK_PIN, 0);  
+	 for (data_mask = 0x8000; data_mask != 0; data_mask >>= 1)       
+         {
+             SerialDelay(4);           
+             gpio_line_set(EECK_PIN, 1);  
+             gpio_line_get(EEDI_PIN, &value); 
+             if (value)
+             {
+                 *lodata |= data_mask;                 
+	     }
+             gpio_line_set(EECK_PIN, 0); 
+	     SerialDelay(4);
+         }
+  	
+         SerialDelay(2);
+
+         /* Idle, EECK must send at least one clock at idle time */
+         SerialPulse();
+         gpio_line_set(EECK_PIN, 0);  
+         SerialDelay(10);
+         gpio_line_set(EECK_PIN, 1);  
+         SerialDelay(10);
+         gpio_line_set(EECK_PIN, 0);  
+         SerialPulse();
+
+         gpio_line_config_out(EEDI_PIN);
+	 gpio_line_set(EECS_PIN, 1);
+
+   //printk("ReadDataFromRegister(addr=0x%x, hidata=0x%x, lodata=0x%x)\n", addr, *hidata, *lodata);
+}
diff -bEruN linux-2.4.20-my/drivers/net/port_based_qos/Makefile linux-2.4.20-nc/drivers/net/port_based_qos/Makefile
--- linux-2.4.20-my/drivers/net/port_based_qos/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/port_based_qos/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,27 @@
+#  Copyright 2001, Cybertan Corporation
+#  All Rights Reserved.
+#  
+#  This is UNPUBLISHED PROPRIETARY SOURCE CODE of Cybertan Corporation;
+#  the contents of this file may not be disclosed to third parties, copied or
+#  duplicated in any form, in whole or in part, without the prior written
+#  permission of Cybertan Corporation.
+#
+#
+# $Id: Makefile,v 1.2 2004/03/02 13:23:33 cnhsieh Exp $
+#
+
+O_TARGET	:= port_based_qos_mod.o 
+
+PORT_BASED_QOS_MOD_OBJS	:= port_based_qos.o Atan.o c47xx.o eeprom.o 
+
+export-objs	:= 
+obj-y		:= $(PORT_BASED_QOS_MOD_OBJS)
+obj-m		:= $(O_TARGET)
+
+SRCBASE		:= $(TOPDIR)/../..
+EXTRA_CFLAGS	+= -I$(SRCBASE)/include -Wall -I$(SRCBASE)/
+
+vpath %.c $(SRCBASE)/shared
+
+include $(TOPDIR)/Rules.make
+
diff -bEruN linux-2.4.20-my/drivers/net/port_based_qos/port_based_qos.c linux-2.4.20-nc/drivers/net/port_based_qos/port_based_qos.c
--- linux-2.4.20-my/drivers/net/port_based_qos/port_based_qos.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/port_based_qos/port_based_qos.c	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,479 @@
+ /*
+ * Remaining issues:
+ *   + stats support
+ *   + multicast support
+ *   + media sense
+ *   + half/full duplex
+ *   - random MAC addr.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <asm/io.h>
+
+#include <linux/sysctl.h>
+#include <cy_conf.h>
+
+#define MODULE_NAME "port_based_qos_mod"
+#define DEVICE_NAME "qos"
+#define MODULE_VERSION "0.0.1"
+
+extern void ReadDataFromRegister(unsigned short addr, unsigned short *hidata, unsigned short *lodata,int select_count);
+
+#ifdef PERFORMANCE_SUPPORT
+static struct ctl_table_header *qos_sysctl_header;
+static unsigned long qos[28];
+
+static ctl_table mytable[] = {
+         { 2000, "qos", 
+	   qos, sizeof(qos), 
+	   0644, NULL, 
+	   proc_dointvec },
+         { 0 }
+};
+
+static unsigned short statis_addr_map[7][6] ={
+	{0x04, 0x06, 0x08, 0x0a, 0x0b, 0x0c},
+	{0x16, 0x18, 0x1a, 0x1c, 0x1d, 0x1e},
+	{0x0d, 0x0f, 0x11, 0x13, 0x14, 0x15},
+	{0x1f, 0x21, 0x23, 0x25, 0x26, 0x27},
+	{0x31, 0x33, 0x35, 0x37, 0x38, 0x39},
+	{0x28, 0x2a, 0x2c, 0x2e, 0x2f, 0x30},
+	{0x01, 0x01, 0x01, 0x01, 0x01, 0x01}
+};
+
+unsigned long get_statistic_from_serial(unsigned short port, unsigned short item)
+{
+    unsigned short hidata, lodata;
+	
+    ReadDataFromRegister(statis_addr_map[item][port], &hidata, &lodata, 1); 
+	return ((hidata << 16) | lodata);
+}
+#endif
+
+void ReadDataFromRegister_(unsigned short reg_idx, unsigned short *hidata, unsigned short *lodata)
+{
+    ReadDataFromRegister(reg_idx, hidata, lodata, 1);
+}
+
+#ifdef HW_QOS_SUPPORT
+struct port_qos_t{
+	int addr;
+	int content_mask;
+	int *content_set; 
+};
+
+void WriteDataToRegister_(unsigned short reg_idx, unsigned short content_idx);
+extern void write_eeprom(short,short *,int);
+
+#define BANDWIDTH_1_BIT	2
+#define BANDWIDTH_2_BIT	4
+#define BANDWIDTH_3_BIT	6
+#define BANDWIDTH_4_BIT	7
+
+#define PORT_CONFIG_0	0x1
+#define PORT_CONFIG_1	0x3
+#define PORT_CONFIG_2	0x5
+#define PORT_CONFIG_3	0x7
+#define PORT_CONFIG_4	0x8
+#define BANDWIDTH_CTL_123	0x31
+#define BANDWIDTH_CTL_4	0x32
+#define BANDWIDTH_CTL_ENABLE	0x33
+#define DISCARD_MODE	0x10
+#define TOS_PRIO_MAP	0xf
+
+#define PRIORITY_MASK	0xfc7f
+#define PRIORITY_DISABLE_MASK	0xfc7e
+#define FLOW_CTL_MASK	0xfffe
+#define RATE_LIMIT_MASK_1	0xff8f
+#define RATE_LIMIT_MASK_2	0xf8ff
+#define RATE_LIMIT_MASK_3	0x8fff
+#define RATE_LIMIT_MASK_4	0xfff8
+#define BANDWIDTH_CTL_MASK	0xff2b
+#define DISCARD_MASK	0x0fff
+#define SPEED_MASK	0xfff1
+
+#define BANDWIDTH_ENABLE_1	1 << BANDWIDTH_1_BIT//04 
+#define BANDWIDTH_ENABLE_2	1 << BANDWIDTH_2_BIT//10 
+#define BANDWIDTH_ENABLE_3	1 << BANDWIDTH_3_BIT//40 
+#define BANDWIDTH_ENABLE_4	1 << BANDWIDTH_4_BIT//80 
+#define BANDWIDTH_CTL_MASK_1	0xffff^BANDWIDTH_ENABLE_1//0xfffb 
+#define BANDWIDTH_CTL_MASK_2	0xffff^BANDWIDTH_ENABLE_2//0xffef 
+#define BANDWIDTH_CTL_MASK_3	0xffff^BANDWIDTH_ENABLE_3//0xffbf 
+#define BANDWIDTH_CTL_MASK_4	0xffff^BANDWIDTH_ENABLE_4//0xff7f 
+
+/*static int disable_content[] = {0x0};
+//static int enable_content[] = {0xd4, 0x0cff};//bit 7,6,4,2; Q1=11(50%),Q0=00(0%)*/
+//static int sw_content[] = {0x0,0x0c00};//bit 7,6,4,2; Q1=11(50%),Q0=00(0%)
+static int sw_content[] = {0x0,0xc000};//bit 7,6,4,2; Q1=11(50%),Q0=00(0%)
+static int port_priority_content[] = {0x080,0x380};//Q0,Q3
+//static int port_priority_content[] = {0x300,0x0};//Q1,Q0
+static int port_flow_ctl_content[] = {0x0,0x1};
+static int port_rate_limit_content_1[] = {0x0,0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70};
+static int port_rate_limit_content_2[] = {0x0,0x000,0x100,0x200,0x300,0x400,0x500,0x600,0x700};
+static int port_rate_limit_content_3[] = {0x0,0x0000,0x1000,0x2000,0x3000,0x4000,0x5000,0x6000,0x7000};
+static int port_rate_limit_content_4[] = {0x0,0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7};
+static int port_rate_limit_enable_1[] = {0x0, BANDWIDTH_ENABLE_1};
+static int port_rate_limit_enable_2[] = {0x0, BANDWIDTH_ENABLE_2};
+static int port_rate_limit_enable_3[] = {0x0, BANDWIDTH_ENABLE_3};
+static int port_rate_limit_enable_4[] = {0x0, BANDWIDTH_ENABLE_4};
+//static int wan_speed_content[] = {0xe, 0xc, 0x4, 0x8, 0x0};//auto, 100Full, 100Half, 10Full, 10Half
+static int wan_speed_content[] = {0x8, 0x0, 0xc, 0x4, 0xe};//10Full, 10Half, 100Full, 100Half, Auto
+
+static struct port_qos_t port_mii_disable[] = {
+	{ BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK, sw_content},
+	//{ DISCARD_MODE, DISCARD_MASK, sw_content},
+	{ PORT_CONFIG_1, PRIORITY_MASK, sw_content},//port_priority_1
+	{ PORT_CONFIG_2, PRIORITY_MASK, sw_content},//port_priority_2
+	{ PORT_CONFIG_3, PRIORITY_MASK, sw_content},//port_priority_3
+	{ PORT_CONFIG_4, PRIORITY_MASK, sw_content},//port_priority_4
+	{ PORT_CONFIG_1, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_1
+	{ PORT_CONFIG_2, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_2
+	{ PORT_CONFIG_3, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_3
+	{ PORT_CONFIG_4, FLOW_CTL_MASK, &port_flow_ctl_content[1]},//port_flow_control_4
+	{ -1}
+};
+
+static struct port_qos_t port_mii_enable[] = {
+	//{ BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK, enable_content},
+	//{ DISCARD_MODE, DISCARD_MASK, sw_content},
+	{ -1}
+};
+
+struct port_qos_t *port_mii_sw_array[] = {port_mii_disable, port_mii_enable};
+
+/*static struct port_qos_t port_mii_addr[] = {
+	{ PORT_CONFIG_1, PRIORITY_MASK, port_priority_content},//port_priority_1
+	{ PORT_CONFIG_1, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_1
+	//{ "port_frame_type_1", 0x3},
+	{ BANDWIDTH_CTL_123, RATE_LIMIT_MASK_14, port_rate_limit_content_14},//port_rate_limit_1
+	{ PORT_CONFIG_2, PRIORITY_MASK, port_priority_content},//port_priority_2
+	{ PORT_CONFIG_2, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_2
+	//{ "port_frame_type_2", 0x5},
+	{ BANDWIDTH_CTL_123, RATE_LIMIT_MASK_2, port_rate_limit_content_2},//port_rate_limit_2
+	{ PORT_CONFIG_3, PRIORITY_MASK, port_priority_content},//port_priority_3
+	{ PORT_CONFIG_3, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_3
+	//{ "port_frame_type_3", 0x7},
+	{ BANDWIDTH_CTL_123, RATE_LIMIT_MASK_3, port_rate_limit_content_3},//port_rate_limit_3
+	//{ "port_priority_4", 0x8, 0x380},
+	{ PORT_CONFIG_4, PRIORITY_MASK, port_priority_content},//port_priority_4
+	{ PORT_CONFIG_4, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_4
+	//{ "port_frame_type_4", 0x8},
+	{ BANDWIDTH_CTL_4, RATE_LIMIT_MASK_14, port_rate_limit_content_14},//port_rate_limit_4
+	{ -1}
+};*/
+
+static struct port_qos_t priority_1[] = {
+	{ PORT_CONFIG_1, PRIORITY_MASK, port_priority_content},//port_priority_1
+	{ -1}
+};
+static struct port_qos_t flow_control_1[] = {
+	{ PORT_CONFIG_1, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_1
+	{ -1}
+};
+static struct port_qos_t rate_limit_1[] = {
+	{ BANDWIDTH_CTL_123, RATE_LIMIT_MASK_1, port_rate_limit_content_1},//port_rate_limit_1
+	{ BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_1, port_rate_limit_enable_1},//port_rate_limit_4
+	{ -1}
+};
+static struct port_qos_t priority_2[] = {
+	{ PORT_CONFIG_2, PRIORITY_MASK, port_priority_content},//port_priority_2
+	{ -1}
+};
+static struct port_qos_t flow_control_2[] = {
+	{ PORT_CONFIG_2, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_2
+	{ -1}
+};
+static struct port_qos_t rate_limit_2[] = {
+	{ BANDWIDTH_CTL_123, RATE_LIMIT_MASK_2, port_rate_limit_content_2},//port_rate_limit_2
+	{ BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_2, port_rate_limit_enable_2},//port_rate_limit_4
+	{ -1}
+};
+static struct port_qos_t priority_3[] = {
+	{ PORT_CONFIG_3, PRIORITY_MASK, port_priority_content},//port_priority_3
+	{ -1}
+};
+static struct port_qos_t flow_control_3[] = {
+	{ PORT_CONFIG_3, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_3
+	{ -1}
+};
+static struct port_qos_t rate_limit_3[] = {
+	{ BANDWIDTH_CTL_123, RATE_LIMIT_MASK_3, port_rate_limit_content_3},//port_rate_limit_3
+	{ BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_3, port_rate_limit_enable_3},//port_rate_limit_4
+	{ -1}
+};
+static struct port_qos_t priority_4[] = {
+	{ PORT_CONFIG_4, PRIORITY_MASK, port_priority_content},//port_priority_4
+	{ -1}
+};
+static struct port_qos_t flow_control_4[] = {
+	{ PORT_CONFIG_4, FLOW_CTL_MASK, port_flow_ctl_content},//port_flow_control_4
+	{ -1}
+};
+static struct port_qos_t rate_limit_4[] = {
+	{ BANDWIDTH_CTL_4, RATE_LIMIT_MASK_4, port_rate_limit_content_4},//port_rate_limit_4
+	{ BANDWIDTH_CTL_ENABLE, BANDWIDTH_CTL_MASK_4, port_rate_limit_enable_4},//port_rate_limit_4
+	{ -1}
+};
+static struct port_qos_t wan_speed[] = {
+	{ PORT_CONFIG_0, SPEED_MASK, wan_speed_content},
+	{ -1}
+};
+
+static struct port_qos_t *port_mii_addr[] = {
+	priority_1,
+	flow_control_1,
+	rate_limit_1,
+	priority_2,
+	flow_control_2,
+	rate_limit_2,
+	priority_3,
+	flow_control_3,
+	rate_limit_3,
+	priority_4,
+	flow_control_4,
+	rate_limit_4,
+	wan_speed,
+	NULL
+};
+
+void WriteDataToRegister_(unsigned short reg_idx, unsigned short content_idx)
+{
+    short RegNumber;
+    unsigned short data, hidata=0x0, lodata=0x0;
+    int i;
+    struct port_qos_t *port_qos = port_mii_addr[reg_idx];
+    
+    //printk("\nWriteDataToRegister_:reg_idx=%d content_idx=%d\n", reg_idx, content_idx);
+    if (!port_qos)
+	 port_qos = port_mii_sw_array[content_idx];
+	
+    for (i=0; port_qos[i].addr != -1; i++)
+    {
+    	RegNumber = port_qos[i].addr;
+ 	ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
+
+        if (!(RegNumber % 2)) /* even port number use lower word */
+		hidata = lodata;
+
+        data = (hidata & port_qos[i].content_mask) | (((i > 0) && (content_idx > 1))? port_qos[i].content_set[1] : port_qos[i].content_set[content_idx]);
+	
+	write_eeprom(RegNumber, &data, 1);
+   	ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
+    }
+   	ReadDataFromRegister(0xf, &hidata, &lodata, 0);
+    	
+	/*RegNumber = port_mii_addr[reg_idx].addr;
+	if (RegNumber == -1)//Disable or Enable
+	{
+		struct port_qos_t *port_mii_sw = port_mii_sw_array[content_idx];
+	
+    		printk("\nWriteDataToRegister_:reg_idx=%d content_idx=%d\n", reg_idx, content_idx);
+		for (i=0; port_mii_sw[i].addr != -1; i++)
+		{
+    			RegNumber = port_mii_sw[i].addr;
+				
+			ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
+        		
+			if (!(RegNumber % 2)) 
+				hidata = lodata;
+			 
+		        data = (hidata & port_mii_sw[i].content_mask) | port_mii_sw[i].content_set[i];
+	
+			write_eeprom(RegNumber, &data, 1);
+    			
+   			ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
+			printk("\n============== %s===============\n", (content_idx==0)?"disable":"enable");
+		}
+	}
+	else
+	{
+    		ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
+
+        	if (!(RegNumber % 2)) 
+			hidata = lodata;
+
+	        data = (hidata & port_mii_addr[reg_idx].content_mask) | port_mii_addr[reg_idx].content_set[content_idx];
+	
+		write_eeprom(RegNumber, &data, 1);
+   		ReadDataFromRegister(RegNumber, &hidata, &lodata, 0);
+	}*/
+}
+#endif
+
+static int dev_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+    struct mii_ioctl_data *data = (struct mii_ioctl_data *)req->ifr_data;
+#ifdef PERFORMANCE_SUPPORT
+    int item, port; 
+    
+    unsigned long status_item;
+#endif
+    
+    switch (cmd)
+    {
+    case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
+    case SIOCDEVPRIVATE:	/* for binary compat, remove in 2.5 */
+
+	/* Fall through to the SIOCGMIIREG, taken from eepro100 and rtl
+	 * drivers */
+    case SIOCGMIIREG:		/* Read MII PHY register. */
+#ifdef PERFORMANCE_SUPPORT
+	for (item=0; item<6; item++)
+		for (port=1; port<5; port++){
+			qos[(item * 4) + (port-1)] = get_statistic_from_serial(port, item);	
+		}
+	
+	status_item = get_statistic_from_serial(0, 6);
+	
+	qos[24] = (0x1 & (status_item >> 8));
+	qos[25] = (0x1 & (status_item >> 16));
+	qos[26] = (0x1 & (status_item >> 24));
+	qos[27] = (0x1 & (status_item >> 28));
+	
+	return 0;
+#else
+   	ReadDataFromRegister_(data->phy_id, &data->val_in, &data->val_out); 
+	return 0;
+		
+#endif
+
+    case SIOCDEVPRIVATE+1:	/* for binary compat, remove in 2.5 */
+#ifdef HW_QOS_SUPPORT
+    case SIOCSMIIREG:		/* Write MII PHY register. */
+	{
+	//printk("\n x phy_id=%x\n", data->phy_id);
+	//printk("\n x reg_num=%x\n", data->reg_num);
+	//printk("\n x val_in=%x\n", data->val_in);
+	//printk("\n x val_out=%x\n", data->val_out);
+		
+   	WriteDataToRegister_(data->phy_id, data->val_in); 
+	return 0;
+	}
+#endif
+    case SIOCDEVPRIVATE+2:	/* for binary compat, remove in 2.5 */
+    default:
+	return -EOPNOTSUPP;
+    }
+}
+
+static int __devinit qos_eth_probe(struct net_device *dev)
+{
+    
+    SET_MODULE_OWNER(dev);
+
+    ether_setup(dev);
+
+    strcpy(dev->name, DEVICE_NAME "0");
+
+    dev->do_ioctl = dev_do_ioctl;
+
+    return 0;
+}
+
+#ifdef HW_QOS_SUPPORT
+static char *port_option_name[] = {
+ 	"port_priority_1",
+	"port_flow_control_1",
+	//{ "port_frame_type_1",
+	"port_rate_limit_1",
+	"port_priority_2",
+	"port_flow_control_2",
+	//{ "port_frame_type_2",
+	"port_rate_limit_2",
+	"port_priority_3",
+	"port_flow_control_3",
+	//{ "port_frame_type_3",
+	"port_rate_limit_3",
+	"port_priority_4",
+	//{ "port_priority_4", PORT_CONFIG_4, PRIORITY_MASK, port_priority_content},
+	"port_flow_control_4",
+	//{ "port_frame_type_4",
+	"port_rate_limit_4",
+	"wan_speed",
+	"QoS",
+	NULL
+};
+
+extern char *nvram_get(const char *name);
+extern uint bcm_atoi(char *s);
+
+static int set_port_option(struct net_device *dev, unsigned short port_addr, char *option_content)
+{
+    struct ifreq ifr;
+    struct mii_ioctl_data stats;
+	
+    stats.phy_id=port_addr;
+    stats.val_in=bcm_atoi(option_content);
+
+    ifr.ifr_data = (void *)&stats;
+    
+    return dev_do_ioctl(dev, &ifr, SIOCSMIIREG);
+}
+
+
+void
+restore_default_from_NV(struct net_device *dev)
+{
+	unsigned short i;
+	char *value = NULL;
+	
+	for (i = 0; port_option_name[i]; i++)
+	{
+		if((value = nvram_get(port_option_name[i])))
+			set_port_option(dev, i, value);
+	}
+	return;
+}
+#endif
+
+static struct net_device qos_devices;
+
+/* Module initialization and cleanup */
+int init_module(void)
+{
+    int res;
+    struct net_device *dev;
+
+    printk("Initializing " MODULE_NAME " driver " MODULE_VERSION "\n");
+
+	dev = &qos_devices;
+
+	dev->init = qos_eth_probe;
+
+	if ((res = register_netdev(dev)))
+	    printk("Failed to register netdev. res = %d\n", res);
+
+#ifdef PERFORMANCE_SUPPORT
+    	qos_sysctl_header = register_sysctl_table(mytable, 0);
+#endif
+#ifdef HW_QOS_SUPPORT
+	restore_default_from_NV(dev);
+	write_eeprom(TOS_PRIO_MAP, &sw_content[0], 1);/* disable TOS priority map*/
+#endif
+    return 0;
+}
+
+void cleanup_module(void)
+{
+	struct net_device *dev = &qos_devices;
+	if (dev->priv != NULL)
+	{
+	    unregister_netdev(dev);
+	    kfree(dev->priv);
+	    dev->priv = NULL;
+	}
+    	
+#ifdef PERFORMANCE_SUPPORT
+	unregister_sysctl_table(qos_sysctl_header);
+#endif
+}
+
diff -bEruN linux-2.4.20-my/drivers/net/wl/Makefile linux-2.4.20-nc/drivers/net/wl/Makefile
--- linux-2.4.20-my/drivers/net/wl/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/wl/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,47 @@
+#
+# Makefile for the Broadcom wl driver
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+# $Id: Makefile,v 1.1.1.9 2005/03/07 07:30:49 kanki Exp $
+#
+
+O_TARGET	:= wl.o
+
+# get the variant for linking
+ifeq ($(CONFIG_WL_LINK),"AP")
+  WL_PREFIX := ap
+  CONFIG_WL_CONF = $(CONFIG_WL_AP)
+else
+ifeq ($(CONFIG_WL_LINK),"STA")
+    WL_PREFIX := sta
+    CONFIG_WL_CONF = $(CONFIG_WL_STA)
+else
+ifeq ($(CONFIG_WL_LINK),"APSTA")
+      WL_PREFIX := apsta
+      CONFIG_WL_CONF = $(CONFIG_WL_APSTA)
+else
+ifeq ($(CONFIG_WL_LINK),"DNGL")
+      WL_PREFIX := dngl
+      CONFIG_WL_CONF = $(CONFIG_WL_DNGL)
+else                                   
+$(error CONFIG_WL_LINK=$(CONFIG_WL_LINK) is wrong, must be AP/STA/APSTA/DNGL)
+endif
+endif
+endif
+endif
+
+# compile variants in sub directories if necessary
+
+
+subdir-y += $(wlsubdirs)
+subdir-m += $(wlsubdirs)
+
+
+include ./wl_generic.mk
diff -bEruN linux-2.4.20-my/drivers/net/wl/wl_ap/Makefile linux-2.4.20-nc/drivers/net/wl/wl_ap/Makefile
--- linux-2.4.20-my/drivers/net/wl/wl_ap/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/wl/wl_ap/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,21 @@
+#
+# Makefile for the Broadcom wl driver
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+# $Id: Makefile,v 1.4 2005/03/07 08:35:32 kanki Exp $
+#
+
+WL_PREFIX := ap
+
+CONFIG_WL_CONF := $(CONFIG_WL_AP)
+
+O_TARGET := wl_$(WL_PREFIX).o
+
+include ../wl_generic.mk
diff -bEruN linux-2.4.20-my/drivers/net/wl/wl_ap/wlconf.h linux-2.4.20-nc/drivers/net/wl/wl_ap/wlconf.h
--- linux-2.4.20-my/drivers/net/wl/wl_ap/wlconf.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/wl/wl_ap/wlconf.h	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,18 @@
+/*
+ * Broadcom 802.11abg Networking Device Driver Configuration file
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: wlconf.h,v 1.1.3.1 2005/03/18 02:55:48 kanki Exp $
+ *
+ * wl driver tunables for linux router
+ */
+#define	NRXBUFPOST	32
+
+
diff -bEruN linux-2.4.20-my/drivers/net/wl/wl_apsta/Makefile linux-2.4.20-nc/drivers/net/wl/wl_apsta/Makefile
--- linux-2.4.20-my/drivers/net/wl/wl_apsta/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/wl/wl_apsta/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,21 @@
+#
+# Makefile for the Broadcom wl driver
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+# $Id: Makefile,v 1.4 2005/03/07 08:35:32 kanki Exp $
+#
+
+WL_PREFIX := apsta
+
+CONFIG_WL_CONF := $(CONFIG_WL_APSTA)
+
+O_TARGET := wl_$(WL_PREFIX).o
+
+include ../wl_generic.mk
diff -bEruN linux-2.4.20-my/drivers/net/wl/wl_apsta/wlconf.h linux-2.4.20-nc/drivers/net/wl/wl_apsta/wlconf.h
--- linux-2.4.20-my/drivers/net/wl/wl_apsta/wlconf.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/wl/wl_apsta/wlconf.h	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,18 @@
+/*
+ * Broadcom 802.11abg Networking Device Driver Configuration file
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: wlconf.h,v 1.1.3.1 2005/03/18 02:55:48 kanki Exp $
+ *
+ * wl driver tunables for linux router
+ */
+#define	NRXBUFPOST	32
+
+
diff -bEruN linux-2.4.20-my/drivers/net/wl/wlconf.h linux-2.4.20-nc/drivers/net/wl/wlconf.h
--- linux-2.4.20-my/drivers/net/wl/wlconf.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/wl/wlconf.h	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,18 @@
+/*
+ * Broadcom 802.11abg Networking Device Driver Configuration file
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: wlconf.h,v 1.1.3.1 2005/03/18 02:55:48 kanki Exp $
+ *
+ * wl driver tunables for linux router
+ */
+#define	NRXBUFPOST	32
+
+
diff -bEruN linux-2.4.20-my/drivers/net/wl/wl_dngl/Makefile linux-2.4.20-nc/drivers/net/wl/wl_dngl/Makefile
--- linux-2.4.20-my/drivers/net/wl/wl_dngl/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/wl/wl_dngl/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,21 @@
+#
+# Makefile for the Broadcom wl driver
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+# $Id: Makefile,v 1.1.1.2 2005/03/07 07:30:49 kanki Exp $
+#
+
+WL_PREFIX := dngl
+
+CONFIG_WL_CONF := $(CONFIG_WL_DNGL)
+
+O_TARGET := wl_$(WL_PREFIX).o
+
+include ../wl_generic.mk
diff -bEruN linux-2.4.20-my/drivers/net/wl/wl_generic.mk linux-2.4.20-nc/drivers/net/wl/wl_generic.mk
--- linux-2.4.20-my/drivers/net/wl/wl_generic.mk	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/wl/wl_generic.mk	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,56 @@
+#
+# Generic portion of the Broadcom wl driver makefile
+#
+# input: O_TARGET, CONFIG_WL_CONF and WL_PREFIX 
+# output: obj-m, obj-y
+#
+# $Id: wl_generic.mk,v 1.1.1.1 2004/08/26 06:56:55 honor Exp $
+#
+
+# get the source file list from config file
+ifeq ($(CONFIG_WL_CONF),)
+$(error CONFIG_WL_CONF is undefined)
+endif
+WLCONFFILE :=$(strip $(subst ",,$(CONFIG_WL_CONF))) # remove quote ", added by parser
+
+WLCFGDIR   := $(SRCBASE)/wl/config
+
+# define OS flag to pick up wl osl file from wl.mk
+WLLX=1
+include $(WLCFGDIR)/$(WLCONFFILE)
+include $(WLCFGDIR)/wl.mk
+
+ifneq ($(WLFILES),)
+WL_SOURCE	:= $(WLFILES)
+else
+$(error WLFILES is undefined in $(WLCFGDIR)/$(WLCONFFILE))
+endif
+WL_DFLAGS       := $(WLFLAGS)
+WL_OBJS         := $(patsubst %.c,%.o,$(WL_SOURCE))
+
+VARIANT_WL_OBJS  := $(foreach obj,$(WL_OBJS),$(WL_PREFIX)_$(obj))
+
+# need -I. to pick up wlconf.h
+EXTRA_CFLAGS	+= -DDMA -I. $(WL_DFLAGS)
+
+# obj-y is for linking to wl.o
+export-objs	:=
+obj-y		:= $(VARIANT_WL_OBJS)
+obj-m		:= $(O_TARGET)
+
+# Search for sources under src/wl/sys or objects under src/wl/linux
+ifneq ($(wildcard $(SRCBASE)/wl/sys/wlc.h),)
+EXTRA_CFLAGS	+= -I$(SRCBASE)/wl/sys
+vpath %.c $(SRCBASE)/wl/sys $(SRCBASE)/shared $(SRCBASE)/bcmcrypto
+else
+#obj-y		:= $(SRCBASE)/wl/linux/wl.o
+obj-y		:= $(foreach objy,$(obj-y),$(SRCBASE)/wl/linux/$(objy))
+endif
+
+
+
+include $(TOPDIR)/Rules.make
+
+
+
+
diff -bEruN linux-2.4.20-my/drivers/net/wl/wl_sta/Makefile linux-2.4.20-nc/drivers/net/wl/wl_sta/Makefile
--- linux-2.4.20-my/drivers/net/wl/wl_sta/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/wl/wl_sta/Makefile	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,21 @@
+#
+# Makefile for the Broadcom wl driver
+#
+# Copyright 2005, Broadcom Corporation
+# All Rights Reserved.
+# 
+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+#
+# $Id: Makefile,v 1.4 2005/03/07 08:35:32 kanki Exp $
+#
+
+WL_PREFIX := sta
+
+CONFIG_WL_CONF := $(CONFIG_WL_STA)
+
+O_TARGET := wl_$(WL_PREFIX).o
+
+include ../wl_generic.mk
diff -bEruN linux-2.4.20-my/drivers/net/wl/wl_sta/wlconf.h linux-2.4.20-nc/drivers/net/wl/wl_sta/wlconf.h
--- linux-2.4.20-my/drivers/net/wl/wl_sta/wlconf.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-nc/drivers/net/wl/wl_sta/wlconf.h	2006-06-02 08:21:26.000000000 -0700
@@ -0,0 +1,18 @@
+/*
+ * Broadcom 802.11abg Networking Device Driver Configuration file
+ *
+ * Copyright 2005, Broadcom Corporation
+ * All Rights Reserved.
+ * 
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ * $Id: wlconf.h,v 1.1.3.1 2005/03/18 02:55:48 kanki Exp $
+ *
+ * wl driver tunables for linux router
+ */
+#define	NRXBUFPOST	32
+
+
diff -ruN linux-2.4.20-WRT/drivers/net/ext_io/ext_io.c linux-2.4.20-WRT54GSV4/drivers/net/ext_io/ext_io.c
--- linux-2.4.20-WRT/drivers/net/ext_io/ext_io.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-WRT54GSV4/drivers/net/ext_io/ext_io.c	2004-09-23 00:28:48.000000000 -0700
@@ -0,0 +1,113 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+
+#include <typedefs.h>
+#include <bcmutils.h>
+#include <sbutils.h>
+#include <bcmdevs.h>
+#include "ext_io.h"
+
+/*
+ * global variable for external I/O driver
+ */
+
+static u8 value;
+static int extio_major;
+static devfs_handle_t extio_handle = NULL;
+
+int extio_open (struct inode *inode, struct file *filp)
+{
+	//printk("tallest:=====( extio_open )=====\n");
+	return 0;
+}
+
+ssize_t extio_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+{
+	//printk("tallest:=====( extio_read )=====\n");
+	return 0;
+}
+
+ssize_t extio_write(struct file *filp, const char *buf, size_t count, loff_t *ppos)
+{
+	//printk("tallest:=====( extio_write )=====\n");
+	return 0;
+}
+
+int extio_release(struct inode* inode, struct file *flip)
+{
+	//printk("tallest:=====( extio_release )=====\n");
+	return 0;
+}
+
+int extio_flush(struct inode* inode)
+{
+	//printk("tallest:=====( extio_flush )=====\n");
+	return 0;
+}
+
+int extio_ioctl(struct inode * inode, struct file *flip, unsigned int cmd, unsigned long arg)
+{
+	//printk("tallest:=====( extio_ioctl )=====\n");
+	//printk("tallest:=====( cmd=0x%x )=====\n",cmd);
+
+	switch(cmd)
+	{
+		case GOT_IP:
+			value = (value & INTERNET_LED) | ILED_SOLID_GREEN;
+			*(volatile u8*)(KSEG1ADDR(EXTERNAL_IF_BASE)+ASYNC_IF_BASE)=value; // tallest
+			//printk("tallest:=====( DATA=0x%x  cmd=0x%x )=====\n",*(volatile u8*)(KSEG1ADDR(EXTERNAL_IF_BASE)+ASYNC_IF_BASE),cmd);
+			break;
+
+		case RELEASE_IP:
+			value = (value & INTERNET_LED) | ILED_OFF;
+			*(volatile u8*)(KSEG1ADDR(EXTERNAL_IF_BASE)+ASYNC_IF_BASE)=value; // tallest
+			//printk("tallest:=====( DATA=0x%x  cmd=0x%x )=====\n",*(volatile u8*)(KSEG1ADDR(EXTERNAL_IF_BASE)+ASYNC_IF_BASE),cmd);
+			break;
+
+		case GET_IP_ERROR:
+			value = (value & INTERNET_LED) | ILED_SOLID_AMBER;
+			*(volatile u8*)(KSEG1ADDR(EXTERNAL_IF_BASE)+ASYNC_IF_BASE)=value; // tallest
+			//printk("tallest:=====( DATA=0x%x  cmd=0x%x )=====\n",*(volatile u8*)(KSEG1ADDR(EXTERNAL_IF_BASE)+ASYNC_IF_BASE),cmd);
+			break;
+
+		case RELEASE_WAN_CONTROL:
+			value = (value & WAN_LED) | WLED_FLASHING_GREEN;
+			*(volatile u8*)(KSEG1ADDR(EXTERNAL_IF_BASE)+ASYNC_IF_BASE)=value; // tallest
+			//printk("tallest:=====( DATA=0x%x  cmd=0x%x )=====\n",*(volatile u8*)(KSEG1ADDR(EXTERNAL_IF_BASE)+ASYNC_IF_BASE),cmd);
+			break;
+	}
+	return 0;
+}
+
+struct file_operations extio_fops = {
+	read: extio_read,
+	write: extio_write,
+	open: extio_open, 
+	release: extio_release,
+	ioctl: extio_ioctl,
+	flush: extio_flush,
+};
+
+int init_module(void)
+{
+	if(extio_major=devfs_register_chrdev(0, "extio", &extio_fops) < 0)
+		return extio_major;
+
+	extio_handle=devfs_register(NULL, "extio", DEVFS_FL_DEFAULT, extio_major, 0,S_IFCHR | S_IRUGO | S_IWUGO,&extio_fops, NULL);
+	//printk("tallest:=====( tallest module init )=====\n");
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	devfs_unregister(extio_handle);
+	devfs_unregister_chrdev(0, "extio");
+	//printk("tallest:=====( tallest module cleanup )=====\n");
+	
+}
+
diff -ruN linux-2.4.20-WRT/drivers/net/ext_io/ext_io.h linux-2.4.20-WRT54GSV4/drivers/net/ext_io/ext_io.h
--- linux-2.4.20-WRT/drivers/net/ext_io/ext_io.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-WRT54GSV4/drivers/net/ext_io/ext_io.h	2004-10-13 18:01:25.000000000 -0700
@@ -0,0 +1,31 @@
+#include <asm/ioctl.h>
+
+#define EXTIO_IOC_MAGIC 'x'
+
+#define EXTIO_IOCRESET _IO(EXTIO_IOC_MAGIC, 0)
+#define EXTIO_IOCSFUNCTION _IOW(EXTIO_IOC_MAGIC, 1, int)
+#define EXTIO_IOCGOUTLEN _IOR(EXTIO_IOC_MAGIC, 2, int)
+#define EXTIO_IOC_MAXNR 2
+
+#define EXTERNAL_IF_BASE	0x1A000000
+#define ASYNC_IF_BASE		0x1000000
+
+/*
+	0~2 bit -> WAN LED
+	3~5 bit -> internet LED
+*/
+#define WAN_LED			0xc7
+#define INTERNET_LED		0xf8
+
+/*
+	color of LED
+*/
+#define ILED_SOLID_GREEN	0x06
+#define ILED_OFF		0x07
+#define ILED_SOLID_AMBER	0x03
+#define WLED_FLASHING_GREEN	0x30
+
+#define GOT_IP                  0x01
+#define RELEASE_IP              0x02
+#define GET_IP_ERROR            0x03
+#define RELEASE_WAN_CONTROL     0x04
diff -ruN linux-2.4.20-WRT/drivers/net/ext_io/Makefile linux-2.4.20-WRT54GSV4/drivers/net/ext_io/Makefile
--- linux-2.4.20-WRT/drivers/net/ext_io/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-WRT54GSV4/drivers/net/ext_io/Makefile	2004-09-23 00:28:48.000000000 -0700
@@ -0,0 +1,13 @@
+O_TARGET        := extio.o
+MAC_OBJS	:= ext_io.o
+
+export-objs     :=
+obj-y           := $(MAC_OBJS)
+obj-m           := $(O_TARGET)
+                                                                                                                                               
+SRCBASE         := $(TOPDIR)/../..
+EXTRA_CFLAGS    += -I$(SRCBASE)/include
+                                                                                                                                               
+vpath %.c $(SRCBASE)/shared
+                                                                                                                                               
+include $(TOPDIR)/Rules.make
diff -ruN linux-2.4.20-WRT/drivers/net/mac/mac.c linux-2.4.20-WRT54GSV4/drivers/net/mac/mac.c
--- linux-2.4.20-WRT/drivers/net/mac/mac.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-WRT54GSV4/drivers/net/mac/mac.c	2004-08-29 09:30:19.000000000 -0700
@@ -0,0 +1,731 @@
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include <typedefs.h>
+//#include <bcm4710.h>
+#include <bcmnvram.h>
+#include <sbextif.h>
+#include <flash.h>
+#include <flashutl.h>
+
+#include <cymac.h>
+
+#define FLASH_ADDR(off) ((unsigned long)flashutl_base + (off))
+#define WBUFSIZE 32
+#define FLASH_TRIES 4000000 
+#define CMD_ADDR ((unsigned long)0xFFFFFFFF)
+#define DONE	0x80
+#define AMD_CMD 0xaaa
+#define BLOCK_BASE 0
+#define BLOCK_LIM 1
+#define MIN(a, b)               (((a)<(b))?(a):(b))
+
+#define ASSERT(x)
+#define my_printk(x)
+#define DPRINT(x) printk(x)
+
+#define FLASH_BASE                0xbfc00000
+
+int MAC_START_ADDRESS;
+unsigned long offset;    
+char *string;
+int debug;
+char *flag;
+int add;
+
+MODULE_AUTHOR("Honor_kao");
+MODULE_DESCRIPTION("Write mac to 0x2000");
+MODULE_PARM(offset, "i");
+MODULE_PARM_DESC(offset, "Where address to write?");
+MODULE_PARM(string, "s");
+MODULE_PARM_DESC(string, "What mac address to write?");
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Turn on debug message.");
+MODULE_PARM(flag, "s");
+MODULE_PARM_DESC(flag, "Set flag to \"set\" to write mac.");
+MODULE_PARM(add, "i");
+MODULE_PARM_DESC(add, "How many mac to increment?");
+
+flash_desc_t*   flashutl_desc   = NULL;
+flash_cmds_t*	flashutl_cmd	= NULL;
+char*		flashutl_base	= NULL;
+
+
+unlock_cmd_t unlock_cmd_amd = {
+#ifdef MIPSEB
+/* addr: */	{ 0x0aa8,	0x0556},
+#else
+/* addr: */	{ 0x0aaa,	0x0554},
+#endif
+/* data: */	{ 0xaa,		0x55}
+};
+
+unlock_cmd_t unlock_cmd_sst = {
+#ifdef MIPSEB
+/* addr: */	{ 0xaaa8,	0x5556},
+#else
+/* addr: */	{ 0xaaaa,	0x5554},
+#endif
+/* data: */	{ 0xaa,		0x55}
+};
+
+#define AMD_CMD 0xaaa
+#define SST_CMD 0xaaaa
+
+/* intel unlock block cmds */
+#define INTEL_UNLOCK1   0x60
+#define INTEL_UNLOCK2   0xD0
+
+
+flash_cmds_t flash_cmds[] = {
+//        type  needu   preera  eraseb  erasech write   wbuf    clcsr   rdcsr   rdid    confrm  read 
+        { BSC,  0,      0x00,   0x20,   0x00,   0x40,   0x00,   0x50,   0x70,   0x90,   0xd0,   0xff },
+        { SCS,  0,      0x00,   0x20,   0x00,   0x40,   0xe8,   0x50,   0x70,   0x90,   0xd0,   0xff },
+        { AMD,  1,      0x80,   0x30,   0x10,   0xa0,   0x00,   0x00,   0x00,   0x90,   0x00,   0xf0 },
+	{ SST,  1,      0x80,   0x50,   0x10,   0xa0,   0x00,   0x00,   0x00,   0x90,   0x00,   0xf0 },
+        { 0 }
+};
+
+
+uint blk8x8k[] = { 0x00000000,
+		   0x00002000,
+		   0x00004000,
+		   0x00006000,
+		   0x00008000,
+		   0x0000a000,
+		   0x0000c000,
+		   0x0000e000,
+		   0x00010000
+};
+
+/* Funky AMD arrangement for 29xx800's */
+uint amd800[] = { 0x00000000,		/* 16KB */
+		  0x00004000,		/* 32KB */
+		  0x0000c000,		/* 8KB */
+		  0x0000e000,		/* 8KB */
+		  0x00010000,		/* 8KB */
+		  0x00012000,		/* 8KB */
+		  0x00014000,		/* 32KB */
+		  0x0001c000,		/* 16KB */
+		  0x00020000
+};
+
+/* AMD arrangement for 29xx160's */
+uint amd4112[] = { 0x00000000,		/* 32KB */
+		   0x00008000,		/* 8KB */
+		   0x0000a000,		/* 8KB */
+		   0x0000c000,		/* 16KB */
+		   0x00010000
+};
+uint amd2114[] = { 0x00000000,		/* 16KB */
+		   0x00004000,		/* 8KB */
+		   0x00006000,		/* 8KB */
+		   0x00008000,		/* 32KB */
+		   0x00010000
+};
+
+
+/*
+typedef struct _flash_cmds{
+        flash_type_t    type;
+        bool            need_unlock;
+        uint16          pre_erase;
+        uint16          erase_block;
+        uint16          erase_chip;
+        uint16          write_word;
+        uint16          write_buf;
+        uint16          clear_csr;
+        uint16          read_csr;
+        uint16          read_id;
+        uint16          confirm;
+        uint16          read_array;
+} flash_cmds_t;
+*/
+//typedef struct _flash_desc {
+//	uint16		mfgid;		/* Manufacturer Id */
+//	uint16		devid;		/* Device Id */
+//	uint		size;		/* Total size in bytes */
+//	uint		width;		/* Device width in bytes */
+//	flash_type_t	type;		/* Device type old, S, J */
+//	uint		bsize;		/* Block size */
+//	uint		nb;		/* Number of blocks */
+//	uint		ff;		/* First full block */
+//	uint		lf;		/* Last full block */
+//	uint		nsub;		/* Number of subblocks */
+//	uint		*subblocks;	/* Offsets for subblocks */
+//	char		*desc;		/* Description */
+//} flash_desc_t;
+
+flash_desc_t flashes[] = {
+	{ 0x00b0, 0x00d0, 0x0200000, 2,	SCS, 0x10000, 32,  0, 31,  0, NULL,    "Intel 28F160S3/5 1Mx16" },
+	{ 0x00b0, 0x00d4, 0x0400000, 2,	SCS, 0x10000, 64,  0, 63,  0, NULL,    "Intel 28F320S3/5 2Mx16" },
+	{ 0x0089, 0x8890, 0x0200000, 2,	BSC, 0x10000, 32,  0, 30,  8, blk8x8k, "Intel 28F160B3 1Mx16 TopB" },
+	{ 0x0089, 0x8891, 0x0200000, 2,	BSC, 0x10000, 32,  1, 31,  8, blk8x8k, "Intel 28F160B3 1Mx16 BotB" },
+	{ 0x0089, 0x8896, 0x0400000, 2,	BSC, 0x10000, 64,  0, 62,  8, blk8x8k, "Intel 28F320B3 2Mx16 TopB" },
+	{ 0x0089, 0x8897, 0x0400000, 2,	BSC, 0x10000, 64,  1, 63,  8, blk8x8k, "Intel 28F320B3 2Mx16 BotB" },
+	{ 0x0089, 0x8898, 0x0800000, 2,	BSC, 0x10000, 128, 0, 126, 8, blk8x8k, "Intel 28F640B3 4Mx16 TopB" },
+	{ 0x0089, 0x8899, 0x0800000, 2,	BSC, 0x10000, 128, 1, 127, 8, blk8x8k, "Intel 28F640B3 4Mx16 BotB" },
+	{ 0x0089, 0x88C2, 0x0200000, 2,	BSC, 0x10000, 32,  0, 30,  8, blk8x8k, "Intel 28F160C3 1Mx16 TopB" },
+	{ 0x0089, 0x88C3, 0x0200000, 2,	BSC, 0x10000, 32,  1, 31,  8, blk8x8k, "Intel 28F160C3 1Mx16 BotB" },
+	{ 0x0089, 0x88C4, 0x0400000, 2,	BSC, 0x10000, 64,  0, 62,  8, blk8x8k, "Intel 28F320C3 2Mx16 TopB" },
+	{ 0x0089, 0x88C5, 0x0400000, 2,	BSC, 0x10000, 64,  1, 63,  8, blk8x8k, "Intel 28F320C3 2Mx16 BotB" },
+	{ 0x0089, 0x88CC, 0x0800000, 2,	BSC, 0x10000, 128, 0, 126, 8, blk8x8k, "Intel 28F640C3 4Mx16 TopB" },
+	{ 0x0089, 0x88CD, 0x0800000, 2,	BSC, 0x10000, 128, 1, 127, 8, blk8x8k, "Intel 28F640C3 4Mx16 BotB" },
+	{ 0x0089, 0x0014, 0x0400000, 2,	SCS, 0x20000, 32,  0, 31,  0, NULL,    "Intel 28F320J5 2Mx16" },
+	{ 0x0089, 0x0015, 0x0800000, 2,	SCS, 0x20000, 64,  0, 63,  0, NULL,    "Intel 28F640J5 4Mx16" },
+	{ 0x0089, 0x0016, 0x0400000, 2,	SCS, 0x20000, 32,  0, 31,  0, NULL,    "Intel 28F320J3 2Mx16" },
+	{ 0x0089, 0x0017, 0x0800000, 2,	SCS, 0x20000, 64,  0, 63,  0, NULL,    "Intel 28F640J3 4Mx16" },
+	{ 0x0089, 0x0018, 0x1000000, 2,	SCS, 0x20000, 128, 0, 127, 0, NULL,    "Intel 28F128J3 8Mx16" },
+	{ 0x00b0, 0x00e3, 0x0400000, 2,	BSC, 0x10000, 64,  1, 63,  8, blk8x8k, "Sharp 28F320BJE 2Mx16 BotB" },
+	{ 0x0001, 0x224a, 0x0100000, 2,	AMD, 0x10000, 16,  0, 13,  8, amd800,  "AMD 29DL800BT 512Kx16 TopB" },
+	{ 0x0001, 0x22cb, 0x0100000, 2,	AMD, 0x10000, 16,  2, 15,  8, amd800,  "AMD 29DL800BB 512Kx16 BotB" },
+	{ 0x0001, 0x22c4, 0x0200000, 2,	AMD, 0x10000, 32,  0, 30,  4, amd2114, "AMD 29lv160DT 1Mx16 TopB" },
+	{ 0x0001, 0x2249, 0x0200000, 2,	AMD, 0x10000, 32,  1, 31,  4, amd4112, "AMD 29lv160DB 1Mx16 BotB" },
+	{ 0x0001, 0x22f6, 0x0400000, 2,	AMD, 0x10000, 64,  0, 62,  8, blk8x8k, "AMD 29lv320DT 2Mx16 TopB" },
+	{ 0x0001, 0x22f9, 0x0400000, 2,	AMD, 0x10000, 64,  1, 63,  8, blk8x8k, "AMD 29lv320DB 2Mx16 BotB" },
+	{ 0x0001, 0x227E, 0x0400000, 2,	AMD, 0x10000, 64,  0, 62,  8, blk8x8k, "AMD 29lv320MT 2Mx16 TopB" },
+	//{ 0x0001, 0x2201, 0x0400000, 2,	AMD, 0x10000, 64,  0, 62,  8, blk8x8k, "AMD 29lv320MT 2Mx16 TopB" },
+	{ 0x0001, 0x2200, 0x0400000, 2,	AMD, 0x10000, 64,  1, 63,  8, blk8x8k, "AMD 29lv320MB 2Mx16 BotB" },
+	{ 0x0020, 0x22CA, 0x0400000, 2,	AMD, 0x10000, 64,  0, 62,  4, amd4112, "ST 29w320DT 2Mx16 TopB" },
+	{ 0x0020, 0x22CB, 0x0400000, 2,	AMD, 0x10000, 64,  1, 63,  4, amd2114, "ST 29w320DB 2Mx16 BotB" },
+	{ 0x00C2, 0x00A7, 0x0400000, 2,	AMD, 0x10000, 64,  0, 62,  4, amd4112, "MX29LV320T 2Mx16 TopB" },
+	{ 0x00C2, 0x00A8, 0x0400000, 2,	AMD, 0x10000, 64,  1, 63,  4, amd2114, "MX29LV320B 2Mx16 BotB" },
+	{ 0x0004, 0x22F6, 0x0400000, 2,	AMD, 0x10000, 64,  0, 62,  4, amd4112, "MBM29LV320TE 2Mx16 TopB" },
+	{ 0x0004, 0x22F9, 0x0400000, 2,	AMD, 0x10000, 64,  1, 63,  4, amd2114, "MBM29LV320BE 2Mx16 BotB" },
+	{ 0x0098, 0x009A, 0x0400000, 2,	AMD, 0x10000, 64,  0, 62,  4, amd4112, "TC58FVT321 2Mx16 TopB" },
+	{ 0x0098, 0x009C, 0x0400000, 2,	AMD, 0x10000, 64,  1, 63,  4, amd2114, "TC58FVB321 2Mx16 BotB" }, 
+	{ 0x00C2, 0x22A7, 0x0400000, 2,	AMD, 0x10000, 64,  0, 62,  4, amd4112, "MX29LV320T 2Mx16 TopB" },
+	{ 0x00C2, 0x22A8, 0x0400000, 2,	AMD, 0x10000, 64,  1, 63,  4, amd2114, "MX29LV320B 2Mx16 BotB" },
+	{ 0x00BF, 0x2783, 0x0400000, 2,	SST, 0x10000, 64,  0, 63,  0, NULL,    "SST39VF320 2Mx16" },
+	{ 0,      0,      0,         0,	OLD, 0,       0,   0, 0,   0, NULL,    NULL },
+};
+
+/* Read the flash ID and set the globals */
+int
+flash_init(void* base_addr, char *flash_str)
+{
+	uint16 flash_vendid = 0;
+	uint16 flash_devid = 0;
+	uint16* flash = (uint16*)base_addr;
+	int idx;
+	
+	flashutl_base = (uint8*)base_addr;
+
+
+	/* 
+	 * Some flashes have different unlock addresses, try each it turn
+	 */
+	idx = sizeof(flash_cmds)/sizeof(flash_cmds_t) - 2;
+	flashutl_cmd = &flash_cmds[idx--];
+
+	while(flashutl_cmd->type) {
+
+		if (flashutl_cmd->read_id)
+			cmd(flashutl_cmd->read_id, CMD_ADDR);
+
+#ifdef MIPSEB
+		flash_vendid = *(flash + 1);
+		flash_devid = *flash;	
+#else
+		flash_vendid = *flash;
+		flash_devid = *(flash + 1);
+#endif
+
+		/* Funky AMD */
+		if ((flash_vendid == 1) && (flash_devid == 0x227e)) {
+			/* Get real devid */
+#ifdef MIPSEB
+			flash_devid = *(flash+0xe);	
+#else
+			flash_devid = *(flash+0xf);
+#endif
+		}
+
+		flashutl_desc = flashes;
+		while (flashutl_desc->mfgid != 0 &&
+			   !(flashutl_desc->mfgid == flash_vendid &&
+			 flashutl_desc->devid == flash_devid)) {
+			flashutl_desc++;
+		}
+		if (flashutl_desc->mfgid != 0)
+			break;
+
+		flashutl_cmd = &flash_cmds[idx--];
+	}
+
+	if (flashutl_desc->mfgid == 0) {
+		flashutl_desc = NULL;
+		flashutl_cmd = NULL;
+	} else {
+		flashutl_cmd = flash_cmds;
+		while (flashutl_cmd->type != 0 && flashutl_cmd->type != flashutl_desc->type)
+			flashutl_cmd++;
+		if (flashutl_cmd->type == 0)
+			flashutl_cmd = NULL;
+	}
+
+	if (flashutl_cmd != NULL) {
+		flash_reset();
+	}
+
+	if (flashutl_desc == NULL) {
+		if (flash_str)
+			sprintf(flash_str, "UNKNOWN 0x%x 0x%x", flash_vendid, flash_devid);
+		DPRINT(("Flash type UNKNOWN\n"));
+		return 1;
+	}
+	
+	if (flash_str)
+		strcpy(flash_str, flashutl_desc->desc);
+	DPRINT(("Flash type \"%s\"\n", flashutl_desc->desc));
+
+	return 0;
+}
+
+int
+flash_write(unsigned long off, uint16 *src, uint nbytes)
+{
+	uint16* dest;
+	uint16 st, data;
+	uint i, len;
+	
+	unsigned long a;
+
+	printk("Write %d bytes from %X to %X\n", off, off, off + nbytes);
+
+	a = (unsigned long)off;
+	if (a >= flashutl_desc->size)
+	           return 1;
+
+	a = block(a, BLOCK_BASE);
+
+	/* Ensure blocks are unlocked (for intel chips) */
+	if (flashutl_cmd->type == BSC) {
+	      scmd( INTEL_UNLOCK1, a);
+	      scmd( INTEL_UNLOCK2, a);
+	}
+	 
+	my_printk(("flash_write(%lx,%x)\n",off,nbytes));
+
+	ASSERT(flashutl_desc != NULL);
+
+	if (off >= flashutl_desc->size)
+		return 1;
+
+	dest = (uint16*)FLASH_ADDR(off);
+	st = 0;
+
+	while (nbytes) {
+	//	if ((flashutl_desc->type == SCS) &&
+	//	    flashutl_cmd->write_buf &&
+	//	    ((off & (WBUFSIZE - 1)) == 0)) {
+		if(0){	// The will fail in Intel J3 flash, 2004-2-17, honor
+			my_printk(("SCS\n"));
+			/* issue write command */
+			if (flashutl_cmd->write_buf)
+				cmd(flashutl_cmd->write_buf, off);
+			if ((st = flash_poll(off, DONE)))
+				continue;
+
+			len = MIN(nbytes, WBUFSIZE);
+			printk("flash_write(): len=%d\n", len);
+
+#ifndef MIPSEB
+			/* write (length - 1) */
+			cmd((len / 2) - 1, off);
+
+			/* write data */
+			for (i = 0; i < len; i += 2, dest++, src++){
+				printk("i=%d\n",i);
+				*dest = *src;
+			}
+#else
+			/* 
+			 * BCM4710 endianness is word consistent but
+			 * byte/short scrambled. This write buffer
+			 * mechanism appears to be sensitive to the
+			 * order of the addresses hence we need to
+			 * unscramble them. We may also need to pad
+			 * the source with two bytes of 0xffff in case
+			 * an odd number of shorts are presented.
+			 */
+
+			/* write (padded length - 1) */
+			cmd((ROUNDUP(len, 4) / 2) - 1, off);
+
+			/* write data (plus pad if necessary) */
+			for (i = 0; i < ROUNDUP(len, 4); i += 4, dest += 2, src += 2) {
+				*(dest + 1) = ((i + 2) < len) ? *(src + 1) : 0xffff;
+				*dest = *src;
+			}
+#endif
+
+			/* write confirm */
+			if (flashutl_cmd->confirm)
+				cmd(flashutl_cmd->confirm, off);
+
+			if ((st = flash_poll(off, DONE)))
+				break;
+		} else {
+			my_printk(("no SCS\n"));
+			/* issue write command */
+			if (flashutl_cmd->write_word)
+				cmd(flashutl_cmd->write_word, CMD_ADDR);
+
+			/* write data */
+			len = MIN(nbytes, 2);
+			data = *src++;
+			*dest++ = data;
+
+			/* poll for done */
+			if ((st = flash_poll(off, data)))
+				break;
+		}
+
+		nbytes -= len;
+		off += len;
+	}
+
+	flash_reset();
+
+	return st;
+}
+
+
+
+/* Writes a single command to the flash. */
+static void
+scmd(uint16 cmd, unsigned long off)
+{
+	my_printk(("scmd(%x,%lx)\n",cmd,off));
+	ASSERT(flashutl_base != NULL);
+	
+	/*  cmd |= cmd << 8; */
+
+	*(uint16*)(flashutl_base + off) = cmd;
+}
+
+/* Writes a command to flash, performing an unlock if needed. */
+static void
+cmd(uint16 cmd, unsigned long off)
+{
+	int i;
+	unlock_cmd_t *ul=NULL;
+	unsigned long cmd_off;
+
+	my_printk(("cmd(%x,%lx)\n",cmd,off));
+	my_printk(("\tflashutl_cmd->need_unlock=[%x]\n",flashutl_cmd->need_unlock));
+
+
+	ASSERT(flashutl_cmd != NULL);
+
+	switch (flashutl_cmd->type) {
+	case AMD:
+		ul = &unlock_cmd_amd;
+		cmd_off = AMD_CMD;
+		break;
+	case SST:
+		ul = &unlock_cmd_sst;
+		cmd_off = SST_CMD;
+		break;
+	default:
+		cmd_off = 0;
+		break;
+	}
+	
+	if (flashutl_cmd->need_unlock) {
+		for (i = 0; i < UNLOCK_CMD_WORDS; i++)
+			*(uint16*)(flashutl_base + ul->addr[i]) = ul->cmd[i];
+	}
+	
+	/* cmd |= cmd << 8; */
+
+	if (off == CMD_ADDR) 
+		off = cmd_off;
+
+#ifdef MIPSEB
+	off ^= 2;
+#endif
+	
+	*(uint16*)(flashutl_base + off) = cmd;
+
+}
+
+static void
+flash_reset(void) 
+{
+	my_printk(("flash_reset\n"));
+	my_printk(("\tflashutl_cmd->clear_csr=[%x] flashutl_cmd->read_array=[%x]\n",flashutl_cmd->clear_csr,flashutl_cmd->read_array));
+	ASSERT(flashutl_desc != NULL);
+
+	if (flashutl_cmd->clear_csr)
+		scmd(flashutl_cmd->clear_csr, 0);
+	if (flashutl_cmd->read_array)
+		scmd(flashutl_cmd->read_array, 0);
+}
+
+static int
+flash_poll(unsigned long off, uint16 data)
+{
+	volatile uint16* addr;
+	int cnt = FLASH_TRIES;
+	uint16 st;
+
+	my_printk(("flash_poll(%lx,%x)\n",off,data));
+	my_printk(("\tflashutl_desc->type=[%x]\n",flashutl_desc->type));
+
+	ASSERT(flashutl_desc != NULL);
+	
+	if (flashutl_desc->type == AMD || flashutl_desc->type == SST) {
+		/* AMD style poll checkes the address being written */
+		addr = (volatile uint16*)FLASH_ADDR(off);
+		while ((st = *addr) != data && cnt != 0)
+			cnt--;
+		if (cnt == 0) {
+			DPRINT(("flash_poll: timeout, read 0x%x, expected 0x%x\n", st, data));
+			return -1;
+		}
+	} else {
+		/* INTEL style poll is at second word of the block being written */
+		addr = (volatile uint16*)FLASH_ADDR(block(off, BLOCK_BASE));
+		addr++;
+		while (((st = *addr) & DONE) == 0 && cnt != 0)
+			cnt--;
+		if (cnt == 0) {
+			DPRINT(("flash_poll: timeout, error status = 0x%x\n", st));
+			return -1;
+		}
+	}
+	
+	return 0;
+}
+
+static unsigned long
+block(unsigned long addr, int which)
+{
+	unsigned long b, l, sb;
+	uint* sblocks;
+	int i;
+	my_printk(("block(%lx,%d)\n",addr,which));
+	my_printk(("\tflashutl_desc->bsize=[%x]\n",flashutl_desc->bsize));
+	
+	ASSERT(flashutl_desc != NULL);
+	ASSERT(addr < (unsigned long)flashutl_desc->size);
+	
+	b = addr / flashutl_desc->bsize;
+	my_printk(("\tb=[%lx]\n",b));
+	/* check for an address a full size block */
+	if (b >= flashutl_desc->ff && b <= flashutl_desc->lf) {
+		if (which == BLOCK_LIM) b++;
+		return (b * flashutl_desc->bsize);
+	}
+
+        /* search for the sub-block */
+	if (flashutl_desc->ff == 0) {
+		/* sub blocks are at the end of the flash */
+		sb = flashutl_desc->bsize * (flashutl_desc->lf + 1);
+	} else {
+		/* sub blocks are at the start of the flash */
+		sb = 0;
+	}
+
+	sblocks = flashutl_desc->subblocks;
+	for (i = 0; i < flashutl_desc->nsub; i++) {
+		b = sb + sblocks[i];
+		l = sb + sblocks[i+1];
+		if (addr >= b && addr < l) {
+			if (which == BLOCK_BASE)
+				return b;
+			else
+				return l;
+		}
+	}
+
+	ASSERT(1);
+	return 0;
+}
+
+/***************************************************************************/
+
+static int
+mac_init(void)
+{
+	unsigned char vars[RESERVE_MAC*PER_MAC_LEN];
+	unsigned long *src = (unsigned long *) (FLASH_BASE + MAC_START_ADDRESS);
+	unsigned long *dst = (unsigned long *) vars;
+	int i,j,tag=-1;
+	char *var;
+
+	printk("mac_init()\n");
+
+	for (i = 0; i < sizeof(vars); i += 4)
+		*dst++ = *src++;
+
+	for (i=0,j=0 ; i<sizeof(vars) ; i += PER_MAC_LEN) {
+		if(IS_NULL(vars,i,0xff)) {
+			tag = j;
+			break;
+		}
+		else {
+			var = &vars[i];
+		}	
+		j++;
+	}
+	printk("location = [%d]\n",tag);
+	
+	return tag;
+}
+
+static int
+eou_key_init(void)
+{
+	unsigned char vars[RESERVE_EOU_KEY*PER_EOU_KEY_LEN];
+	unsigned long *src = (unsigned long *) (FLASH_BASE + CFE_EOU_KEY_START_ADDRESS);
+	unsigned long *dst = (unsigned long *) vars;
+	int i,j,tag=-1;
+	char *var;
+
+	printk("eou_key_init()\n");
+
+	for (i = 0; i < sizeof(vars); i += 4)
+		*dst++ = *src++;
+
+	/* Check the first location, if it is fill all 0x00, maybe the boot cann't support to burn eou key */
+	if(IS_CNULL(vars, 0, 0x00, PER_EOU_KEY_LEN))
+		return -2;
+
+	for (i=0,j=0 ; i<sizeof(vars) ; i += PER_EOU_KEY_LEN) {
+		if(IS_CNULL(vars, i, 0xFF, PER_EOU_KEY_LEN)) {
+			tag = j;	// We already find a empty space to burn eou key
+			break;
+		}
+		else {
+			var = &vars[i];
+		}	
+		j++;
+	}
+	printk("location = [%d]\n",tag);
+	
+	return tag;
+}
+
+static int __init
+write_mac_module_init(void)
+{
+	char nvmsg[40];
+	int flash_not_exist;
+	int c;
+	unsigned long avail_addr = -1;
+
+	printk("flag=[%s] offset=[%lx] string=[%s]\n", flag, offset, string);
+	
+	if(!flag) {
+		printk("insmod writemac flag=[ get_flash | get_mac_index | set_mac | get_eou_key_index | set_eou_key ] [string=xxxxx]\n");
+		return 0;
+	}
+	
+        /* Barry adds for get flash_type 20030908 */
+        if(!strcmp(flag, "get_flash"))
+        {
+		flash_not_exist = flash_init((void*)FLASH_BASE, nvmsg);
+                printk("\nSet flash_type=%s\n",nvmsg);
+		if(strcmp(nvram_safe_get("flash_type"), nvmsg)){
+			nvram_set("flash_type", nvmsg);
+			nvram_commit();
+		}
+        }
+        else if(!strcmp(flag, "get_mac_index")) {
+		
+		if(!strncmp(nvram_safe_get("pmon_ver"), "PMON", 4))
+			MAC_START_ADDRESS = PMON_MAC_START_ADDRESS;
+		else
+			MAC_START_ADDRESS = CFE_MAC_START_ADDRESS;
+		
+		c = mac_init();
+
+		printk("Available mac index is %d\n", c);
+	}
+        else if(!strcmp(flag, "set_mac")) {
+	
+		printk("Write mac init\n");
+	
+		if(!strncmp(nvram_safe_get("pmon_ver"), "PMON", 4))
+			MAC_START_ADDRESS = PMON_MAC_START_ADDRESS;
+		else
+			MAC_START_ADDRESS = CFE_MAC_START_ADDRESS;
+				
+		c = mac_init();
+		if(c == -1){
+			printk("The mac space is full! Please update boot.bin\n");
+			return 0;
+		}
+		else{
+			avail_addr = (unsigned long)(c * PER_MAC_LEN  + MAC_START_ADDRESS);
+			printk("The mac %d is available, address is %lX!\n", c, avail_addr);
+			flash_not_exist = flash_init((void*)FLASH_BASE, nvmsg);
+
+			if(offset && string)
+				flash_write(offset, string, strlen(string));
+			else if(string)
+				flash_write(avail_addr, string, strlen(string));
+		}
+		
+		printk("Write mac done\n");
+        }
+        else if(!strcmp(flag, "get_eou_key_index")) {
+		char buf[10];
+		
+		c = eou_key_init();
+		
+		snprintf(buf, sizeof(buf), "%d", c);
+		
+		if(strcmp(nvram_safe_get("eou_key_index"), buf)){
+			nvram_set("eou_key_index", buf);
+		}
+		
+		printk("Available eou key index is %d\n", c);
+	}
+        else if(!strcmp(flag, "set_eou_key")) {
+		
+		printk("Write eou key init\n");
+		
+		c = eou_key_init();
+		if(c == -1){
+			printk("The eou key space is full! Please update boot.bin\n");
+			return 0;
+		}
+		else if(c == -2){
+			printk("The boot cann't support to burn eou key!\n");
+			return 0;
+		}
+		else{
+			avail_addr = (unsigned long)(c * PER_EOU_KEY_LEN + CFE_EOU_KEY_START_ADDRESS);
+			printk("The key %d is available, address is %lX!\n", c, avail_addr);
+			flash_not_exist = flash_init((void*)FLASH_BASE, nvmsg);
+			
+			if(offset && string)
+				flash_write(offset, string, strlen(string));
+			else if(string)
+				flash_write(avail_addr, string, strlen(string));
+		}
+		
+		printk("Write eou key done\n");
+        }
+	
+	return 0;
+}
+
+static void __exit
+write_mac_module_exit(void)
+{
+	printk("exit\n");
+}
+
+module_init(write_mac_module_init);
+module_exit(write_mac_module_exit);
diff -ruN linux-2.4.20-WRT/drivers/net/mac/Makefile linux-2.4.20-WRT54GSV4/drivers/net/mac/Makefile
--- linux-2.4.20-WRT/drivers/net/mac/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.20-WRT54GSV4/drivers/net/mac/Makefile	2003-07-09 07:10:26.000000000 -0700
@@ -0,0 +1,27 @@
+#  Copyright 2001, Cybertan Corporation
+#  All Rights Reserved.
+#  
+#  This is UNPUBLISHED PROPRIETARY SOURCE CODE of Cybertan Corporation;
+#  the contents of this file may not be disclosed to third parties, copied or
+#  duplicated in any form, in whole or in part, without the prior written
+#  permission of Cybertan Corporation.
+#
+#
+# $Id: Makefile,v 1.1 2003/07/09 14:10:26 honor Exp $
+#
+
+O_TARGET	:= writemac.o
+
+MAC_OBJS	:= mac.o
+
+export-objs	:= 
+obj-y		:= $(MAC_OBJS)
+obj-m		:= $(O_TARGET)
+
+SRCBASE		:= $(TOPDIR)/../..
+EXTRA_CFLAGS	+= -I$(SRCBASE)/include
+
+vpath %.c $(SRCBASE)/shared
+
+include $(TOPDIR)/Rules.make
+
