first ar531x support for 2.4, thx Mile Albon, some addons from me for mips big endian...
authorWaldemar Brodkorb <mail@waldemar-brodkorb.de>
Sun, 25 Dec 2005 20:04:16 +0000 (20:04 +0000)
committerWaldemar Brodkorb <mail@waldemar-brodkorb.de>
Sun, 25 Dec 2005 20:04:16 +0000 (20:04 +0000)
SVN-Revision: 2781

13 files changed:
openwrt/Config.in
openwrt/Config.in.devel
openwrt/target/linux/Config.in
openwrt/target/linux/Makefile
openwrt/target/linux/linux-2.4/config/ar531x [new file with mode: 0644]
openwrt/target/linux/linux-2.4/patches/ar531x/000-atheros-support.patch [new file with mode: 0644]
openwrt/target/linux/linux-2.4/patches/ar531x/001-ar531x-ethernet.patch [new file with mode: 0644]
openwrt/target/linux/package/diag/Config.in
openwrt/target/linux/package/madwifi/Config.in
openwrt/target/linux/package/switch/Config.in
openwrt/target/linux/rules.mk
openwrt/toolchain/kernel-headers/Makefile
openwrt/toolchain/uClibc/files/config.mipseb [new file with mode: 0644]

index 3f5cb29..c93b1f1 100644 (file)
@@ -11,12 +11,11 @@ config BR2_HAVE_DOT_CONFIG
        default y
 
 config BR2_mipsel
+       bool
        default y
 
 choice
-       default BR2_mipsel
-       help
-         Stuff
+       prompt "Target Architecture" if CONFIG_DEVEL
 
 config BR2_arm
        bool "arm"
@@ -33,8 +32,8 @@ config BR2_i386
 config BR2_m68k
        bool "m68k"
 
-config BR2_mips
-       bool "mips"
+config BR2_mipseb
+       bool "mipseb"
 
 config BR2_mipsel
        bool "mipsel"
@@ -66,7 +65,7 @@ config BR2_ARCH
        default "cris"    if BR2_cris
        default "i386"    if BR2_i386
        default "m68k"    if BR2_m68k
-       default "mips"    if BR2_mips
+       default "mipseb"  if BR2_mipseb
        default "mipsel"  if BR2_mipsel || !CONFIG_DEVEL
        default "powerpc" if BR2_powerpc
        default "sh3"     if BR2_sh3
index 38e79b9..ad42316 100644 (file)
@@ -35,8 +35,8 @@ config BR2_i386
 config BR2_m68k
        bool "m68k"
 
-config BR2_mips
-       bool "mips"
+config BR2_mipseb
+       bool "mipseb"
 
 config BR2_mipsel
        bool "mipsel"
@@ -68,7 +68,7 @@ config BR2_ARCH
        default "cris"    if BR2_cris
        default "i386"    if BR2_i386
        default "m68k"    if BR2_m68k
-       default "mips"    if BR2_mips
+       default "mipseb"  if BR2_mipseb
        default "mipsel"  if BR2_mipsel
        default "powerpc" if BR2_powerpc
        default "sh3"     if BR2_sh3
index 9442c9f..9f3b525 100644 (file)
@@ -48,6 +48,14 @@ config BR2_LINUX_2_6_X86
          Build firmware images for x86 based boards
          (e.g. Soekris net4521 and net4801, PC Engines WRAP...)
 
+config BR2_LINUX_2_4_AR531X
+       bool "Support for Atheros ar531x based APs"
+       default n
+       depends BR2_mipseb
+       help
+         Build firmware images for Atheros ar531x based boards
+         (e.g. Netgear WGT624, Linksys WRT55AG)
+
 endchoice
 
 
index 02ed636..5dfe12a 100644 (file)
@@ -88,3 +88,4 @@ $(eval $(call kernel_template,2.4,ar7,2_4_AR7))
 $(eval $(call kernel_template,2.4,x86,2_4_X86))
 $(eval $(call kernel_template,2.6,brcm,2_6_BRCM))
 $(eval $(call kernel_template,2.6,x86,2_6_X86))
+$(eval $(call kernel_template,2.4,ar531x,2_4_AR531X))
diff --git a/openwrt/target/linux/linux-2.4/config/ar531x b/openwrt/target/linux/linux-2.4/config/ar531x
new file mode 100644 (file)
index 0000000..3db1f57
--- /dev/null
@@ -0,0 +1,1098 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_FICMMP is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_DB1200 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+CONFIG_AR531X=y
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_PB1200 is not set
+# CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_COGENT_CSB250 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TANBAC_TB0226 is not set
+# CONFIG_TANBAC_TB0229 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_CPU_VR41XX=y
+CONFIG_IRQ_CPU=y
+CONFIG_SERIAL=y
+CONFIG_NEW_IRQ=y
+CONFIG_NEW_TIME_C=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_EARLY_PRINTK_HACK=y
+# CONFIG_SCSI is not set
+
+#
+# Board selection
+#
+# CONFIG_APUNKNOWN is not set
+CONFIG_AP30=y
+# CONFIG_AP31 is not set
+# CONFIG_AP33 is not set
+# CONFIG_AP38 is not set
+# CONFIG_AP43 is not set
+# CONFIG_AP48 is not set
+CONFIG_MTD_PHYSMAP_BUSWIDTH=2
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+CONFIG_CPU_VR41XX=y
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+# CONFIG_CPU_ADVANCED is not set
+# CONFIG_CPU_HAS_LLSC is not set
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
+# CONFIG_BINFMT_IRIX is not set
+CONFIG_NET=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_NEW is not set
+CONFIG_PCI_AUTO=y
+# CONFIG_ISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_ELF_AOUT is not set
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_MIPS32_O32 is not set
+# CONFIG_MIPS32_N32 is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_B1 is not set
+CONFIG_MTD_CFI_B2=y
+# CONFIG_MTD_CFI_B4 is not set
+# CONFIG_MTD_CFI_B8 is not set
+CONFIG_MTD_CFI_I1=y
+# CONFIG_MTD_CFI_I2 is not set
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_SSTSTD=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+CONFIG_MTD_OBSOLETE_CHIPS=y
+CONFIG_MTD_AMDSTD=y
+# CONFIG_MTD_SHARP is not set
+CONFIG_MTD_JEDEC=y
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0xbe000000
+CONFIG_MTD_PHYSMAP_LEN=0x800000
+CONFIG_MTD_PHYSMAP_BUSWIDTH=1
+# CONFIG_MTD_PB1000 is not set
+# CONFIG_MTD_PB1500 is not set
+# CONFIG_MTD_PB1100 is not set
+# CONFIG_MTD_BOSPORUS is not set
+# CONFIG_MTD_XXS1500 is not set
+# CONFIG_MTD_MTX1 is not set
+# CONFIG_MTD_DB1X00 is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
+# CONFIG_MTD_MIRAGE is not set
+# CONFIG_MTD_CSTM_MIPS_IXX is not set
+# CONFIG_MTD_OCELOT is not set
+# CONFIG_MTD_LASAT is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+# CONFIG_PARPORT_PC is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_IP22 is not set
+# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_1284 is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
+CONFIG_RING=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_NAT=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_TOS=y
+# CONFIG_IP_ROUTE_VERBOSE is not set
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_NET_IPGRE_BROADCAST is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_FTP=y
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_IRC=y
+CONFIG_IP_NF_CT_ACCT=m
+CONFIG_IP_NF_MATCH_CONNBYTES=m
+CONFIG_IP_NF_CT_PROTO_GRE=m
+CONFIG_IP_NF_PPTP=m
+CONFIG_IP_NF_SIP=m
+CONFIG_IP_NF_H323=m
+CONFIG_IP_NF_MMS=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_QUOTA=m
+CONFIG_IP_NF_SET=m
+CONFIG_IP_NF_SET_MAX=256
+CONFIG_IP_NF_SET_HASHSIZE=1024
+CONFIG_IP_NF_MATCH_SET=m
+CONFIG_IP_NF_TARGET_SET=m
+CONFIG_IP_NF_SET_IPMAP=m
+CONFIG_IP_NF_SET_PORTMAP=m
+CONFIG_IP_NF_SET_MACIPMAP=m
+CONFIG_IP_NF_SET_IPHASH=m
+CONFIG_IP_NF_SET_NETHASH=m
+CONFIG_IP_NF_SET_IPTREE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=y
+CONFIG_IP_NF_MATCH_MULTIPORT=y
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_CONDITION=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_IPP2P=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=y
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_UNCLEAN=m
+CONFIG_IP_NF_MATCH_STRING=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_LAYER7=m
+# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set
+CONFIG_IP_NF_MATCH_LAYER7_MAXDATALEN=2048
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_MIRROR=m
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_NAT_PPTP=m
+CONFIG_IP_NF_NAT_PROTO_GRE=m
+CONFIG_IP_NF_NAT_SIP=m
+CONFIG_IP_NF_NAT_H323=m
+CONFIG_IP_NF_NAT_MMS=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=y
+CONFIG_IP_NF_NAT_FTP=y
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=y
+CONFIG_IP_NF_TARGET_IMQ=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=y
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+#   IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_IPV6=m
+
+#
+#   IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_CONDITION=m
+CONFIG_IP6_NF_MATCH_MAC=m
+# CONFIG_IP6_NF_MATCH_RT is not set
+# CONFIG_IP6_NF_MATCH_OPTS is not set
+# CONFIG_IP6_NF_MATCH_FRAG is not set
+# CONFIG_IP6_NF_MATCH_HL is not set
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
+# CONFIG_IP6_NF_MATCH_AHESP is not set
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_TARGET_IMQ=m
+# CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+CONFIG_VLAN_8021Q=y
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+CONFIG_BRIDGE=y
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_CSZ=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+# CONFIG_NET_SCH_NETEM is not set
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_IPSEC_NAT_TRAVERSAL=y
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=m
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=m
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=m
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_IDEDISK_STROKE=y
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
+# CONFIG_BLK_DEV_ATARAID_SII is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_BOOT is not set
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_IMQ=m
+CONFIG_TUN=m
+CONFIG_NET_RANDOM=y
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_VENETDEV is not set
+CONFIG_MARVELL_ENET_PHY=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE_MPPC=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_HERMES is not set
+# CONFIG_PRISM54 is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+CONFIG_SHAPER=m
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+CONFIG_HAMRADIO=y
+CONFIG_AX25=m
+# CONFIG_AX25_DAMA_SLAVE is not set
+# CONFIG_NETROM is not set
+# CONFIG_ROSE is not set
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+# CONFIG_6PACK is not set
+# CONFIG_BPQETHER is not set
+# CONFIG_SCC_DELAY is not set
+# CONFIG_SCC_TRXECHO is not set
+# CONFIG_BAYCOM_SER_FDX is not set
+# CONFIG_BAYCOM_SER_HDX is not set
+# CONFIG_BAYCOM_PAR is not set
+# CONFIG_BAYCOM_EPP is not set
+# CONFIG_SOUNDMODEM is not set
+# CONFIG_YAM is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_VR41XX_KIU is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=128
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+CONFIG_PPDEV=m
+# CONFIG_TIPAR is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM1535_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_SCx200_WDT is not set
+CONFIG_SOFT_WATCHDOG=y
+# CONFIG_W83877F_WDT is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_SCx200 is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+CONFIG_HFSPLUS_FS=m
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=m
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=m
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_JFFS2_BBC_ARMLIB is not set
+# CONFIG_JFFS2_BBC_LZO is not set
+CONFIG_JFFS2_BBC_LZARI=y
+# CONFIG_JFFS2_BBC_LZHD is not set
+# CONFIG_JFFS2_BBC_LZSS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=m
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=m
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_POSIX=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+CONFIG_VIDEO_PROC_FS=y
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_VIDEO_BWQCAM is not set
+# CONFIG_VIDEO_CQCAM is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZORAN_BUZ is not set
+# CONFIG_VIDEO_ZORAN_DC10 is not set
+# CONFIG_VIDEO_ZORAN_LML33 is not set
+# CONFIG_VIDEO_ZR36120 is not set
+# CONFIG_VIDEO_MEYE is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_RADIO_MIROPCM20 is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+# CONFIG_SOUND_AD1980 is not set
+# CONFIG_SOUND_WM97XX is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# Bluetooth support
+#
+CONFIG_BLUEZ=m
+CONFIG_BLUEZ_L2CAP=m
+CONFIG_BLUEZ_SCO=m
+CONFIG_BLUEZ_RFCOMM=m
+CONFIG_BLUEZ_RFCOMM_TTY=y
+CONFIG_BLUEZ_BNEP=m
+CONFIG_BLUEZ_BNEP_MC_FILTER=y
+CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BLUEZ_HCIUSB is not set
+CONFIG_BLUEZ_HCIUART=m
+CONFIG_BLUEZ_HCIUART_H4=y
+CONFIG_BLUEZ_HCIUART_BCSP=y
+CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
+# CONFIG_BLUEZ_HCIBFUSB is not set
+# CONFIG_BLUEZ_HCIDTL1 is not set
+# CONFIG_BLUEZ_HCIBT3C is not set
+# CONFIG_BLUEZ_HCIBLUECARD is not set
+# CONFIG_BLUEZ_HCIBTUART is not set
+# CONFIG_BLUEZ_HCIVHCI is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_KGDB is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG_INFO is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_MIPS_UNCACHED is not set
+CONFIG_LOG_BUF_SHIFT=0
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/openwrt/target/linux/linux-2.4/patches/ar531x/000-atheros-support.patch b/openwrt/target/linux/linux-2.4/patches/ar531x/000-atheros-support.patch
new file mode 100644 (file)
index 0000000..1ec012f
--- /dev/null
@@ -0,0 +1,2642 @@
+diff -urN linux-2.4.32/arch/mips/ar531x/ar531xdbg_io.c linux-2.4.32.new/arch/mips/ar531x/ar531xdbg_io.c\r
+--- linux-2.4.32/arch/mips/ar531x/ar531xdbg_io.c       1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/ar531xdbg_io.c   2005-12-24 20:29:42.102311328 +0000\r
+@@ -0,0 +1,217 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright MontaVista Software Inc\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++/*\r
++ * Basic support for polled character input/output\r
++ * using the AR531X's serial port.\r
++ */\r
++\r
++#include <linux/config.h>\r
++#include <linux/init.h>\r
++#include <linux/delay.h>\r
++#include <linux/irq.h>\r
++#include <linux/interrupt.h>\r
++#include <linux/serial.h>\r
++#include <linux/types.h>\r
++#include <linux/string.h>\r
++\r
++#include <asm/reboot.h>\r
++#include <asm/io.h>\r
++#include <asm/time.h>\r
++#include <asm/pgtable.h>\r
++#include <asm/processor.h>\r
++#include <asm/reboot.h>\r
++#include <asm/system.h>\r
++#include <asm/serial.h>\r
++#include <asm/gdb-stub.h>\r
++\r
++#include "ar531xlnx.h"\r
++\r
++#if CONFIG_EARLY_PRINTK_HACK || CONFIG_KGDB\r
++/* base addr of uart and clock timing */\r
++#define         BASE                    0xbc000003\r
++\r
++/* distance in bytes between two serial registers */\r
++#define         REG_OFFSET              4\r
++\r
++/*\r
++ * 0 - we need to do serial init\r
++ * 1 - skip serial init\r
++ */\r
++static int serialPortInitialized = 0;\r
++\r
++/*\r
++ *  * the default baud rate *if* we do serial init\r
++ *   */\r
++#define         BAUD_DEFAULT            UART16550_BAUD_9600\r
++\r
++/* === END OF CONFIG === */\r
++\r
++#define         UART16550_BAUD_2400             2400\r
++#define         UART16550_BAUD_4800             4800\r
++#define         UART16550_BAUD_9600             9600\r
++#define         UART16550_BAUD_19200            19200\r
++#define         UART16550_BAUD_38400            38400\r
++#define         UART16550_BAUD_57600            57600\r
++#define         UART16550_BAUD_115200           115200\r
++\r
++#define         UART16550_PARITY_NONE           0\r
++#define         UART16550_PARITY_ODD            0x08\r
++#define         UART16550_PARITY_EVEN           0x18\r
++#define         UART16550_PARITY_MARK           0x28\r
++#define         UART16550_PARITY_SPACE          0x38\r
++\r
++#define         UART16550_DATA_5BIT             0x0\r
++#define         UART16550_DATA_6BIT             0x1\r
++#define         UART16550_DATA_7BIT             0x2\r
++#define         UART16550_DATA_8BIT             0x3\r
++\r
++#define         UART16550_STOP_1BIT             0x0\r
++#define         UART16550_STOP_2BIT             0x4\r
++\r
++/* register offset */\r
++#define         OFS_RCV_BUFFER          (0*REG_OFFSET)\r
++#define         OFS_TRANS_HOLD          (0*REG_OFFSET)\r
++#define         OFS_SEND_BUFFER         (0*REG_OFFSET)\r
++#define         OFS_INTR_ENABLE         (1*REG_OFFSET)\r
++#define         OFS_INTR_ID             (2*REG_OFFSET)\r
++#define         OFS_DATA_FORMAT         (3*REG_OFFSET)\r
++#define         OFS_LINE_CONTROL        (3*REG_OFFSET)\r
++#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)\r
++#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)\r
++#define         OFS_LINE_STATUS         (5*REG_OFFSET)\r
++#define         OFS_MODEM_STATUS        (6*REG_OFFSET)\r
++#define         OFS_RS232_INPUT         (6*REG_OFFSET)\r
++#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)\r
++\r
++#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)\r
++#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)\r
++\r
++\r
++/* memory-mapped read/write of the port */\r
++#define         UART16550_READ(y)    (*((volatile u8*)(BASE + y)))\r
++#define         UART16550_WRITE(y, z)  ((*((volatile u8*)(BASE + y))) = z)\r
++\r
++void\r
++debugPortInit(u32 baud, u8 data, u8 parity, u8 stop)\r
++{\r
++      /* Pull UART out of reset */\r
++      sysRegWrite(AR531X_RESET,\r
++              sysRegRead(AR531X_RESET) & ~(AR531X_RESET_UART0));\r
++\r
++      /* disable interrupts */\r
++        UART16550_WRITE(OFS_LINE_CONTROL, 0x0);\r
++      UART16550_WRITE(OFS_INTR_ENABLE, 0);\r
++\r
++      /* set up buad rate */\r
++      { \r
++              u32 divisor;\r
++              u32 uart_clock_rate = ar531x_cpu_frequency() / 4;\r
++              u32 base_baud = uart_clock_rate / 16;\r
++       \r
++              /* set DIAB bit */\r
++              UART16550_WRITE(OFS_LINE_CONTROL, 0x80);\r
++        \r
++              /* set divisor */\r
++              divisor = base_baud / baud;\r
++              UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);\r
++              UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00)>>8);\r
++\r
++              /* clear DIAB bit */\r
++              UART16550_WRITE(OFS_LINE_CONTROL, 0x0);\r
++      }\r
++\r
++      /* set data format */\r
++      UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);\r
++}\r
++\r
++u8\r
++getDebugChar(void)\r
++{\r
++        if (!serialPortInitialized) {\r
++                serialPortInitialized = 1;\r
++                debugPortInit(BAUD_DEFAULT,\r
++                              UART16550_DATA_8BIT,\r
++                              UART16550_PARITY_NONE, UART16550_STOP_1BIT);\r
++        }\r
++\r
++      while((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);\r
++      return UART16550_READ(OFS_RCV_BUFFER);\r
++}\r
++\r
++#if CONFIG_KGDB\r
++/*\r
++ * Peek at the most recently received character.\r
++ * Don't wait for a new character to be received.\r
++ */\r
++u8\r
++peekDebugChar(void)\r
++{\r
++      return UART16550_READ(OFS_RCV_BUFFER);\r
++}\r
++\r
++static int kgdbInitialized = 0;\r
++\r
++void\r
++kgdbInit(void)\r
++{\r
++    sysRegWrite(AR531X_WD_CTRL, AR531X_WD_CTRL_IGNORE_EXPIRATION);\r
++\r
++    if (!kgdbInitialized) {\r
++        printk("Setting debug traps - please connect the remote debugger.\n");\r
++        set_debug_traps();\r
++        kgdbInitialized = 1;\r
++    }\r
++    breakpoint();\r
++}\r
++\r
++int\r
++kgdbEnabled(void)\r
++{\r
++    return kgdbInitialized;\r
++}\r
++\r
++#define DEBUG_CHAR '\001';\r
++\r
++int\r
++kgdbInterrupt(void)\r
++{\r
++    if (!kgdbInitialized) {\r
++        return 0;\r
++    }\r
++\r
++    /* \r
++     * Try to avoid swallowing too much input: Only consume\r
++     * a character if nothing new has arrived.  Yes, there's\r
++     * still a small hole here, and we may lose an input\r
++     * character now and then.\r
++     */\r
++    if (UART16550_READ(OFS_LINE_STATUS) & 1) {\r
++        return 0;\r
++    } else {\r
++        return UART16550_READ(OFS_RCV_BUFFER) == DEBUG_CHAR;\r
++    }\r
++}\r
++#endif\r
++\r
++\r
++void\r
++putDebugChar(char byte)\r
++{\r
++        if (!serialPortInitialized) {\r
++                serialPortInitialized = 1;\r
++                debugPortInit(BAUD_DEFAULT,\r
++                              UART16550_DATA_8BIT,\r
++                              UART16550_PARITY_NONE, UART16550_STOP_1BIT);\r
++        }\r
++\r
++      while ((UART16550_READ(OFS_LINE_STATUS) &0x20) == 0);\r
++      UART16550_WRITE(OFS_SEND_BUFFER, byte);\r
++ }\r
++#endif /* CONFIG_EARLY_PRINTK_HACK || CONFIG_KGDB */\r
+diff -urN linux-2.4.32/arch/mips/ar531x/ar531xgpio.c linux-2.4.32.new/arch/mips/ar531x/ar531xgpio.c\r
+--- linux-2.4.32/arch/mips/ar531x/ar531xgpio.c 1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/ar531xgpio.c     2005-12-24 20:29:42.102311328 +0000\r
+@@ -0,0 +1,141 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++/*\r
++ * Support for GPIO -- General Purpose Input/Output Pins\r
++ */\r
++\r
++#include <linux/config.h>\r
++#include <linux/kernel.h>\r
++#include <linux/signal.h>\r
++#include <linux/interrupt.h>\r
++#include <linux/irq.h>\r
++\r
++#include "ar531xlnx.h"\r
++\r
++/* GPIO Interrupt Support */\r
++\r
++/* Turn on the specified AR531X_GPIO_IRQ interrupt */\r
++static unsigned int\r
++ar531x_gpio_intr_startup(unsigned int irq)\r
++{\r
++      ar531x_gpio_intr_enable(irq);\r
++      return 0;\r
++}\r
++\r
++/* Turn off the specified AR531X_GPIO_IRQ interrupt */\r
++static void\r
++ar531x_gpio_intr_shutdown(unsigned int irq)\r
++{\r
++      ar531x_gpio_intr_disable(irq);\r
++}\r
++\r
++u32 gpioIntMask = 0;\r
++\r
++/* Enable the specified AR531X_GPIO_IRQ interrupt */\r
++void\r
++ar531x_gpio_intr_enable(unsigned int irq)\r
++{\r
++    u32 reg;\r
++    int gpio;\r
++\r
++    gpio = irq - AR531X_GPIO_IRQ_BASE;\r
++    gpioIntMask |= gpio;\r
++\r
++    reg = sysRegRead(AR531X_GPIO_CR);\r
++    reg &= ~(GPIO_CR_M(gpio) | GPIO_CR_UART(gpio) | GPIO_CR_INT(gpio));\r
++    reg |= GPIO_CR_I(gpio);\r
++    reg |= GPIO_CR_INT(gpio);\r
++\r
++    sysRegWrite(AR531X_GPIO_CR, reg);\r
++    (void)sysRegRead(AR531X_GPIO_CR); /* flush to hardware */\r
++}\r
++\r
++/* Disable the specified AR531X_GPIO_IRQ interrupt */\r
++void\r
++ar531x_gpio_intr_disable(unsigned int irq)\r
++{\r
++    u32 reg;\r
++    int gpio;\r
++\r
++    gpio = irq - AR531X_GPIO_IRQ_BASE;\r
++\r
++    reg = sysRegRead(AR531X_GPIO_CR);\r
++    reg &= ~(GPIO_CR_M(gpio) | GPIO_CR_UART(gpio) | GPIO_CR_INT(gpio));\r
++    reg |= GPIO_CR_I(gpio);\r
++    /* No GPIO_CR_INT bit */\r
++\r
++    sysRegWrite(AR531X_GPIO_CR, reg);\r
++    (void)sysRegRead(AR531X_GPIO_CR); /* flush to hardware */\r
++\r
++    gpioIntMask &= ~gpio;\r
++}\r
++\r
++static void\r
++ar531x_gpio_intr_ack(unsigned int irq)\r
++{\r
++      ar531x_gpio_intr_disable(irq);\r
++}\r
++\r
++static void\r
++ar531x_gpio_intr_end(unsigned int irq)\r
++{\r
++      if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))\r
++              ar531x_gpio_intr_enable(irq);\r
++}\r
++\r
++static void\r
++ar531x_gpio_intr_set_affinity(unsigned int irq, unsigned long mask)\r
++{\r
++      /* Only 1 CPU; ignore affinity request */\r
++}\r
++\r
++int ar531x_gpio_irq_base;\r
++\r
++struct hw_interrupt_type ar531x_gpio_intr_controller = {\r
++      "AR531X GPIO",\r
++      ar531x_gpio_intr_startup,\r
++      ar531x_gpio_intr_shutdown,\r
++      ar531x_gpio_intr_enable,\r
++      ar531x_gpio_intr_disable,\r
++      ar531x_gpio_intr_ack,\r
++      ar531x_gpio_intr_end,\r
++      ar531x_gpio_intr_set_affinity,\r
++};\r
++\r
++void\r
++ar531x_gpio_intr_init(int irq_base)\r
++{\r
++      int i;\r
++\r
++      for (i = irq_base; i < irq_base + AR531X_GPIO_IRQ_COUNT; i++) {\r
++              irq_desc[i].status = IRQ_DISABLED;\r
++              irq_desc[i].action = NULL;\r
++              irq_desc[i].depth = 1;\r
++              irq_desc[i].handler = &ar531x_gpio_intr_controller;\r
++      }\r
++\r
++      ar531x_gpio_irq_base = irq_base;\r
++}\r
++\r
++/* ARGSUSED */\r
++void\r
++spurious_gpio_handler(int cpl, void *dev_id, struct pt_regs *regs)\r
++{\r
++    u32 gpioDataIn;\r
++\r
++    gpioDataIn = sysRegRead(AR531X_GPIO_DI) & gpioIntMask;\r
++\r
++    printk("spurious_gpio_handler: 0x%x di=0x%8.8x gpioIntMask=0x%8.8x\n",\r
++           cpl, gpioDataIn, gpioIntMask);\r
++}\r
++\r
++struct irqaction spurious_gpio =\r
++      {spurious_gpio_handler, SA_INTERRUPT, 0, "spurious_gpio",\r
++            NULL, NULL};\r
++\r
+diff -urN linux-2.4.32/arch/mips/ar531x/ar531x.h linux-2.4.32.new/arch/mips/ar531x/ar531x.h\r
+--- linux-2.4.32/arch/mips/ar531x/ar531x.h     1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/ar531x.h 2005-12-24 20:29:42.102311328 +0000\r
+@@ -0,0 +1,280 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++#ifndef AR531X_H\r
++#define AR531X_H 1\r
++\r
++#include <asm/addrspace.h>\r
++\r
++/* Address Map */\r
++#define AR531X_WLAN0            0x18000000\r
++#define AR531X_WLAN1            0x18500000\r
++#define AR531X_ENET0            0x18100000\r
++#define AR531X_ENET1            0x18200000\r
++#define AR531X_SDRAMCTL         0x18300000\r
++#define AR531X_FLASHCTL         0x18400000\r
++#define AR531X_APBBASE                0x1c000000\r
++#define AR531X_FLASH            0x1e000000\r
++\r
++/*\r
++ * AR531X_NUM_ENET_MAC defines the number of ethernet MACs that\r
++ * should be considered available.  The AR5312 supports 2 enet MACS,\r
++ * even though many reference boards only actually use 1 of them\r
++ * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch.\r
++ * The AR2312 supports 1 enet MAC.\r
++ */\r
++#define AR531X_NUM_ENET_MAC             2\r
++\r
++/*\r
++ * Need these defines to determine true number of ethernet MACs\r
++ */\r
++#define AR5212_AR5312_REV2      0x0052          /* AR5312 WMAC (AP31) */\r
++#define AR5212_AR5312_REV7      0x0057          /* AR5312 WMAC (AP30-040) */\r
++#define AR5212_AR2313_REV8      0x0058          /* AR2313 WMAC (AP43-030) */\r
++#define AR531X_RADIO_MASK_OFF  0xc8\r
++#define AR531X_RADIO0_MASK     0x0003\r
++#define AR531X_RADIO1_MASK     0x000c\r
++#define AR531X_RADIO1_S        2 \r
++\r
++/*\r
++ * AR531X_NUM_WMAC defines the number of Wireless MACs that\\r
++ * should be considered available.\r
++ */\r
++#define AR531X_NUM_WMAC                 2\r
++\r
++/* Reset/Timer Block Address Map */\r
++#define AR531X_RESETTMR               (AR531X_APBBASE  + 0x3000)\r
++#define AR531X_TIMER          (AR531X_RESETTMR + 0x0000) /* countdown timer */\r
++#define AR531X_WD_CTRL          (AR531X_RESETTMR + 0x0008) /* watchdog cntrl */\r
++#define AR531X_WD_TIMER         (AR531X_RESETTMR + 0x000c) /* watchdog timer */\r
++#define AR531X_ISR            (AR531X_RESETTMR + 0x0010) /* Intr Status Reg */\r
++#define AR531X_IMR            (AR531X_RESETTMR + 0x0014) /* Intr Mask Reg */\r
++#define AR531X_RESET          (AR531X_RESETTMR + 0x0020)\r
++#define AR5312_CLOCKCTL1      (AR531X_RESETTMR + 0x0064)\r
++#define AR5312_SCRATCH        (AR531X_RESETTMR + 0x006c)\r
++#define AR531X_PROCADDR               (AR531X_RESETTMR + 0x0070)\r
++#define AR531X_PROC1          (AR531X_RESETTMR + 0x0074)\r
++#define AR531X_DMAADDR                (AR531X_RESETTMR + 0x0078)\r
++#define AR531X_DMA1           (AR531X_RESETTMR + 0x007c)\r
++#define AR531X_ENABLE           (AR531X_RESETTMR + 0x0080) /* interface enb */\r
++#define AR531X_REV            (AR531X_RESETTMR + 0x0090) /* revision */\r
++\r
++/* AR531X_WD_CTRL register bit field definitions */\r
++#define AR531X_WD_CTRL_IGNORE_EXPIRATION 0x0000\r
++#define AR531X_WD_CTRL_NMI               0x0001\r
++#define AR531X_WD_CTRL_RESET             0x0002\r
++\r
++/* AR531X_ISR register bit field definitions */\r
++#define AR531X_ISR_NONE               0x0000\r
++#define AR531X_ISR_TIMER      0x0001\r
++#define AR531X_ISR_AHBPROC    0x0002\r
++#define AR531X_ISR_AHBDMA     0x0004\r
++#define AR531X_ISR_GPIO               0x0008\r
++#define AR531X_ISR_UART0      0x0010\r
++#define AR531X_ISR_UART0DMA   0x0020\r
++#define AR531X_ISR_WD         0x0040\r
++#define AR531X_ISR_LOCAL      0x0080\r
++\r
++/* AR531X_RESET register bit field definitions */\r
++#define AR531X_RESET_SYSTEM     0x00000001  /* cold reset full system */\r
++#define AR531X_RESET_PROC       0x00000002  /* cold reset MIPS core */\r
++#define AR531X_RESET_WLAN0      0x00000004  /* cold reset WLAN MAC and BB */\r
++#define AR531X_RESET_EPHY0      0x00000008  /* cold reset ENET0 phy */\r
++#define AR531X_RESET_EPHY1      0x00000010  /* cold reset ENET1 phy */\r
++#define AR531X_RESET_ENET0      0x00000020  /* cold reset ENET0 mac */\r
++#define AR531X_RESET_ENET1      0x00000040  /* cold reset ENET1 mac */\r
++#define AR531X_RESET_UART0      0x00000100  /* cold reset UART0 (high speed) */\r
++#define AR531X_RESET_WLAN1      0x00000200  /* cold reset WLAN MAC/BB */\r
++#define AR531X_RESET_APB        0x00000400  /* cold reset APB (ar5312) */\r
++#define AR531X_RESET_WARM_PROC  0x00001000  /* warm reset MIPS core */\r
++#define AR531X_RESET_WARM_WLAN0_MAC 0x00002000  /* warm reset WLAN0 MAC */\r
++#define AR531X_RESET_WARM_WLAN0_BB  0x00004000  /* warm reset WLAN0 BaseBand */\r
++#define AR531X_RESET_NMI        0x00010000  /* send an NMI to the processor */\r
++#define AR531X_RESET_WARM_WLAN1_MAC 0x00020000  /* warm reset WLAN1 mac */\r
++#define AR531X_RESET_WARM_WLAN1_BB  0x00040000  /* warm reset WLAN1 baseband */\r
++#define AR531X_RESET_LOCAL_BUS  0x00080000  /* reset local bus */\r
++#define AR531X_RESET_WDOG       0x00100000  /* last reset was a watchdog */\r
++\r
++#define AR531X_RESET_WMAC0_BITS \\r
++        AR531X_RESET_WLAN0 |\\r
++        AR531X_RESET_WARM_WLAN0_MAC |\\r
++        AR531X_RESET_WARM_WLAN0_BB\r
++\r
++#define AR531X_RESERT_WMAC1_BITS \\r
++        AR531X_RESET_WLAN1 |\\r
++        AR531X_RESET_WARM_WLAN1_MAC |\\r
++        AR531X_RESET_WARM_WLAN1_BB\r
++\r
++/* AR5312_CLOCKCTL1 register bit field definitions */\r
++#define AR5312_CLOCKCTL1_PREDIVIDE_MASK    0x00000030\r
++#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT            4\r
++#define AR5312_CLOCKCTL1_MULTIPLIER_MASK   0x00001f00\r
++#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT           8\r
++#define AR5312_CLOCKCTL1_DOUBLER_MASK      0x00010000\r
++\r
++/* Valid for AR5312 and AR2312 */\r
++#define AR5312_CLOCKCTL1_PREDIVIDE_MASK    0x00000030\r
++#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT            4\r
++#define AR5312_CLOCKCTL1_MULTIPLIER_MASK   0x00001f00\r
++#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT           8\r
++#define AR5312_CLOCKCTL1_DOUBLER_MASK      0x00010000\r
++\r
++/* Valid for AR2313 */\r
++#define AR2313_CLOCKCTL1_PREDIVIDE_MASK    0x00003000\r
++#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT           12\r
++#define AR2313_CLOCKCTL1_MULTIPLIER_MASK   0x001f0000\r
++#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT          16\r
++#define AR2313_CLOCKCTL1_DOUBLER_MASK      0x00000000\r
++\r
++\r
++/* AR531X_ENABLE register bit field definitions */\r
++#define AR531X_ENABLE_WLAN0              0x0001\r
++#define AR531X_ENABLE_ENET0              0x0002\r
++#define AR531X_ENABLE_ENET1              0x0004\r
++#define AR531X_ENABLE_UART_AND_WLAN1_PIO 0x0008   /* UART, and WLAN1 PIOs */\r
++#define AR531X_ENABLE_WLAN1_DMA          0x0010   /* WLAN1 DMAs */\r
++#define AR531X_ENABLE_WLAN1 \\r
++            (AR531X_ENABLE_UART_AND_WLAN1_PIO | AR531X_ENABLE_WLAN1_DMA)\r
++\r
++/* AR531X_REV register bit field definitions */\r
++#define AR531X_REV_WMAC_MAJ    0xf000\r
++#define AR531X_REV_WMAC_MAJ_S  12\r
++#define AR531X_REV_WMAC_MIN    0x0f00\r
++#define AR531X_REV_WMAC_MIN_S  8\r
++#define AR531X_REV_MAJ         0x00f0\r
++#define AR531X_REV_MAJ_S       4\r
++#define AR531X_REV_MIN         0x000f\r
++#define AR531X_REV_MIN_S       0\r
++#define AR531X_REV_CHIP        (REV_MAJ|REV_MIN)\r
++\r
++/* Major revision numbers, bits 7..4 of Revision ID register */\r
++#define AR531X_REV_MAJ_AR5312          0x4\r
++#define AR531X_REV_MAJ_AR2313          0x5\r
++\r
++/* Minor revision numbers, bits 3..0 of Revision ID register */\r
++#define AR5312_REV_MIN_DUAL     0x0     /* Dual WLAN version */\r
++#define AR5312_REV_MIN_SINGLE   0x1     /* Single WLAN version */\r
++\r
++/* AR531X_FLASHCTL register bit field definitions */\r
++#define FLASHCTL_IDCY   0x0000000f      /* Idle cycle turn around time */\r
++#define FLASHCTL_IDCY_S 0\r
++#define FLASHCTL_WST1   0x000003e0      /* Wait state 1 */\r
++#define FLASHCTL_WST1_S 5\r
++#define FLASHCTL_RBLE   0x00000400      /* Read byte lane enable */\r
++#define FLASHCTL_WST2   0x0000f800      /* Wait state 2 */\r
++#define FLASHCTL_WST2_S 11\r
++#define FLASHCTL_AC     0x00070000      /* Flash address check (added) */\r
++#define FLASHCTL_AC_S   16\r
++#define FLASHCTL_AC_128K 0x00000000\r
++#define FLASHCTL_AC_256K 0x00010000\r
++#define FLASHCTL_AC_512K 0x00020000\r
++#define FLASHCTL_AC_1M   0x00030000\r
++#define FLASHCTL_AC_2M   0x00040000\r
++#define FLASHCTL_AC_4M   0x00050000\r
++#define FLASHCTL_AC_8M   0x00060000\r
++#define FLASHCTL_AC_RES  0x00070000     /* 16MB is not supported */\r
++#define FLASHCTL_E      0x00080000      /* Flash bank enable (added) */\r
++#define FLASHCTL_BUSERR 0x01000000      /* Bus transfer error status flag */\r
++#define FLASHCTL_WPERR  0x02000000      /* Write protect error status flag */\r
++#define FLASHCTL_WP     0x04000000      /* Write protect */\r
++#define FLASHCTL_BM     0x08000000      /* Burst mode */\r
++#define FLASHCTL_MW     0x30000000      /* Memory width */\r
++#define FLASHCTL_MWx8   0x00000000      /* Memory width x8 */\r
++#define FLASHCTL_MWx16  0x10000000      /* Memory width x16 */\r
++#define FLASHCTL_MWx32  0x20000000      /* Memory width x32 (not supported) */\r
++#define FLASHCTL_ATNR   0x00000000      /* Access type == no retry */\r
++#define FLASHCTL_ATR    0x80000000      /* Access type == retry every */\r
++#define FLASHCTL_ATR4   0xc0000000      /* Access type == retry every 4 */\r
++\r
++/* ARM Flash Controller -- 3 flash banks with either x8 or x16 devices.  */\r
++#define AR531X_FLASHCTL0        (AR531X_FLASHCTL + 0x00)\r
++#define AR531X_FLASHCTL1        (AR531X_FLASHCTL + 0x04)\r
++#define AR531X_FLASHCTL2        (AR531X_FLASHCTL + 0x08)\r
++\r
++/* ARM SDRAM Controller -- just enough to determine memory size */\r
++#define AR531X_MEM_CFG1 (AR531X_SDRAMCTL + 0x04)\r
++#define MEM_CFG1_AC0    0x00000700      /* bank 0: SDRAM addr check (added) */\r
++#define MEM_CFG1_AC0_S  8\r
++#define MEM_CFG1_AC1    0x00007000      /* bank 1: SDRAM addr check (added) */\r
++#define MEM_CFG1_AC1_S  12\r
++\r
++/* GPIO Address Map */\r
++#define AR531X_GPIO         (AR531X_APBBASE  + 0x2000)\r
++#define AR531X_GPIO_DO      (AR531X_GPIO + 0x00)        /* output register */\r
++#define AR531X_GPIO_DI      (AR531X_GPIO + 0x04)        /* intput register */\r
++#define AR531X_GPIO_CR      (AR531X_GPIO + 0x08)        /* control register */\r
++\r
++/* GPIO Control Register bit field definitions */\r
++#define GPIO_CR_M(x)    (1 << (x))                      /* mask for i/o */\r
++#define GPIO_CR_O(x)    (0 << (x))                      /* mask for output */\r
++#define GPIO_CR_I(x)    (1 << (x))                      /* mask for input */\r
++#define GPIO_CR_INT(x)  (1 << ((x)+8))                  /* mask for interrupt */\r
++#define GPIO_CR_UART(x) (1 << ((x)+16))                 /* uart multiplex */\r
++\r
++\r
++typedef unsigned int AR531X_REG;\r
++\r
++#define sysRegRead(phys)      \\r
++      (*(volatile AR531X_REG *)PHYS_TO_K1(phys))\r
++\r
++#define sysRegWrite(phys, val)        \\r
++      ((*(volatile AR531X_REG *)PHYS_TO_K1(phys)) = (val))\r
++\r
++\r
++/*\r
++ * This is board-specific data that is stored in a "fixed" location in flash.\r
++ * It is shared across operating systems, so it should not be changed lightly.\r
++ * The main reason we need it is in order to extract the ethernet MAC\r
++ * address(es).\r
++ */\r
++struct ar531x_boarddata {\r
++    u32 magic;                       /* board data is valid */\r
++#define AR531X_BD_MAGIC 0x35333131   /* "5311", for all 531x platforms */\r
++    u16 cksum;                       /* checksum (starting with BD_REV 2) */\r
++    u16 rev;                         /* revision of this struct */\r
++#define BD_REV  4\r
++    char   boardName[64];            /* Name of board */\r
++    u16 major;                       /* Board major number */\r
++    u16 minor;                       /* Board minor number */\r
++    u32 config;                      /* Board configuration */\r
++#define BD_ENET0        0x00000001   /* ENET0 is stuffed */\r
++#define BD_ENET1        0x00000002   /* ENET1 is stuffed */\r
++#define BD_UART1        0x00000004   /* UART1 is stuffed */\r
++#define BD_UART0        0x00000008   /* UART0 is stuffed (dma) */\r
++#define BD_RSTFACTORY   0x00000010   /* Reset factory defaults stuffed */\r
++#define BD_SYSLED       0x00000020   /* System LED stuffed */\r
++#define BD_EXTUARTCLK   0x00000040   /* External UART clock */\r
++#define BD_CPUFREQ      0x00000080   /* cpu freq is valid in nvram */\r
++#define BD_SYSFREQ      0x00000100   /* sys freq is set in nvram */\r
++#define BD_WLAN0        0x00000200   /* Enable WLAN0 */\r
++#define BD_MEMCAP       0x00000400   /* CAP SDRAM @ memCap for testing */\r
++#define BD_DISWATCHDOG  0x00000800   /* disable system watchdog */\r
++#define BD_WLAN1        0x00001000   /* Enable WLAN1 (ar5212) */\r
++#define BD_ISCASPER     0x00002000   /* FLAG for AR2312 */\r
++#define BD_WLAN0_2G_EN  0x00004000   /* FLAG for radio0_2G */\r
++#define BD_WLAN0_5G_EN  0x00008000   /* FLAG for radio0_2G */\r
++#define BD_WLAN1_2G_EN  0x00020000   /* FLAG for radio0_2G */\r
++#define BD_WLAN1_5G_EN  0x00040000   /* FLAG for radio0_2G */\r
++    u16 resetConfigGpio;             /* Reset factory GPIO pin */\r
++    u16 sysLedGpio;                  /* System LED GPIO pin */\r
++\r
++    u32 cpuFreq;                     /* CPU core frequency in Hz */\r
++    u32 sysFreq;                     /* System frequency in Hz */\r
++    u32 cntFreq;                     /* Calculated C0_COUNT frequency */\r
++\r
++    u8  wlan0Mac[6];\r
++    u8  enet0Mac[6];\r
++    u8  enet1Mac[6];\r
++\r
++    u16 pciId;                       /* Pseudo PCIID for common code */\r
++    u16 memCap;                      /* cap bank1 in MB */\r
++\r
++    /* version 3 */\r
++    u8  wlan1Mac[6];                 /* (ar5212) */\r
++};\r
++#endif /* AR531X_H */\r
+diff -urN linux-2.4.32/arch/mips/ar531x/ar531xintr.S linux-2.4.32.new/arch/mips/ar531x/ar531xintr.S\r
+--- linux-2.4.32/arch/mips/ar531x/ar531xintr.S 1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/ar531xintr.S     2005-12-24 20:29:42.103311176 +0000\r
+@@ -0,0 +1,30 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++#include <asm/asm.h>\r
++#include <asm/mipsregs.h>\r
++#include <asm/regdef.h>\r
++#include <asm/stackframe.h>\r
++\r
++/*\r
++ * Glue code to save registers and get us to the interrupt dispatcher\r
++ */\r
++      .text\r
++      .set    noat\r
++      .align  5\r
++NESTED(ar531x_interrupt_receive, PT_SIZE, sp)\r
++      SAVE_ALL\r
++      CLI\r
++      .set    at\r
++\r
++      move    a0, sp\r
++      jal     ar531x_irq_dispatch\r
++\r
++      j       ret_from_irq\r
++\r
++      END(ar531x_interrupt_receive)\r
+diff -urN linux-2.4.32/arch/mips/ar531x/ar531xirq.c linux-2.4.32.new/arch/mips/ar531x/ar531xirq.c\r
+--- linux-2.4.32/arch/mips/ar531x/ar531xirq.c  1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/ar531xirq.c      2005-12-24 20:29:42.132306768 +0000\r
+@@ -0,0 +1,292 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++/*\r
++ * Interrupt support for AR531X WiSOC.\r
++ */\r
++\r
++#include <linux/config.h>\r
++#include <linux/init.h>\r
++#include <linux/kernel_stat.h>\r
++#include <linux/signal.h>\r
++#include <linux/sched.h>\r
++#include <linux/interrupt.h>\r
++#include <linux/slab.h>\r
++#include <linux/random.h>\r
++#include <linux/pm.h>\r
++#include <linux/delay.h>\r
++#include <linux/reboot.h>\r
++\r
++#include <asm/irq.h>\r
++#include <asm/mipsregs.h>\r
++#include <asm/gdb-stub.h>\r
++\r
++#include "ar531xlnx.h"\r
++#include <asm/irq_cpu.h>\r
++\r
++extern int setup_irq(unsigned int irq, struct irqaction *irqaction);\r
++\r
++static void ar531x_misc_intr_enable(unsigned int irq);\r
++static void ar531x_misc_intr_disable(unsigned int irq);\r
++\r
++/* Turn on the specified AR531X_MISC_IRQ interrupt */\r
++static unsigned int\r
++ar531x_misc_intr_startup(unsigned int irq)\r
++{\r
++      ar531x_misc_intr_enable(irq);\r
++      return 0;\r
++}\r
++\r
++/* Turn off the specified AR531X_MISC_IRQ interrupt */\r
++static void\r
++ar531x_misc_intr_shutdown(unsigned int irq)\r
++{\r
++      ar531x_misc_intr_disable(irq);\r
++}\r
++\r
++/* Enable the specified AR531X_MISC_IRQ interrupt */\r
++static void\r
++ar531x_misc_intr_enable(unsigned int irq)\r
++{\r
++      unsigned int imr;\r
++\r
++      imr = sysRegRead(AR531X_IMR);\r
++      imr |= (1 << (irq - AR531X_MISC_IRQ_BASE - 1));\r
++      sysRegWrite(AR531X_IMR, imr);\r
++      sysRegRead(AR531X_IMR); /* flush write buffer */\r
++}\r
++\r
++/* Disable the specified AR531X_MISC_IRQ interrupt */\r
++static void\r
++ar531x_misc_intr_disable(unsigned int irq)\r
++{\r
++      unsigned int imr;\r
++\r
++      imr = sysRegRead(AR531X_IMR);\r
++      imr &= ~(1 << (irq - AR531X_MISC_IRQ_BASE - 1));\r
++      sysRegWrite(AR531X_IMR, imr);\r
++      sysRegRead(AR531X_IMR); /* flush write buffer */\r
++}\r
++\r
++static void\r
++ar531x_misc_intr_ack(unsigned int irq)\r
++{\r
++      ar531x_misc_intr_disable(irq);\r
++}\r
++\r
++static void\r
++ar531x_misc_intr_end(unsigned int irq)\r
++{\r
++      if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))\r
++              ar531x_misc_intr_enable(irq);\r
++}\r
++\r
++static void\r
++ar531x_misc_intr_set_affinity(unsigned int irq, unsigned long mask)\r
++{\r
++      /* Only 1 CPU; ignore affinity request */\r
++}\r
++\r
++struct hw_interrupt_type ar531x_misc_intr_controller = {\r
++      "AR531X MISC",\r
++      ar531x_misc_intr_startup,\r
++      ar531x_misc_intr_shutdown,\r
++      ar531x_misc_intr_enable,\r
++      ar531x_misc_intr_disable,\r
++      ar531x_misc_intr_ack,\r
++      ar531x_misc_intr_end,\r
++      ar531x_misc_intr_set_affinity,\r
++};\r
++\r
++int ar531x_misc_irq_base;\r
++\r
++/*\r
++ * Determine interrupt source among interrupts that use IP6\r
++ */\r
++void\r
++ar531x_misc_intr_init(int irq_base)\r
++{\r
++      int i;\r
++\r
++      for (i = irq_base; i < irq_base + AR531X_MISC_IRQ_COUNT; i++) {\r
++              irq_desc[i].status = IRQ_DISABLED;\r
++              irq_desc[i].action = NULL;\r
++              irq_desc[i].depth = 1;\r
++              irq_desc[i].handler = &ar531x_misc_intr_controller;\r
++      }\r
++\r
++      ar531x_misc_irq_base = irq_base;\r
++}\r
++\r
++/* ARGSUSED */\r
++void\r
++spurious_irq_handler(int cpl, void *dev_id, struct pt_regs *regs)\r
++{\r
++    /* \r
++    printk("spurious_irq_handler: %d  cause=0x%8.8x  status=0x%8.8x\n",\r
++           cpl, cause_intrs, status_intrs); \r
++    */\r
++}\r
++\r
++/* ARGSUSED */\r
++void\r
++spurious_misc_handler(int cpl, void *dev_id, struct pt_regs *regs)\r
++{\r
++    /*\r
++    printk("spurious_misc_handler: 0x%x isr=0x%8.8x imr=0x%8.8x\n",\r
++           cpl, ar531x_isr, ar531x_imr);\r
++    */\r
++}\r
++\r
++void\r
++ar531x_timer_handler(int cpl, void *dev_id, struct pt_regs *regs)\r
++{\r
++      (void)sysRegRead(AR531X_TIMER); /* clear interrupt */\r
++}\r
++\r
++void\r
++ar531x_ahb_proc_handler(int cpl, void *dev_id, struct pt_regs *regs)\r
++{\r
++    u32 procAddr;\r
++    u32 proc1;\r
++    u32 dmaAddr;\r
++    u32 dma1;\r
++\r
++    proc1 = sysRegRead(AR531X_PROC1);\r
++    procAddr = sysRegRead(AR531X_PROCADDR); /* clears error state */\r
++    dma1 = sysRegRead(AR531X_DMA1);\r
++    dmaAddr = sysRegRead(AR531X_DMAADDR);   /* clears error state */\r
++\r
++    printk("AHB interrupt: PROCADDR=0x%8.8x  PROC1=0x%8.8x  DMAADDR=0x%8.8x  DMA1=0x%8.8x\n",\r
++        procAddr, proc1, dmaAddr, dma1);\r
++        \r
++    machine_restart("AHB error"); /* Catastrophic failure */\r
++}\r
++\r
++static struct irqaction cascade  =\r
++      {no_action, SA_INTERRUPT, 0, "cascade",\r
++            NULL, NULL};\r
++\r
++static struct irqaction spurious_irq =\r
++      {spurious_irq_handler, SA_INTERRUPT, 0, "spurious_irq",\r
++            NULL, NULL};\r
++\r
++static struct irqaction spurious_misc =\r
++      {spurious_misc_handler, SA_INTERRUPT, 0, "spurious_misc",\r
++            NULL, NULL};\r
++\r
++static struct irqaction ar531x_timer_interrupt =\r
++      {ar531x_timer_handler, SA_INTERRUPT, 0, "ar531x_timer_interrupt",\r
++            NULL, NULL};\r
++\r
++static struct irqaction ar531x_ahb_proc_interrupt =\r
++      {ar531x_ahb_proc_handler, SA_INTERRUPT, 0, "ar531x_ahb_proc_interrupt",\r
++            NULL, NULL};\r
++\r
++extern asmlinkage void ar531x_interrupt_receive(void);\r
++\r
++/*\r
++ * Called when an interrupt is received, this function\r
++ * determines exactly which interrupt it was, and it\r
++ * invokes the appropriate handler.\r
++ *\r
++ * Implicitly, we also define interrupt priority by\r
++ * choosing which to dispatch first.\r
++ */\r
++void\r
++ar531x_irq_dispatch(struct pt_regs *regs)\r
++{\r
++      int cause_intrs = regs->cp0_cause;\r
++      int status_intrs = regs->cp0_status;\r
++      int pending = cause_intrs & status_intrs;\r
++\r
++      if (pending & CAUSEF_IP2) {\r
++              do_IRQ(AR531X_IRQ_WLAN0_INTRS, regs);\r
++      }               \r
++      else if (pending & CAUSEF_IP3) {\r
++              do_IRQ(AR531X_IRQ_ENET0_INTRS, regs);\r
++      }\r
++      else if (pending & CAUSEF_IP4) {\r
++              do_IRQ(AR531X_IRQ_ENET1_INTRS, regs);\r
++      }\r
++      else if (pending & CAUSEF_IP5) {\r
++              do_IRQ(AR531X_IRQ_WLAN1_INTRS, regs);\r
++      }\r
++      else if (pending & CAUSEF_IP6) {\r
++              AR531X_REG ar531x_isr = sysRegRead(AR531X_ISR);\r
++              AR531X_REG ar531x_imr = sysRegRead(AR531X_IMR);\r
++              unsigned int ar531x_misc_intrs = ar531x_isr & ar531x_imr;\r
++\r
++              if (ar531x_misc_intrs & AR531X_ISR_TIMER)\r
++                      do_IRQ(AR531X_MISC_IRQ_TIMER, regs);\r
++              else if (ar531x_misc_intrs & AR531X_ISR_AHBPROC)\r
++                      do_IRQ(AR531X_MISC_IRQ_AHB_PROC, regs);\r
++              else if (ar531x_misc_intrs & AR531X_ISR_AHBDMA)\r
++                      do_IRQ(AR531X_MISC_IRQ_AHB_DMA, regs);\r
++              else if (ar531x_misc_intrs & AR531X_ISR_GPIO)\r
++                {\r
++                    int i;\r
++                    u32 gpioIntPending;\r
++\r
++                    gpioIntPending = sysRegRead(AR531X_GPIO_DI) & gpioIntMask;\r
++                    for (i=0; i<AR531X_GPIO_IRQ_COUNT; i++) {\r
++                        if (gpioIntPending & (1 << i))\r
++                            do_IRQ(AR531X_GPIO_IRQ(i), regs);\r
++                    }\r
++                }\r
++              else if ((ar531x_misc_intrs & AR531X_ISR_UART0) ||\r
++                       (ar531x_misc_intrs & AR531X_ISR_UART0DMA)) {\r
++                      do_IRQ(AR531X_MISC_IRQ_UART0, regs);\r
++#if CONFIG_KGDB\r
++                        if (kgdbInterrupt()) {\r
++                                if (!user_mode(regs))\r
++                                  set_async_breakpoint((unsigned long *)&regs->cp0_epc);\r
++                        }\r
++#endif        /* CONFIG_KGDB */\r
++                }\r
++              else if (ar531x_misc_intrs & AR531X_ISR_WD)\r
++                      do_IRQ(AR531X_MISC_IRQ_WATCHDOG, regs);\r
++              else if (ar531x_misc_intrs & AR531X_ISR_LOCAL)\r
++                      do_IRQ(AR531X_MISC_IRQ_LOCAL, regs);\r
++              else\r
++                      do_IRQ(AR531X_MISC_IRQ_NONE, regs);\r
++      } else if (pending & CAUSEF_IP7)\r
++              do_IRQ(AR531X_IRQ_CPU_CLOCK, regs);\r
++      else\r
++              do_IRQ(AR531X_IRQ_NONE, regs);\r
++}\r
++\r
++void __init init_IRQ(void)\r
++{\r
++      init_generic_irq();\r
++      set_except_vector(0, ar531x_interrupt_receive);\r
++\r
++      /* Initialize interrupt controllers */\r
++      mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);\r
++      ar531x_misc_intr_init(AR531X_MISC_IRQ_BASE);\r
++        ar531x_gpio_intr_init(AR531X_GPIO_IRQ_BASE);\r
++      setup_irq(AR531X_IRQ_MISC_INTRS, &cascade);\r
++      /*\r
++         * AR531X_IRQ_CPU_CLOCK is setup by ar531x_timer_setup.\r
++         */\r
++\r
++      /* Default "spurious interrupt" handlers */\r
++      setup_irq(AR531X_IRQ_NONE, &spurious_irq);\r
++      setup_irq(AR531X_MISC_IRQ_NONE, &spurious_misc);\r
++      setup_irq(AR531X_GPIO_IRQ_NONE, &spurious_gpio);\r
++\r
++      setup_irq(AR531X_MISC_IRQ_TIMER, &ar531x_timer_interrupt);\r
++      setup_irq(AR531X_MISC_IRQ_AHB_PROC, &ar531x_ahb_proc_interrupt);\r
++        setup_irq(AR531X_MISC_IRQ_GPIO, &cascade);\r
++\r
++#ifdef CONFIG_KGDB\r
++#if CONFIG_EARLY_STOP\r
++        kgdbInit();\r
++#endif\r
++#endif\r
++}\r
+diff -urN linux-2.4.32/arch/mips/ar531x/ar531xksyms.c linux-2.4.32.new/arch/mips/ar531x/ar531xksyms.c\r
+--- linux-2.4.32/arch/mips/ar531x/ar531xksyms.c        1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/ar531xksyms.c    2005-12-24 20:29:42.132306768 +0000\r
+@@ -0,0 +1,16 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++#include <linux/module.h>\r
++#include "asm/atheros/ar531xbsp.h"\r
++\r
++#if CONFIG_KGDB\r
++EXPORT_SYMBOL(kgdbInit);\r
++EXPORT_SYMBOL(kgdbEnabled);\r
++#endif\r
++EXPORT_SYMBOL(ar531x_sys_frequency);\r
+diff -urN linux-2.4.32/arch/mips/ar531x/ar531xlnx.h linux-2.4.32.new/arch/mips/ar531x/ar531xlnx.h\r
+--- linux-2.4.32/arch/mips/ar531x/ar531xlnx.h  1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/ar531xlnx.h      2005-12-24 20:29:42.133306616 +0000\r
+@@ -0,0 +1,122 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++/*\r
++ * This file contains definitions needed in order to compile\r
++ * AR531X products for linux.  Definitions that are largely\r
++ * AR531X-specific and independent of operating system belong\r
++ * in ar531x.h rather than this file.\r
++ */\r
++#include "ar531x.h"\r
++\r
++#define MIPS_CPU_IRQ_BASE             0x00\r
++#define AR531X_HIGH_PRIO                0x10\r
++#define AR531X_MISC_IRQ_BASE          0x20\r
++#define AR531X_GPIO_IRQ_BASE            0x30\r
++\r
++/* Software's idea of interrupts handled by "CPU Interrupt Controller" */\r
++#define AR531X_IRQ_NONE               MIPS_CPU_IRQ_BASE+0\r
++#define AR531X_IRQ_WLAN0_INTRS        MIPS_CPU_IRQ_BASE+2 /* C0_CAUSE: 0x0400 */\r
++#define AR531X_IRQ_ENET0_INTRS        MIPS_CPU_IRQ_BASE+3 /* C0_CAUSE: 0x0800 */\r
++#define AR531X_IRQ_ENET1_INTRS        MIPS_CPU_IRQ_BASE+4 /* C0_CAUSE: 0x1000 */\r
++#define AR531X_IRQ_WLAN1_INTRS        MIPS_CPU_IRQ_BASE+5 /* C0_CAUSE: 0x2000 */\r
++#define AR531X_IRQ_MISC_INTRS MIPS_CPU_IRQ_BASE+6 /* C0_CAUSE: 0x4000 */\r
++#define AR531X_IRQ_CPU_CLOCK  MIPS_CPU_IRQ_BASE+7 /* C0_CAUSE: 0x8000 */\r
++\r
++/* Miscellaneous interrupts, which share IP6 */\r
++#define AR531X_MISC_IRQ_NONE          AR531X_MISC_IRQ_BASE+0\r
++#define AR531X_MISC_IRQ_TIMER         AR531X_MISC_IRQ_BASE+1\r
++#define AR531X_MISC_IRQ_AHB_PROC      AR531X_MISC_IRQ_BASE+2\r
++#define AR531X_MISC_IRQ_AHB_DMA               AR531X_MISC_IRQ_BASE+3\r
++#define AR531X_MISC_IRQ_GPIO          AR531X_MISC_IRQ_BASE+4\r
++#define AR531X_MISC_IRQ_UART0         AR531X_MISC_IRQ_BASE+5\r
++#define AR531X_MISC_IRQ_UART0_DMA     AR531X_MISC_IRQ_BASE+6\r
++#define AR531X_MISC_IRQ_WATCHDOG      AR531X_MISC_IRQ_BASE+7\r
++#define AR531X_MISC_IRQ_LOCAL         AR531X_MISC_IRQ_BASE+8\r
++#define AR531X_MISC_IRQ_COUNT         9\r
++\r
++/* GPIO Interrupts [0..7], share AR531X_MISC_IRQ_GPIO */\r
++#define AR531X_GPIO_IRQ_NONE            AR531X_MISC_IRQ_BASE+0\r
++#define AR531X_GPIO_IRQ(n)              AR531X_MISC_IRQ_BASE+(n)+1\r
++#define AR531X_GPIO_IRQ_COUNT           9\r
++\r
++#define PHYS_TO_K1(physaddr) KSEG1ADDR(physaddr)\r
++#define PHYS_TO_K0(physaddr) KSEG0ADDR(physaddr)\r
++#define UNMAPPED_TO_PHYS(vaddr)  PHYSADDR(vaddr)\r
++#define IS_UNMAPPED_VADDR(vaddr) \\r
++    ((KSEGX(vaddr) == KSEG0) || (KSEGX(vaddr) == KSEG1))\r
++\r
++/* IOCTL commands for /proc/ar531x */\r
++#define AR531X_CTRL_DO_BREAKPOINT       1\r
++#define AR531X_CTRL_DO_MADWIFI          2\r
++\r
++/*\r
++ * Definitions for operating system portability.\r
++ * These are vxWorks-->Linux translations.\r
++ */\r
++#define LOCAL static\r
++#define BOOL int\r
++#define TRUE 1\r
++#define FALSE 0\r
++#define UINT8 u8\r
++#define UINT16 u16\r
++#define UINT32 u32\r
++#define PRINTF printk\r
++#if /* DEBUG */ 1\r
++#define DEBUG_PRINTF printk\r
++#define INLINE\r
++#else\r
++DEBUG_PRINTF while (0) printk\r
++#define INLINE inline\r
++#endif\r
++#define sysUDelay(usecs) udelay(usecs)\r
++#define sysMsDelay(msecs) mdelay(msecs)\r
++typedef volatile UINT8 *VIRT_ADDR;\r
++#define MALLOC(sz) kmalloc(sz, GFP_KERNEL)\r
++#define MALLOC_NOSLEEP(sz) kmalloc(sz, GFP_ATOMIC)\r
++#define FREE(ptr) kfree((void *)ptr)\r
++#define BSP_BUG() do { printk("kernel BSP BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)\r
++#define BSP_BUG_ON(condition) do { if (unlikely((condition)!=0)) BSP_BUG(); } while(0)\r
++#define ASSERT(x) BSP_BUG_ON(!(x))\r
++\r
++extern struct ar531x_boarddata *ar531x_board_configuration;\r
++extern char *ar531x_radio_configuration;\r
++extern char *enet_mac_address_get(int MACUnit);\r
++\r
++extern void kgdbInit(void);\r
++extern int kgdbEnabled(void);\r
++extern void breakpoint(void);\r
++extern int kgdbInterrupt(void);\r
++extern unsigned int ar531x_cpu_frequency(void);\r
++extern unsigned int ar531x_sys_frequency(void);\r
++\r
++/* GPIO support */\r
++extern struct irqaction spurious_gpio;\r
++extern unsigned int gpioIntMask;\r
++extern void ar531x_gpio_intr_init(int irq_base);\r
++extern void ar531x_gpio_ctrl_output(int gpio);\r
++extern void ar531x_gpio_ctrl_input(int gpio);\r
++extern void ar531x_gpio_set(int gpio, int val);\r
++extern int  ar531x_gpio_get(int gpio);\r
++extern void ar531x_gpio_intr_enable(unsigned int irq);\r
++extern void ar531x_gpio_intr_disable(unsigned int irq);\r
++\r
++/* Watchdog Timer support */\r
++extern int watchdog_start(unsigned int milliseconds);\r
++extern int watchdog_stop(void);\r
++extern int watchdog_is_enabled(void);\r
++extern unsigned int watchdog_min_timer_reached(void);\r
++extern void watchdog_notify_alive(void);\r
++\r
++#define A_DATA_CACHE_INVAL(start, length) \\r
++        dma_cache_inv((UINT32)(start),(length))\r
++\r
++#define sysWbFlush() mb()\r
++\r
++#define intDisable(x) cli()\r
++#define intEnable(x) sti()\r
+diff -urN linux-2.4.32/arch/mips/ar531x/ar531xprom.c linux-2.4.32.new/arch/mips/ar531x/ar531xprom.c\r
+--- linux-2.4.32/arch/mips/ar531x/ar531xprom.c 1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/ar531xprom.c     2005-12-24 20:29:42.133306616 +0000\r
+@@ -0,0 +1,84 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright MontaVista Software Inc\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++/*\r
++ * Prom setup file for ar531x\r
++ */\r
++\r
++#include <linux/init.h>\r
++#include <linux/config.h>\r
++#include <linux/kernel.h>\r
++#include <linux/string.h>\r
++#include <linux/mm.h>\r
++#include <linux/bootmem.h>\r
++\r
++#include <asm/bootinfo.h>\r
++#include <asm/addrspace.h>\r
++\r
++#include "ar531xlnx.h"\r
++\r
++#define COMMAND_LINE_SIZE 512\r
++\r
++char arcs_cmdline[COMMAND_LINE_SIZE];\r
++\r
++void __init prom_init(int argc, char *argv[])\r
++{\r
++    int i;\r
++    unsigned int memcfg1;\r
++    int bank0AC, bank1AC;\r
++    int memsz_in_mb;\r
++\r
++    strcpy(arcs_cmdline, "console=ttyS0,9600");\r
++    for (i=0; i<argc; i++) {\r
++        strcat(arcs_cmdline, " ");\r
++        strcat(arcs_cmdline, argv[i]);\r
++    }\r
++\r
++    mips_machgroup = MACH_GROUP_AR531X;\r
++#ifdef CONFIG_APUNUSED\r
++    mips_machtype = MACH_ATHEROS_UNUSED;\r
++#endif\r
++#ifdef CONFIG_AP30\r
++    mips_machtype = MACH_ATHEROS_AP30;\r
++#endif\r
++#ifdef CONFIG_AP33\r
++    mips_machtype = MACH_ATHEROS_AP33;\r
++#endif\r
++#ifdef CONFIG_AP38\r
++    mips_machtype = MACH_ATHEROS_AP38;\r
++#endif\r
++#ifdef CONFIG_AP43\r
++    mips_machtype = MACH_ATHEROS_AP43;\r
++#endif\r
++#ifdef CONFIG_AP48\r
++    mips_machtype = MACH_ATHEROS_AP48;\r
++#endif\r
++#ifdef CONFIG_PB32\r
++    mips_machtype = MACH_ATHEROS_PB32;\r
++#endif\r
++\r
++\r
++    /* Determine SDRAM size based on Address Checks done at startup */\r
++    memcfg1 = sysRegRead(AR531X_MEM_CFG1);\r
++    bank0AC = (memcfg1 & MEM_CFG1_AC0) >> MEM_CFG1_AC0_S;\r
++    bank1AC = (memcfg1 & MEM_CFG1_AC1) >> MEM_CFG1_AC1_S;\r
++    memsz_in_mb = (bank0AC ? (1 << (bank0AC+1)) : 0)\r
++                + (bank1AC ? (1 << (bank1AC+1)) : 0);\r
++\r
++    /*\r
++     * By default, use all available memory.  You can override this\r
++     * to use, say, 8MB by specifying "mem=8M" as an argument on the\r
++     * linux bootup command line.\r
++     */\r
++    add_memory_region(0, memsz_in_mb << 20, BOOT_MEM_RAM);\r
++}\r
++\r
++void __init prom_free_prom_memory(void)\r
++{\r
++}\r
+diff -urN linux-2.4.32/arch/mips/ar531x/ar531xsetup.c linux-2.4.32.new/arch/mips/ar531x/ar531xsetup.c\r
+--- linux-2.4.32/arch/mips/ar531x/ar531xsetup.c        1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/ar531xsetup.c    2005-12-24 20:29:42.133306616 +0000\r
+@@ -0,0 +1,240 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++/*\r
++ * Initialization for ar531x SOC.\r
++ */\r
++\r
++#include <linux/config.h>\r
++#include <linux/init.h>\r
++#include <linux/delay.h>\r
++#include <linux/irq.h>\r
++#include <linux/interrupt.h>\r
++#include <linux/serial.h>\r
++#include <linux/types.h>\r
++#include <linux/string.h>\r
++\r
++#include <asm/reboot.h>\r
++#include <asm/io.h>\r
++#include <asm/time.h>\r
++#include <asm/pgtable.h>\r
++#include <asm/processor.h>\r
++#include <asm/reboot.h>\r
++#include <asm/system.h>\r
++#include <asm/serial.h>\r
++\r
++#include "ar531xlnx.h"\r
++\r
++void\r
++ar531x_restart(char *command)\r
++{\r
++    for(;;) {\r
++        sysRegWrite(AR531X_RESET, AR531X_RESET_SYSTEM);\r
++    }\r
++}\r
++\r
++void\r
++ar531x_halt(void)\r
++{\r
++        printk(KERN_NOTICE "\n** You can safely turn off the power\n");\r
++        while (1);\r
++}\r
++\r
++void\r
++ar531x_power_off(void)\r
++{\r
++        ar531x_halt();\r
++}\r
++\r
++const char *\r
++get_system_type(void)\r
++{\r
++      return "Atheros AR531X";\r
++}\r
++\r
++/*\r
++ * This table is indexed by bits 5..4 of the CLOCKCTL1 register\r
++ * to determine the predevisor value.\r
++ */\r
++static int CLOCKCTL1_PREDIVIDE_TABLE[4] = {\r
++    1,\r
++    2,\r
++    4,\r
++    5\r
++};\r
++\r
++unsigned int\r
++ar531x_cpu_frequency(void)\r
++{\r
++      static unsigned int ar531x_calculated_cpu_freq;\r
++        unsigned int clockctl1_predivide_mask;\r
++        unsigned int clockctl1_predivide_shift;\r
++        unsigned int clockctl1_multiplier_mask;\r
++        unsigned int clockctl1_multiplier_shift;\r
++        unsigned int clockctl1_doubler_mask;\r
++        int wisoc_revision;\r
++\r
++        /*\r
++         * Trust the bootrom's idea of cpu frequency.\r
++         */\r
++        ar531x_calculated_cpu_freq = sysRegRead(AR5312_SCRATCH);\r
++        if (ar531x_calculated_cpu_freq)\r
++          return ar531x_calculated_cpu_freq;\r
++\r
++        wisoc_revision = (sysRegRead(AR531X_REV) & AR531X_REV_MAJ) >> AR531X_REV_MAJ_S;\r
++        if (wisoc_revision == AR531X_REV_MAJ_AR2313) {\r
++            clockctl1_predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK;\r
++            clockctl1_predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT;\r
++            clockctl1_multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK;\r
++            clockctl1_multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT;\r
++            clockctl1_doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK;\r
++        } else { /* AR5312 and AR2312 */\r
++            clockctl1_predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK;\r
++            clockctl1_predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT;\r
++            clockctl1_multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK;\r
++            clockctl1_multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT;\r
++            clockctl1_doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK;\r
++        }\r
++\r
++        /*\r
++         * Clocking is derived from a fixed 40MHz input clock.\r
++         *  cpuFreq = InputClock * MULT (where MULT is PLL multiplier)\r
++         *\r
++         *  sysFreq = cpuFreq / 4       (used for APB clock, serial,\r
++         *                               flash, Timer, Watchdog Timer)\r
++         *\r
++         *  cntFreq = cpuFreq / 2       (use for CPU count/compare)\r
++         *\r
++         * So, for example, with a PLL multiplier of 5, we have\r
++         *  cpuFrez = 200MHz\r
++         *  sysFreq = 50MHz\r
++         *  cntFreq = 100MHz\r
++         *\r
++         * We compute the CPU frequency, based on PLL settings.\r
++         */\r
++      if (ar531x_calculated_cpu_freq == 0) {\r
++            unsigned int clockCtl1 = sysRegRead(AR5312_CLOCKCTL1);\r
++\r
++            int preDivideSelect = (clockCtl1 & clockctl1_predivide_mask) >>\r
++                                   clockctl1_predivide_shift;\r
++\r
++            int preDivisor = CLOCKCTL1_PREDIVIDE_TABLE[preDivideSelect];\r
++\r
++            int multiplier = (clockCtl1 & clockctl1_multiplier_mask) >>\r
++                              clockctl1_multiplier_shift;\r
++\r
++            if (clockCtl1 & clockctl1_doubler_mask) {\r
++                multiplier = multiplier << 1;\r
++            }\r
++\r
++            ar531x_calculated_cpu_freq = (40000000 / preDivisor) * multiplier;\r
++        }\r
++\r
++      return ar531x_calculated_cpu_freq;\r
++}\r
++\r
++unsigned int\r
++ar531x_sys_frequency(void)\r
++{\r
++      static unsigned int ar531x_calculated_sys_freq = 0;\r
++\r
++      if (ar531x_calculated_sys_freq == 0) {\r
++              ar531x_calculated_sys_freq = ar531x_cpu_frequency() / 4;\r
++      }\r
++\r
++      return ar531x_calculated_sys_freq;\r
++}\r
++\r
++static void __init\r
++flash_setup(void)\r
++{\r
++    UINT32 flash_ctl;\r
++\r
++    /* Configure flash bank 0 */\r
++    flash_ctl = FLASHCTL_E |\r
++                FLASHCTL_AC_8M |\r
++                FLASHCTL_RBLE |\r
++                (0x01 << FLASHCTL_IDCY_S) |\r
++                (0x07 << FLASHCTL_WST1_S) |\r
++                (0x07 << FLASHCTL_WST2_S) |\r
++                (sysRegRead(AR531X_FLASHCTL0) & FLASHCTL_MW);\r
++\r
++    sysRegWrite(AR531X_FLASHCTL0, flash_ctl);\r
++\r
++    /* Disable other flash banks */\r
++    sysRegWrite(AR531X_FLASHCTL1,\r
++                sysRegRead(AR531X_FLASHCTL1) & ~(FLASHCTL_E | FLASHCTL_AC));\r
++\r
++    sysRegWrite(AR531X_FLASHCTL2,\r
++                sysRegRead(AR531X_FLASHCTL2) & ~(FLASHCTL_E | FLASHCTL_AC));\r
++}\r
++\r
++\r
++\r
++void __init\r
++serial_setup(void)\r
++{\r
++      struct serial_struct s;\r
++\r
++      memset(&s, 0, sizeof(s));\r
++\r
++      s.flags = STD_COM_FLAGS;\r
++      s.io_type = SERIAL_IO_MEM;\r
++      s.baud_base = ar531x_sys_frequency()/16;\r
++      s.irq = AR531X_MISC_IRQ_UART0;\r
++      s.iomem_reg_shift = 2;\r
++      s.iomem_base = (u8 *)0xbc000003;\r
++\r
++      if (early_serial_setup(&s) != 0)\r
++              printk(KERN_ERR "early_serial_setup failed\n");\r
++}\r
++\r
++extern int setup_irq(unsigned int irq, struct irqaction *irqaction);\r
++static void __init\r
++ar531x_timer_setup(struct irqaction *irq)\r
++{\r
++        unsigned int count;\r
++\r
++      /* Usually irq is timer_irqaction (timer_interrupt) */\r
++              setup_irq(AR531X_IRQ_CPU_CLOCK, irq);\r
++\r
++        /* to generate the first CPU timer interrupt */\r
++        count = read_c0_count();\r
++        write_c0_compare(count + 1000);\r
++}\r
++\r
++extern void (*board_time_init)(void);\r
++\r
++static void __init\r
++ar531x_time_init(void)\r
++{\r
++      mips_hpt_frequency = ar531x_cpu_frequency() / 2;\r
++}\r
++\r
++void __init\r
++ar531x_setup(void)\r
++{\r
++      /* Clear any lingering AHB errors */\r
++      sysRegRead(AR531X_PROCADDR);\r
++      sysRegRead(AR531X_DMAADDR);\r
++\r
++      sysRegWrite(AR531X_WD_CTRL, AR531X_WD_CTRL_IGNORE_EXPIRATION);\r
++\r
++        /* Disable data watchpoints */\r
++        write_c0_watchlo0(0);\r
++\r
++      board_time_init = ar531x_time_init;\r
++        board_timer_setup = ar531x_timer_setup;\r
++\r
++        _machine_restart = ar531x_restart;\r
++        _machine_halt = ar531x_halt;\r
++        _machine_power_off = ar531x_power_off;\r
++\r
++        flash_setup();\r
++        serial_setup();\r
++}\r
+diff -urN linux-2.4.32/arch/mips/ar531x/Makefile linux-2.4.32.new/arch/mips/ar531x/Makefile\r
+--- linux-2.4.32/arch/mips/ar531x/Makefile     1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/Makefile 2005-12-24 20:29:42.010325312 +0000\r
+@@ -0,0 +1,33 @@\r
++#\r
++# This file is subject to the terms and conditions of the GNU General Public\r
++# License.  See the file "COPYING" in the main directory of this archive\r
++# for more details.\r
++#\r
++# Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++#\r
++\r
++# Makefile for Atheros ar531x boards\r
++#\r
++# Note! Dependencies are done automagically by 'make dep', which also\r
++# removes any old dependencies. DON'T put your own dependencies here\r
++# unless it's something special (ie not a .c file).\r
++#\r
++\r
++.S.s:\r
++      $(CPP) $(CFLAGS) $< -o $*.s\r
++.S.o:\r
++      $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $*.o\r
++\r
++O_TARGET:= ar531x.o\r
++\r
++export-objs = ar531xksyms.o\r
++\r
++obj-y    := ar531xdbg_io.o    \\r
++      ar531xsetup.o   \\r
++      ar531xprom.o    \\r
++      ar531xirq.o     \\r
++      ar531xintr.o    \\r
++      ar531xgpio.o    \\r
++      ar531xksyms.o\r
++\r
++include $(TOPDIR)/Rules.make\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/backup-busybox.links linux-2.4.32.new/arch/mips/ar531x/RAMDISK/backup-busybox.links\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/backup-busybox.links 1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/backup-busybox.links     2005-12-24 20:29:42.011325160 +0000\r
+@@ -0,0 +1,33 @@\r
++/usr/bin/[\r
++/sbin/brctl\r
++/bin/cat\r
++/bin/chmod\r
++/bin/cp\r
++/bin/df\r
++/bin/echo\r
++/bin/false\r
++/sbin/ifconfig\r
++/sbin/init\r
++/sbin/insmod\r
++/bin/kill\r
++/bin/ls\r
++/sbin/lsmod\r
++/bin/mkdir\r
++/sbin/modprobe\r
++/bin/mount\r
++/bin/msh\r
++/bin/mv\r
++/bin/ping\r
++/bin/ps\r
++/bin/pwd\r
++/sbin/reboot\r
++/bin/rm\r
++/bin/rmdir\r
++/sbin/rmmod\r
++/sbin/route\r
++/bin/sh\r
++/usr/bin/test\r
++/usr/bin/top\r
++/bin/true\r
++/bin/umount\r
++/usr/bin/wget\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/busybox.links linux-2.4.32.new/arch/mips/ar531x/RAMDISK/busybox.links\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/busybox.links        1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/busybox.links    2005-12-24 20:29:42.011325160 +0000\r
+@@ -0,0 +1,33 @@\r
++/usr/bin/[\r
++/sbin/brctl\r
++/bin/cat\r
++/bin/chmod\r
++/bin/cp\r
++/bin/df\r
++/bin/echo\r
++/bin/false\r
++/sbin/ifconfig\r
++/sbin/init\r
++/sbin/insmod\r
++/bin/kill\r
++/bin/ls\r
++/sbin/lsmod\r
++/bin/mkdir\r
++/sbin/modprobe\r
++/bin/mount\r
++/bin/msh\r
++/bin/mv\r
++/bin/ping\r
++/bin/ps\r
++/bin/pwd\r
++/sbin/reboot\r
++/bin/rm\r
++/bin/rmdir\r
++/sbin/rmmod\r
++/sbin/route\r
++/bin/sh\r
++/usr/bin/test\r
++/bin/true\r
++/bin/umount\r
++/bin/uname\r
++/usr/bin/wget\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/Makefile linux-2.4.32.new/arch/mips/ar531x/RAMDISK/Makefile\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/Makefile     1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/Makefile 2005-12-24 20:29:42.011325160 +0000\r
+@@ -0,0 +1,53 @@\r
++KERNEL_SOURCE=../../../..\r
++\r
++# The value for INITRDSIZE is extracted from linux/.config,\r
++# if it exists; otherwise, a default value is used.\r
++\r
++CONFIG_FILE = $(KERNEL_SOURCE)/.config\r
++\r
++ifeq ($(CONFIG_FILE),$(wildcard $(CONFIG_FILE)))\r
++\r
++include $(CONFIG_FILE)\r
++ifdef CONFIG_BLK_DEV_RAM_SIZE\r
++INITRDSIZE  := $(shell echo $(CONFIG_BLK_DEV_RAM_SIZE))\r
++else\r
++INITRDSIZE := 8192\r
++endif\r
++\r
++else\r
++INITRDSIZE := 8192\r
++endif\r
++\r
++MOUNTPT = /mnt/xtmp\r
++\r
++ramdisk.gz: ramdisk\r
++      gzip -f ramdisk\r
++\r
++ramdisk:\r
++      ./makelinks  \r
++      @echo "CREATING RAMDISK OF SIZE $(INITRDSIZE) on $@"\r
++      dd if=/dev/zero of=$@ bs=1k count=$(INITRDSIZE)\r
++      /sbin/mke2fs -vFm0 $@ $(INITRDSIZE)\r
++      if [ \! -e $(MOUNTPT) ]; then mkdir -p $(MOUNTPT) ; fi\r
++      mount -o loop $@ $(MOUNTPT)\r
++      @df $(MOUNTPT)\r
++      (cd rootdir; tar cf - . ) | (cd $(MOUNTPT) && tar xf - )\r
++      (cd $(MOUNTPT) ; chown -R root.root . )\r
++      @df $(MOUNTPT)\r
++      umount $(MOUNTPT)\r
++\r
++install:\r
++      @(if [ -d $(KERNEL_SOURCE)/arch/mips/ramdisk ]; \\r
++      then \\r
++              if [ -f ramdisk.gz ]; \\r
++              then \\r
++                      cp ramdisk.gz $(KERNEL_SOURCE)/arch/mips/ramdisk/; \\r
++              else \\r
++                      echo "No ramdisk.gz image"; \\r
++              fi; \\r
++      else \\r
++              echo "No ramdisk directory.  Check KERNEL_SOURCE variable."; \\r
++      fi)\r
++\r
++clean:        \r
++      rm -f ramdisk.gz ramdisk\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/makelinks linux-2.4.32.new/arch/mips/ar531x/RAMDISK/makelinks\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/makelinks    1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/makelinks        2005-12-24 20:29:42.012325008 +0000\r
+@@ -0,0 +1,65 @@\r
++#!/bin/sh\r
++\r
++if [ -f busybox.links ]\r
++then\r
++    cat busybox.links | sed 's/\//ln -s -f \/bin\/busybox rootdir\//' | /bin/sh\r
++fi\r
++\r
++cons="  root tty    622"\r
++disk="  root disk   660"\r
++mtd="  root root   640"\r
++makedev () {    # usage: makedev name [bcu] major minor owner group mode\r
++        if [ "$opt_v" ]\r
++        then    if [ "$opt_d" ]\r
++                then    echo "rm -f $1"\r
++                else    echo "$1        = $2 $3 $4 $5:$6 $7"\r
++                fi\r
++        fi\r
++        [ ! "$opt_n" ] && rm -f $1 &&\r
++        [ ! "$opt_d" ] && mknod $1 $2 $3 $4 &&\r
++                chown $5:$6 $1 &&\r
++                chmod $7 $1\r
++}  \r
++\r
++makedev rootdir/dev/console c 5 1 $cons\r
++makedev rootdir/dev/ram  b 1 1 $disk \r
++makedev rootdir/dev/ram0 b 1 0 $disk\r
++makedev rootdir/dev/ram1 b 1 1 $disk \r
++makedev rootdir/dev/ram2 b 1 2 $disk\r
++makedev rootdir/dev/ram3 b 1 3 $disk\r
++makedev rootdir/dev/ram4 b 1 4 $disk\r
++makedev rootdir/dev/ram5 b 1 5 $disk\r
++makedev rootdir/dev/ram6 b 1 6 $disk\r
++makedev rootdir/dev/ram7 b 1 7 $disk\r
++makedev rootdir/dev/ram8 b 1 8 $disk\r
++makedev rootdir/dev/ram9 b 1 9 $disk\r
++makedev rootdir/dev/ram10 b 1 10 $disk\r
++makedev rootdir/dev/ram11 b 1 11 $disk\r
++makedev rootdir/dev/ram12 b 1 12 $disk\r
++makedev rootdir/dev/ram13 b 1 13 $disk\r
++makedev rootdir/dev/ram14 b 1 14 $disk\r
++makedev rootdir/dev/ram15 b 1 15 $disk\r
++\r
++makedev rootdir/dev/mtd0 c 90 0 $mtd\r
++makedev rootdir/dev/mtd1 c 90 2 $mtd\r
++makedev rootdir/dev/mtd2 c 90 4 $mtd\r
++makedev rootdir/dev/mtd3 c 90 6 $mtd\r
++makedev rootdir/dev/mtd4 c 90 8 $mtd\r
++makedev rootdir/dev/mtd5 c 90 10 $mtd\r
++makedev rootdir/dev/mtd6 c 90 12 $mtd\r
++makedev rootdir/dev/mtdblock0 b 31 0 $mtd\r
++makedev rootdir/dev/mtdblock1 b 31 1 $mtd\r
++makedev rootdir/dev/mtdblock2 b 31 2 $mtd\r
++makedev rootdir/dev/mtdblock3 b 31 3 $mtd\r
++makedev rootdir/dev/mtdblock4 b 31 4 $mtd\r
++makedev rootdir/dev/mtdblock5 b 31 5 $mtd\r
++makedev rootdir/dev/mtdblock6 b 31 6 $mtd\r
++makedev rootdir/dev/mtdr0 c 90 1 $mtd\r
++makedev rootdir/dev/mtdr1 c 90 3 $mtd\r
++makedev rootdir/dev/mtdr2 c 90 5 $mtd\r
++makedev rootdir/dev/mtdr3 c 90 7 $mtd\r
++makedev rootdir/dev/mtdr4 c 90 9 $mtd\r
++makedev rootdir/dev/mtdr5 c 90 11 $mtd\r
++makedev rootdir/dev/mtdr6 c 90 13 $mtd\r
++\r
++cd rootdir/dev;ln -sf ram1 ram\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/README linux-2.4.32.new/arch/mips/ar531x/RAMDISK/README\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/README       1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/README   2005-12-24 20:29:42.011325160 +0000\r
+@@ -0,0 +1,40 @@\r
++How to build a ramdisk image for use as a root filesystem with AR531X\r
++\r
++Overview:\r
++In order to boot from a ramdisk root file system image, you will\r
++first create a root directory structure in the "rootdir" directory.\r
++Then run "make" to create a compressed root file system image in\r
++ramdisk.gz.  Finally, copy this image into your kernel source tree\r
++and remake the kernel.  The ramdisk image is then built into the\r
++kernel.  When the kernel starts, it is uncompressed into RAM, and\r
++used as a root file system.\r
++\r
++If you'd like to use a pre-built ramdisk.gz rather than build\r
++one yourself:\r
++  cp arch/mips/ar531x/RAMDISK/ramdisk.gz arch/mips/ramdisk/ramdisk.gz\r
++\r
++Here are the detailed steps to build your own:\r
++\r
++1) Modify Makefile to point KERNEL_SOURCE at your linux source tree.\r
++\r
++2) Copy whatever additional files/directories/links you'd like to\r
++   under rootdir.  Note that you're limited to CONFIG_BLK_DEV_RAM_SIZE\r
++   1KB blocks, as specified in your linux/.config file.\r
++   Examples:\r
++      Copy busybox to rootdir/bin/\r
++        [NOTE: Copy busybox.links to this directory to\r
++        cause the makelinks script to automatically\r
++        set up all of the necessary busybox command links\r
++        in the rootdir/bin directory].\r
++\r
++      Copy any wireless driver modules into rootdir tree\r
++\r
++   You might want to make a copy of the rootdir directory\r
++   before you modify it, just in case you want to get back\r
++   to the original.\r
++\r
++3) LOGIN AS ROOT (e.g. "su") and type "make"\r
++\r
++4) Copy the resulting ramdisk.gz to your linux source tree under\r
++       arch/mips/ramdisk/ramdisk.gz\r
++   (or "make install" will do this step for you)\r
+Binary files linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/bin/busybox and linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/bin/busybox differ\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/fstab linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/fstab\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/fstab    1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/fstab        2005-12-24 20:29:42.063317256 +0000\r
+@@ -0,0 +1 @@\r
++/proc /proc proc defaults 0 0\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/group linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/group\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/group    1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/group        2005-12-24 20:29:42.064317104 +0000\r
+@@ -0,0 +1,18 @@\r
++root:x:0:\r
++wheel:x:10:\r
++bin:x:1:bin,daemon\r
++daemon:x:2:bin,daemon\r
++sys:x:3:bin,adm\r
++adm:x:4:adm,daemon\r
++tty:x:5:\r
++disk:x:6:\r
++lp:x:7:daemon,lp\r
++mem:x:8:\r
++kmem:x:9:\r
++operator:x:11:\r
++uucp:x:14:uucp\r
++dip:x:40:\r
++utmp:x:45:\r
++www:x:63:\r
++nobody:x:65534:\r
++users:x:100:\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/host.conf linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/host.conf\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/host.conf        1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/host.conf    2005-12-24 20:29:42.064317104 +0000\r
+@@ -0,0 +1,2 @@\r
++order hosts,bind\r
++multi on\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/inittab linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/inittab\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/inittab  1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/inittab      2005-12-24 20:29:42.064317104 +0000\r
+@@ -0,0 +1,2 @@\r
++::sysinit:/etc/rc.d/rcS\r
++::respawn:/bin/sh\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/nsswitch.conf linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/nsswitch.conf\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/nsswitch.conf    1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/nsswitch.conf        2005-12-24 20:29:42.065316952 +0000\r
+@@ -0,0 +1,16 @@\r
++# /etc/nsswitch.conf\r
++#\r
++# Name Service Switch configuration file.\r
++#\r
++\r
++passwd:               compat\r
++shadow:               compat\r
++group:                compat\r
++\r
++hosts:                files dns\r
++networks:     files dns\r
++\r
++ethers:               files\r
++protocols:    files\r
++rpc:          files\r
++services:     files\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/passwd linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/passwd\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/passwd   1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/passwd       2005-12-24 20:29:42.065316952 +0000\r
+@@ -0,0 +1,11 @@\r
++root:x:0:0:root:/root:/bin/ash\r
++bin:x:1:1:bin:/bin:/bin/sh\r
++daemon:x:2:2:daemon:/usr/sbin:/bin/sh\r
++adm:x:3:4:adm:/adm:/bin/sh\r
++lp:x:4:7:lp:/var/spool/lpd:/bin/sh\r
++sync:x:5:0:sync:/bin:/bin/sync\r
++shutdown:x:6:11:shutdown:/sbin:/sbin/shutdown\r
++halt:x:7:0:halt:/sbin:/sbin/halt\r
++uucp:x:10:14:uucp:/var/spool/uucp:/bin/sh\r
++operator:x:11:0:Operator:/var:/bin/sh\r
++nobody:x:65534:65534:nobody:/home:/bin/sh\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/rc.d/rcS linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/rc.d/rcS\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/rc.d/rcS 1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/rc.d/rcS     2005-12-24 20:29:42.066316800 +0000\r
+@@ -0,0 +1,17 @@\r
++#!/bin/sh\r
++\r
++mount -a\r
++mount -t jffs2 -o remount +w /\r
++# mount -t ramfs /dev/ram /ramdisk\r
++\r
++echo Load MADWiFi wlan module\r
++insmod ../../lib/modules/2.4.25/net/wlan.o\r
++\r
++echo Load MADWiFi Atheros HAL module\r
++insmod ../../lib/modules/2.4.25/net/ath_hal.o\r
++\r
++echo Load MADWiFi Atheros Driver module\r
++insmod ../../lib/modules/2.4.25/net/ath_lbus.o\r
++\r
++exit\r
++\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/resolv.conf linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/resolv.conf\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/resolv.conf      1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/resolv.conf  2005-12-24 20:29:42.066316800 +0000\r
+@@ -0,0 +1,18 @@\r
++# /etc/resolv.conf - DNS setup file\r
++#\r
++# possible entries are:\r
++#\r
++#       domain <domain>                 Local domain name. If not present, the\r
++#                                       gethostbyname syscall is used to\r
++#                                       determine the local domain name.\r
++#\r
++#       search <list_of_domains>        Search list for hostname lookup.\r
++#                                       The search list is normally determined\r
++#                                       from the local domain name but it\r
++#                                       can be set to a list of domains.\r
++#\r
++#       nameserver <ip_addr>            Define which server to contact\r
++#                                       for DNS lookups. If there are\r
++#                                       multiple nameserver lines (Max=3),\r
++#                                       they are queried in the listed order.\r
++#\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/securetty linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/securetty\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/securetty        1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/securetty    2005-12-24 20:29:42.066316800 +0000\r
+@@ -0,0 +1,12 @@\r
++tty1\r
++tty2\r
++tty3\r
++tty4\r
++tty5\r
++tty6\r
++tty7\r
++tty8\r
++ttyS0\r
++ttyS1\r
++ttyS2\r
++ttyS3\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/services linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/services\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/services 1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/services     2005-12-24 20:29:42.066316800 +0000\r
+@@ -0,0 +1,193 @@\r
++#     $NetBSD: services,v 1.18 1996/03/26 00:07:58 mrg Exp $\r
++#\r
++# Network services, Internet style\r
++#\r
++# Note that it is presently the policy of IANA to assign a single well-known\r
++# port number for both TCP and UDP; hence, most entries here have two entries\r
++# even if the protocol doesn't support UDP operations.\r
++# Updated from RFC 1340, ``Assigned Numbers'' (July 1992).  Not all ports\r
++# are included, only the more common ones.\r
++#\r
++#     from: @(#)services      5.8 (Berkeley) 5/9/91\r
++#\r
++tcpmux                1/tcp           # TCP port service multiplexer\r
++echo          7/tcp\r
++echo          7/udp\r
++discard               9/tcp           sink null\r
++discard               9/udp           sink null\r
++systat                11/tcp          users\r
++daytime               13/tcp\r
++daytime               13/udp\r
++netstat               15/tcp\r
++qotd          17/tcp          quote\r
++msp           18/tcp          # message send protocol\r
++msp           18/udp          # message send protocol\r
++chargen               19/tcp          ttytst source\r
++chargen               19/udp          ttytst source\r
++ftp-data      20/tcp          # default ftp data port\r
++ftp           21/tcp\r
++ssh           22/tcp\r
++ssh           22/udp\r
++telnet                23/tcp\r
++# 24 - private\r
++smtp          25/tcp          mail\r
++# 26 - unassigned\r
++time          37/tcp          timserver\r
++time          37/udp          timserver\r
++rlp           39/udp          resource        # resource location\r
++nameserver    42/tcp          name            # IEN 116\r
++whois         43/tcp          nicname\r
++domain                53/tcp          nameserver      # name-domain server\r
++domain                53/udp          nameserver\r
++mtp           57/tcp                          # deprecated\r
++bootps                67/tcp          # BOOTP server\r
++bootps                67/udp\r
++bootpc                68/tcp          # BOOTP client\r
++bootpc                68/udp\r
++tftp          69/udp\r
++gopher                70/tcp          # Internet Gopher\r
++gopher                70/udp\r
++rje           77/tcp          netrjs\r
++finger                79/tcp\r
++www           80/tcp          http    # WorldWideWeb HTTP\r
++www           80/udp                  # HyperText Transfer Protocol\r
++link          87/tcp          ttylink\r
++kerberos      88/tcp          krb5    # Kerberos v5\r
++kerberos      88/udp\r
++supdup                95/tcp\r
++# 100 - reserved\r
++hostnames     101/tcp         hostname        # usually from sri-nic\r
++iso-tsap      102/tcp         tsap            # part of ISODE.\r
++csnet-ns      105/tcp         cso-ns  # also used by CSO name server\r
++csnet-ns      105/udp         cso-ns\r
++rtelnet               107/tcp         # Remote Telnet\r
++rtelnet               107/udp\r
++pop2          109/tcp         pop-2 postoffice        # POP version 2\r
++pop2          109/udp\r
++pop3          110/tcp         pop-3 # POP version 3\r
++pop3          110/udp\r
++sunrpc                111/tcp\r
++sunrpc                111/udp\r
++auth          113/tcp         authentication tap ident\r
++sftp          115/tcp\r
++uucp-path     117/tcp\r
++nntp          119/tcp         readnews untp   # USENET News Transfer Protocol\r
++ntp           123/tcp\r
++ntp           123/udp                         # Network Time Protocol\r
++netbios-ns    137/tcp                         # NETBIOS Name Service\r
++netbios-ns    137/udp\r
++netbios-dgm   138/tcp                         # NETBIOS Datagram Service\r
++netbios-dgm   138/udp\r
++netbios-ssn   139/tcp                         # NETBIOS session service\r
++netbios-ssn   139/udp\r
++imap2         143/tcp         imap            # Interim Mail Access Proto v2\r
++imap2         143/udp\r
++snmp          161/udp                         # Simple Net Mgmt Proto\r
++snmp-trap     162/udp         snmptrap        # Traps for SNMP\r
++cmip-man      163/tcp                         # ISO mgmt over IP (CMOT)\r
++cmip-man      163/udp\r
++cmip-agent    164/tcp\r
++cmip-agent    164/udp\r
++xdmcp         177/tcp                         # X Display Mgr. Control Proto\r
++xdmcp         177/udp\r
++nextstep      178/tcp         NeXTStep NextStep       # NeXTStep window\r
++nextstep      178/udp         NeXTStep NextStep       # server\r
++bgp           179/tcp                         # Border Gateway Proto.\r
++bgp           179/udp\r
++prospero      191/tcp                         # Cliff Neuman's Prospero\r
++prospero      191/udp\r
++irc           194/tcp                         # Internet Relay Chat\r
++irc           194/udp\r
++smux          199/tcp                         # SNMP Unix Multiplexer\r
++smux          199/udp\r
++at-rtmp               201/tcp                         # AppleTalk routing\r
++at-rtmp               201/udp\r
++at-nbp                202/tcp                         # AppleTalk name binding\r
++at-nbp                202/udp\r
++at-echo               204/tcp                         # AppleTalk echo\r
++at-echo               204/udp\r
++at-zis                206/tcp                         # AppleTalk zone information\r
++at-zis                206/udp\r
++z3950         210/tcp         wais            # NISO Z39.50 database\r
++z3950         210/udp         wais\r
++ipx           213/tcp                         # IPX\r
++ipx           213/udp\r
++imap3         220/tcp                         # Interactive Mail Access\r
++imap3         220/udp                         # Protocol v3\r
++ulistserv     372/tcp                         # UNIX Listserv\r
++ulistserv     372/udp\r
++#\r
++# UNIX specific services\r
++#\r
++exec          512/tcp\r
++biff          512/udp         comsat\r
++login         513/tcp\r
++who           513/udp         whod\r
++shell         514/tcp         cmd             # no passwords used\r
++syslog                514/udp\r
++printer               515/tcp         spooler         # line printer spooler\r
++talk          517/udp\r
++ntalk         518/udp\r
++route         520/udp         router routed   # RIP\r
++timed         525/udp         timeserver\r
++tempo         526/tcp         newdate\r
++courier               530/tcp         rpc\r
++conference    531/tcp         chat\r
++netnews               532/tcp         readnews\r
++netwall               533/udp                         # -for emergency broadcasts\r
++uucp          540/tcp         uucpd           # uucp daemon\r
++remotefs      556/tcp         rfs_server rfs  # Brunhoff remote filesystem\r
++#\r
++webster               765/tcp                         # Network dictionary\r
++webster               765/udp\r
++# temporary entry (not officially registered by the Samba Team!)\r
++swat          901/tcp         # Samba Web Administration Tool\r
++#\r
++# From ``Assigned Numbers'':\r
++#\r
++#> The Registered Ports are not controlled by the IANA and on most systems\r
++#> can be used by ordinary user processes or programs executed by ordinary\r
++#> users.\r
++#\r
++#> Ports are used in the TCP [45,106] to name the ends of logical\r
++#> connections which carry long term conversations.  For the purpose of\r
++#> providing services to unknown callers, a service contact port is\r
++#> defined.  This list specifies the port used by the server process as its\r
++#> contact port.  While the IANA can not control uses of these ports it\r
++#> does register or list uses of these ports as a convienence to the\r
++#> community.\r
++#\r
++ingreslock    1524/tcp\r
++ingreslock    1524/udp\r
++prospero-np   1525/tcp                # Prospero non-privileged\r
++prospero-np   1525/udp\r
++rfe           5002/tcp                # Radio Free Ethernet\r
++rfe           5002/udp                # Actually uses UDP only\r
++#\r
++#\r
++# Kerberos (Project Athena/MIT) services\r
++# Note that these are for Kerberos v4, and are unofficial.\r
++#\r
++klogin                543/tcp                 # Kerberos `rlogin'\r
++kshell                544/tcp         krcmd   # Kerberos `rsh'\r
++kerberos-adm  749/tcp                 # Kerberos `kadmin' (v5)\r
++kerberos4     750/udp         kdc     # Kerberos (server) udp\r
++kerberos4     750/tcp         kdc     # Kerberos (server) tcp\r
++kerberos-master       751/udp                 # Kerberos admin server udp\r
++kerberos-master       751/tcp                 # Kerberos admin server tcp\r
++krbupdate     760/tcp         kreg    # BSD Kerberos registration\r
++kpasswd               761/tcp         kpwd    # BSD Kerberos `passwd'\r
++eklogin               2105/tcp                # Kerberos encrypted `rlogin'\r
++#\r
++# Unofficial but necessary (for NetBSD) services\r
++#\r
++supfilesrv    871/tcp                 # SUP server\r
++supfiledbg    1127/tcp                # SUP debugging\r
++#\r
++# AppleTalk DDP entries (DDP: Datagram Delivery Protocol)\r
++#\r
++rtmp          1/ddp                   # Routing Table Maintenance Protocol\r
++nbp           2/ddp                   # Name Binding Protocol\r
++echo          4/ddp                   # AppleTalk Echo Protocol\r
++zip           6/ddp                   # Zone Information Protocol\r
++\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/shadow linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/shadow\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/etc/shadow   1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/etc/shadow       2005-12-24 20:29:42.067316648 +0000\r
+@@ -0,0 +1,11 @@\r
++root::10933:0:99999:7:::\r
++bin:*:10933:0:99999:7:::\r
++daemon:*:10933:0:99999:7:::\r
++adm:*:10933:0:99999:7:::\r
++lp:*:10933:0:99999:7:::\r
++sync:*:10933:0:99999:7:::\r
++shutdown:*:10933:0:99999:7:::\r
++halt:*:10933:0:99999:7:::\r
++uucp:*:10933:0:99999:7:::\r
++operator:*:10933:0:99999:7:::\r
++nobody:*:10933:0:99999:7:::\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.generic_string linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.generic_string\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.generic_string    1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.generic_string        2005-12-24 20:29:42.071316040 +0000\r
+@@ -0,0 +1 @@\r
++# module             id=string\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.ieee1394map linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.ieee1394map\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.ieee1394map       1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.ieee1394map   2005-12-24 20:29:42.071316040 +0000\r
+@@ -0,0 +1 @@\r
++# ieee1394 module    match_flags vendor_id model_id specifier_id version\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.isapnpmap linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.isapnpmap\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.isapnpmap 1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.isapnpmap     2005-12-24 20:29:42.079314824 +0000\r
+@@ -0,0 +1 @@\r
++# isapnp module      cardvendor carddevice driver_data vendor     function   ...\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.parportmap linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.parportmap\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.parportmap        1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.parportmap    2005-12-24 20:29:42.079314824 +0000\r
+@@ -0,0 +1 @@\r
++# module             pattern\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.pcimap linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.pcimap\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.pcimap    1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.pcimap        2005-12-24 20:29:42.080314672 +0000\r
+@@ -0,0 +1 @@\r
++# pci module         vendor     device     subvendor  subdevice  class      class_mask driver_data\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.pnpbiosmap linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.pnpbiosmap\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.pnpbiosmap        1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.pnpbiosmap    2005-12-24 20:29:42.080314672 +0000\r
+@@ -0,0 +1 @@\r
++# module             id\r
+diff -urN linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.usbmap linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.usbmap\r
+--- linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.usbmap    1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/lib/modules/2.4.25/modules.usbmap        2005-12-24 20:29:42.080314672 +0000\r
+@@ -0,0 +1 @@\r
++# usb module         match_flags idVendor idProduct bcdDevice_lo bcdDevice_hi bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass bInterfaceSubClass bInterfaceProtocol driver_info\r
+Binary files linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/sbin/iwconfig and linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/sbin/iwconfig differ\r
+Binary files linux-2.4.32/arch/mips/ar531x/RAMDISK/rootdir/sbin/iwpriv and linux-2.4.32.new/arch/mips/ar531x/RAMDISK/rootdir/sbin/iwpriv differ\r
+diff -urN linux-2.4.32/arch/mips/ar531x/README linux-2.4.32.new/arch/mips/ar531x/README\r
+--- linux-2.4.32/arch/mips/ar531x/README       1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/README   2005-12-24 20:29:42.101311480 +0000\r
+@@ -0,0 +1,68 @@\r
++Basic information for the AR531X Board Support Package\r
++\r
++This directory contains the "LBSP" -- Linux Board Support Package --\r
++for Linux on the Atheros AR531X Wireless System-On-a-Chip.  It is intended\r
++primarily as a building block for wireless products.  At this time, the\r
++AR531X Linux BSP is experimental code, and is actively UNDER CONSTRUCTION.\r
++\r
++Some components that are supported by this LBSP along with a standard 2.4\r
++Linux MIPS kernel include\r
++  R4Kc CPU\r
++  instruction and data caches\r
++  SDRAM\r
++  flash (Macronix, AMD, STS, etc.)\r
++  16550 serial port\r
++  ethernet MACs\r
++  ethernet PHY or PHY Switch (RealTek, Kendin, Marvell)\r
++  General-Purpose I/O pins\r
++  kernel debugging with kgdb\r
++\r
++This LBSP code does NOT include drivers for the wireless components of the\r
++chip/boards!  Drivers for those components may be distributed separately.\r
++In particular, the MADWiFi project under SourceForge supports (not yet!)\r
++wireless functions on the AR531X chipset.  See\r
++   http://www.sourceforge.net/projects/madwifi\r
++\r
++Files included in this BSP:\r
++ae531xlnx.c      - Linux-specific portions of the ethernet driver\r
++ae531xmac.c      - OS-independent AR531X ethernet MAC code\r
++ae531xmac.h      - OS-independent AR531X ethernet MAC software definitions\r
++ae531xreg.h      - OS-independent AR531X ethernet MAC hardware definitions\r
++ar531x.h         - OS-independent AR531X system hardware definitions\r
++ar531xlnx.h      - Linux-specific AR531X system definitions and externs\r
++defconfig-ar531x - Default Linux configuration file\r
++intr_recv.S      - Linux interrupt "glue" code\r
++ar531xirq.c      - Linux Interrupt Request management\r
++Makefile         - Linux makefile\r
++mvPhy.c          - OS-independent ethernet PHY code for Marvell Switch\r
++mvPhy.h          - OS-independent ethernet PHY definitions for Marvell Switch\r
++ar531xprom.c     - Linux prom "glue" code\r
++ar531xsetup.c    - Linux startup code\r
++ar531xdbg_io.c   - Support for kgdb-based debugging and for EARLY_PRINTK_HACK\r
++ar531xproc.c     - Pseudo-device driver for /proc/ar531x device\r
++ar531xgpio.c     - Support for General Purpose I/O pins\r
++ar531xwmacsl.c   - Wireless MAC Support Layer\r
++\r
++Additional files, distributed with the BSP:\r
++README           - This file\r
++README.BUILD     - Instructions for building a linux kernel from source\r
++README.EXECUTE   - Instructions for testing your linux kernel\r
++README.RAMDISK   - Instructions for building a root ramdisk image\r
++\r
++ramdisk.gz       - A binary ramdisk image, suitable for use with AR531X.\r
++DIFFS            - Directory that contains "patch" files (See README.BUILD)\r
++\r
++\r
++There are several ways to boot a vmlinux image on an AR531X board:\r
++  -You can boot in over ethernet from the vxWorks bootrom, which is preloaded\r
++   on all Atheros boards\r
++  -You can use an ICE (e.g. VisionICE) to load the vmlinux image.  You will\r
++   need appropriate register initialization (e.g. AP30.ini file)\r
++  -You can use the eCos RedBoot bootrom loader.  This is a full-featured\r
++   bootrom which as been ported to AR531x.  It can boot vmlinux over ethernet\r
++   or from flash.  Source code is available from Atheros.\r
++\r
++Please send comments, corrections, complaints, criticisms, suggestions,\r
++enhancements, requests, or any other reasonable communications regarding\r
++this effort, to "linux@atheros.com".  Your email will be received by a\r
++couple of engineers, and redirected as appropriate.\r
+diff -urN linux-2.4.32/arch/mips/ar531x/README.BUILD linux-2.4.32.new/arch/mips/ar531x/README.BUILD\r
+--- linux-2.4.32/arch/mips/ar531x/README.BUILD 1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/README.BUILD     2005-12-24 20:29:42.101311480 +0000\r
+@@ -0,0 +1,47 @@\r
++       How to BUILD a linux kernel for an AR531X system\r
++\r
++It is expected that you will build Linux on an existing Linux system, which \r
++has all of the standard Linux tools.\r
++\r
++01) Obtain a MIPS BigEndian ELF gcc-compatible toolchain.  For example,\r
++    if you're cross-compiling on a x86 Linux system, you could use:\r
++    ftp://ftp.mips.com/pub/tools/software/sde-for-linux/sdelinux-5.01-4eb.i386.rpm\r
++\r
++02) Obtain the latest working MIPS Linux kernel\r
++    cvs -d :pserver:cvs@ftp.linux-mips.org:/home/cvs login    (password "cvs")\r
++    cvs -d :pserver:cvs@ftp.linux-mips.org:/home/cvs co -r linux_2_4 linux\r
++\r
++    Now "cd linux".  The remainder of these instructions assume\r
++    that you are in the linux directory.\r
++\r
++03) Place the contents of this directory at arch/mips/ar531x.\r
++\r
++04) Use the patch command to patch generic linux files according\r
++    to the DIFFS directory\r
++    for i in arch/mips/ar531x/DIFFS/*.diff\r
++    do\r
++       patch -p1 < $i\r
++    done\r
++    NOTE: This version of the AR531X Linux BSP was tested with\r
++    MIPS Linux 2.4.22 as of 11/14/03.  If you use a different\r
++    (e.g. more recent) version of Linux source, you may need to\r
++    resolve some minor patch and compilation issues.\r
++\r
++05) Set up a RAMDISK image.\r
++    See the instructions in README.RAMDISK.\r
++\r
++06) Set up a linux configuration using ar531x/defconfig-ar531x.\r
++    cp arch/mips/ar531x/defconfig-ar531x .config\r
++    make oldconfig       (answer all questions that are asked)\r
++    NOTE: For development/debug purposes, you may want to\r
++    enable CONFIG_RUNTIME_DEBUG and CONFIG_KGDB.\r
++\r
++07) Make dependencies.\r
++    make dep\r
++\r
++08) Build the linux kernel\r
++    make\r
++\r
++09) The linux image you just built is in vmlinux.\r
++    See instructions in README.EXECUTE to run your vmlinux\r
++    image on an AP531X-based board.\r
+diff -urN linux-2.4.32/arch/mips/ar531x/README.EXECUTE linux-2.4.32.new/arch/mips/ar531x/README.EXECUTE\r
+--- linux-2.4.32/arch/mips/ar531x/README.EXECUTE       1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/README.EXECUTE   2005-12-24 20:29:42.101311480 +0000\r
+@@ -0,0 +1,23 @@\r
++      How to EXECUTE a linux image on an AR531X system\r
++\r
++There are currently three ways to run you vmlinux image:\r
++  1) Load it using the vxWorks bootrom that is supplied with the board.\r
++     You can load it over ethernet or from the TFFS file system, if you\r
++     have sufficient flash to store the image.\r
++  2) Load it using an ICE (e.g. VisionICE).\r
++  3) Use a bootrom loader, such as eCos RedBoot.\r
++\r
++After you have booted linux:\r
++  By default, the root filesystem on ramdisk is read-only.\r
++  To make it writable, use "mount -o remount w /".\r
++\r
++  The user-level commands are slightly non-standard, as they\r
++  are based on "busybox".\r
++\r
++  The "wget" command is included.  You can use wget to fetch\r
++  files from any ftp server.  So, for instance, you can fetch\r
++  a kernel module and then "insmod" it.\r
++\r
++Note that the standard source-level kernel debugger, kgdb, works well\r
++over the serial line with this port.  We use kgdb and the kgdb_demux perl\r
++script -- available over the www -- for debugging.\r
+diff -urN linux-2.4.32/arch/mips/ar531x/README.VERSION linux-2.4.32.new/arch/mips/ar531x/README.VERSION\r
+--- linux-2.4.32/arch/mips/ar531x/README.VERSION       1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/arch/mips/ar531x/README.VERSION   2005-12-24 20:29:42.101311480 +0000\r
+@@ -0,0 +1 @@\r
++Source release last modified: 12/16/03\r
+diff -urN linux-2.4.32/arch/mips/config-shared.in linux-2.4.32.new/arch/mips/config-shared.in\r
+--- linux-2.4.32/arch/mips/config-shared.in    2005-12-24 16:11:21.000000000 +0000\r
++++ linux-2.4.32.new/arch/mips/config-shared.in        2005-12-24 21:33:42.804435856 +0000\r
+@@ -31,6 +31,7 @@\r
+ dep_bool 'Support for Alchemy PB1000 board' CONFIG_MIPS_PB1000 $CONFIG_MIPS32\r
+ dep_bool 'Support for Alchemy PB1100 board' CONFIG_MIPS_PB1100 $CONFIG_MIPS32\r
+ dep_bool 'Support for Alchemy PB1500 board' CONFIG_MIPS_PB1500 $CONFIG_MIPS32\r
++dep_bool 'Support for Atheros AR5312/AR2312 WiSoC (EXPERIMENTAL)' CONFIG_AR531X $CONFIG_AR531X $CONFIG_EXPERIMENTAL\r
+ dep_bool 'Support for Alchemy PB1550 board' CONFIG_MIPS_PB1550 $CONFIG_MIPS32\r
+ dep_bool 'Support for Alchemy PB1200 board' CONFIG_MIPS_PB1200 $CONFIG_MIPS32\r
+ dep_bool 'Support for Alchemy Hydrogen3 board' CONFIG_MIPS_HYDROGEN3 $CONFIG_MIPS32\r
+@@ -196,7 +197,7 @@\r
+    bool '   Support for ZBbus profiling' CONFIG_SIBYTE_TBPROF\r
\r
+    if [ "$CONFIG_SIBYTE_SWARM" = "y" -o \\r
+-        "$CONFIG_SIBYTE_LITTLESUR" = "y" -o \\r
++O5B        "$CONFIG_SIBYTE_LITTLESUR" = "y" -o \\r
+         "$CONFIG_SIBYTE_PTSWARM" = "y" -o \\r
+         "$CONFIG_SIBYTE_CARMEL" = "y" ]; then\r
+       define_bool CONFIG_SIBYTE_GENBUS_IDE y\r
+@@ -239,6 +240,43 @@\r
+    define_bool CONFIG_NONCOHERENT_IO y\r
+    define_bool CONFIG_PC_KEYB y\r
+ fi\r
++if [ "$CONFIG_AR531X" = "y" ]; then\r
++   define_bool CONFIG_IRQ_CPU y\r
++   define_bool CONFIG_CPU_VR4100 y\r
++   define_bool CONFIG_SERIAL y\r
++   define_bool CONFIG_NEW_IRQ y\r
++   define_bool CONFIG_NEW_TIME_C y\r
++   define_bool CONFIG_AR5312\r
++   define_bool CONFIG_NONCOHERENT_IO y\r
++   bool 'Enable early printk hack' CONFIG_EARLY_PRINTK_HACK\r
++   define_bool CONFIG_SCSI n\r
++   mainmenu_option next_comment\r
++   comment 'Board selection'\r
++      choice 'Board type' \\r
++         "UNKNOWN CONFIG_APUNKNOWN \\r
++        AP30 CONFIG_AP30 \\r
++          AP31 CONFIG_AP31 \\r
++        AP33 CONFIG_AP33 \\r
++        AP38 CONFIG_AP38 \\r
++        AP43 CONFIG_AP43 \\r
++        AP48 CONFIG_AP48" AP30\r
++   if [ "$CONFIG_AP30" = "y" ]; then\r
++      define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 2\r
++   fi\r
++   if [ "$CONFIG_AP33" = "y" ]; then\r
++      define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1\r
++   fi\r
++   if [ "$CONFIG_AP38" = "y" ]; then\r
++      define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1\r
++   fi\r
++   if [ "$CONFIG_AP43" = "y" ]; then\r
++      define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1\r
++   fi\r
++   if [ "$CONFIG_AP48" = "y" ]; then\r
++      define_int CONFIG_MTD_PHYSMAP_BUSWIDTH 1\r
++   fi\r
++   endmenu\r
++fi\r
+ if [ "$CONFIG_CASIO_E55" = "y" ]; then\r
+    define_bool CONFIG_IRQ_CPU y\r
+    define_bool CONFIG_NONCOHERENT_IO y\r
+diff -urN linux-2.4.32/arch/mips/kernel/setup.c linux-2.4.32.new/arch/mips/kernel/setup.c\r
+--- linux-2.4.32/arch/mips/kernel/setup.c      2005-12-24 16:08:53.000000000 +0000\r
++++ linux-2.4.32.new/arch/mips/kernel/setup.c  2005-12-24 21:28:51.779678344 +0000\r
+@@ -494,6 +494,7 @@\r
+       void hp_setup(void);\r
+       void au1x00_setup(void);\r
+       void frame_info_init(void);\r
++      void ar531x_setup(void);\r
\r
+       frame_info_init();\r
+ #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)\r
+@@ -691,6 +692,12 @@\r
+                 pmc_yosemite_setup();\r
+                 break;\r
+ #endif\r
++\r
++#ifdef CONFIG_AR531X\r
++      case MACH_GROUP_AR531X:\r
++              ar531x_setup();\r
++              break;\r
++#endif\r
+       default:\r
+               panic("Unsupported architecture");\r
+       }\r
+diff -urN linux-2.4.32/arch/mips/Makefile linux-2.4.32.new/arch/mips/Makefile\r
+--- linux-2.4.32/arch/mips/Makefile    2005-12-24 16:09:51.000000000 +0000\r
++++ linux-2.4.32.new/arch/mips/Makefile        2005-12-24 21:28:51.780678192 +0000\r
+@@ -725,6 +725,12 @@\r
+ LOADADDR      += 0x80020000\r
+ endif\r
\r
++ifdef CONFIG_AR531X\r
++SUBDIRS       += arch/mips/ar531x\r
++LIBS          += arch/mips/ar531x/ar531x.o\r
++LOADADDR      += 0x80002000\r
++endif\r
++\r
+ #\r
+ # Choosing incompatible machines durings configuration will result in\r
+ # error messages during linking.  Select a default linkscript if\r
+diff -urN linux-2.4.32/drivers/mtd/chips/cfi_cmdset_0002.c linux-2.4.32.new/drivers/mtd/chips/cfi_cmdset_0002.c\r
+--- linux-2.4.32/drivers/mtd/chips/cfi_cmdset_0002.c   2004-11-17 11:54:21.000000000 +0000\r
++++ linux-2.4.32.new/drivers/mtd/chips/cfi_cmdset_0002.c       2005-12-24 21:28:51.795675912 +0000\r
+@@ -510,7 +510,7 @@\r
+          or tells us why it failed. */        \r
+       dq6 = CMD(1<<6);\r
+       dq5 = CMD(1<<5);\r
+-      timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */\r
++      timeo = jiffies + (HZ/1000) + 1; /* setting timeout to 1ms for now */\r
+               \r
+       oldstatus = cfi_read(map, adr);\r
+       status = cfi_read(map, adr);\r
+@@ -535,12 +535,14 @@\r
+               if( (status & dq5) == dq5 ) {\r
+                       /* When DQ5 raises, we must check once again\r
+                          if DQ6 is toggling.  If not, the erase has been\r
+-                         completed OK.  If not, reset chip. */\r
++                         completed OK.  But if so, reset chip. */\r
+                       oldstatus = cfi_read(map, adr);\r
+                       status = cfi_read(map, adr);\r
+                   \r
+                       if ( (oldstatus & 0x00FF) == (status & 0x00FF) ) {\r
++#if 0\r
+                               printk(KERN_WARNING "Warning: DQ5 raised while program operation was in progress, however operation completed OK\n" );\r
++#endif\r
+                       } else { \r
+                               /* DQ5 is active so we can do a reset and stop the erase */\r
+                               cfi_write(map, CMD(0xF0), chip->start);\r
+diff -urN linux-2.4.32/drivers/mtd/chips/jedec_probe.c linux-2.4.32.new/drivers/mtd/chips/jedec_probe.c\r
+--- linux-2.4.32/drivers/mtd/chips/jedec_probe.c       2003-06-13 15:51:34.000000000 +0100\r
++++ linux-2.4.32.new/drivers/mtd/chips/jedec_probe.c   2005-12-24 21:28:51.797675608 +0000\r
+@@ -900,7 +900,16 @@\r
+               NumEraseRegions: 1,\r
+               regions: {ERASEINFO(0x01000,256),\r
+               }\r
+-      } \r
++      }, {\r
++              mfr_id: MANUFACTURER_SST,\r
++              dev_id: SST39LF160,\r
++              name: "SST 39LF160",\r
++              DevSize: SIZE_2MiB,\r
++              CmdSet: P_ID_AMD_STD,\r
++              NumEraseRegions: 1,\r
++              regions: {ERASEINFO(0x01000,512),\r
++              }\r
++        }\r
+ };\r
\r
\r
+diff -urN linux-2.4.32/drivers/mtd/Config.in linux-2.4.32.new/drivers/mtd/Config.in\r
+--- linux-2.4.32/drivers/mtd/Config.in 2003-06-13 15:51:34.000000000 +0100\r
++++ linux-2.4.32.new/drivers/mtd/Config.in     2005-12-24 21:28:51.803674696 +0000\r
+@@ -14,6 +14,9 @@\r
+    dep_tristate '  MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD\r
+    dep_tristate '  MTD concatenating support' CONFIG_MTD_CONCAT $CONFIG_MTD\r
+    dep_tristate '  RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS\r
++   if [ "$CONFIG_MTD_END_RESERVED" != "" ]; then\r
++      define_int CONFIG_MTD_END_RESERVED $CONFIG_MTD_END_RESERVED\r
++   fi\r
+    dep_tristate '  Command line partition table parsing' CONFIG_MTD_CMDLINE_PARTS $CONFIG_MTD_PARTITIONS\r
+    if [ "$CONFIG_ARM" = "y" ]; then\r
+       dep_tristate '  ARM Firmware Suite partition parsing' CONFIG_MTD_AFS_PARTS $CONFIG_MTD_PARTITIONS\r
+diff -urN linux-2.4.32/drivers/mtd/maps/physmap.c linux-2.4.32.new/drivers/mtd/maps/physmap.c\r
+--- linux-2.4.32/drivers/mtd/maps/physmap.c    2003-06-13 15:51:34.000000000 +0100\r
++++ linux-2.4.32.new/drivers/mtd/maps/physmap.c        2005-12-24 21:28:51.811673480 +0000\r
+@@ -80,12 +80,18 @@\r
+ };\r
\r
+ #ifdef CONFIG_MTD_PARTITIONS\r
+-#ifdef CONFIG_MTD_CMDLINE_PARTS\r
++#if defined(CONFIG_MTD_CMDLINE_PARTS) || defined(CONFIG_MTD_REDBOOT_PARTS)\r
+ static struct mtd_partition *mtd_parts = 0;\r
+ static int                   mtd_parts_nb = 0;\r
+ #else\r
+ static struct mtd_partition physmap_partitions[] = {\r
+ /* Put your own partition definitions here */\r
++    {\r
++        name:   "rootfs",\r
++        size:   0x000e0000,\r
++        offset: 0x000f0000,\r
++        /* Allow file system to be mounted for writing */\r
++    }\r
+ #if 0\r
+       {\r
+               name:           "bootROM",\r
+@@ -138,6 +144,22 @@\r
\r
+               add_mtd_device(mymtd);\r
+ #ifdef CONFIG_MTD_PARTITIONS\r
++#ifdef CONFIG_MTD_REDBOOT_PARTS\r
++                {\r
++                    extern int parse_redboot_partitions(struct mtd_info *master,\r
++                                        struct mtd_partition **pparts);\r
++\r
++                    struct mtd_partition *rb_parts = 0;\r
++                    int rb_parts_nb = 0;\r
++\r
++                  rb_parts_nb = parse_redboot_partitions(mymtd, &rb_parts);\r
++                  if (rb_parts_nb > 0) {\r
++                        printk(KERN_NOTICE\r
++                               "Using redboot flash partitioning");\r
++                      add_mtd_partitions (mymtd, rb_parts, rb_parts_nb);\r
++                  }\r
++                }\r
++#endif\r
+ #ifdef CONFIG_MTD_CMDLINE_PARTS\r
+               mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, \r
+                                                       "phys");\r
+@@ -147,7 +169,8 @@\r
+                              "Using command line partition definition\n");\r
+                       add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb);\r
+               }\r
+-#else\r
++#endif\r
++#if !defined(CONFIG_MTD_CMDLINE_PARTS) && !defined(CONFIG_MTD_REDBOOT_PARTS)\r
+               if (NUM_PARTITIONS != 0) \r
+               {\r
+                       printk(KERN_NOTICE \r
+diff -urN linux-2.4.32/drivers/mtd/redboot.c linux-2.4.32.new/drivers/mtd/redboot.c\r
+--- linux-2.4.32/drivers/mtd/redboot.c 2001-11-09 22:01:22.000000000 +0000\r
++++ linux-2.4.32.new/drivers/mtd/redboot.c     2005-12-24 21:28:51.821671960 +0000\r
+@@ -51,8 +51,14 @@\r
+               return -ENOMEM;\r
\r
+       /* Read the start of the last erase block */\r
+-      ret = master->read(master, master->size - master->erasesize,\r
++        {\r
++        u_int32_t part_table_start = master->size - master->erasesize;\r
++#if defined(CONFIG_MTD_END_RESERVED)\r
++        part_table_start -= CONFIG_MTD_END_RESERVED;\r
++#endif\r
++      ret = master->read(master, part_table_start,\r
+                          PAGE_SIZE, &retlen, (void *)buf);\r
++        }\r
\r
+       if (ret)\r
+               goto out;\r
+diff -urN linux-2.4.32/drivers/net/Config.in linux-2.4.32.new/drivers/net/Config.in\r
+--- linux-2.4.32/drivers/net/Config.in 2005-12-24 16:16:53.000000000 +0000\r
++++ linux-2.4.32.new/drivers/net/Config.in     2005-12-24 21:28:51.856666640 +0000\r
+@@ -30,6 +30,8 @@\r
+ comment 'Ethernet (10 or 100Mbit)'\r
+ bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET\r
+ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then\r
++   define_bool CONFIG_VENETDEV n\r
++   define_bool CONFIG_MARVELL_ENET_PHY y\r
+    if [ "$CONFIG_ARM" = "y" ]; then  \r
+       dep_bool '  ARM EBSA110 AM79C961A support' CONFIG_ARM_AM79C961A $CONFIG_ARCH_EBSA110\r
+       tristate '  Cirrus Logic CS8900A support' CONFIG_ARM_CIRRUS\r
+diff -urN linux-2.4.32/drivers/net/wireless/Config.in linux-2.4.32.new/drivers/net/wireless/Config.in\r
+--- linux-2.4.32/drivers/net/wireless/Config.in        2004-11-17 11:54:21.000000000 +0000\r
++++ linux-2.4.32.new/drivers/net/wireless/Config.in    2005-12-24 21:28:51.898660256 +0000\r
+@@ -38,7 +38,8 @@\r
\r
+ # yes, this works even when no drivers are selected\r
+ if [ "$CONFIG_ISA" = "y" -o "$CONFIG_PCI" = "y" -o \\r
+-     "$CONFIG_ALL_PPC" = "y" -o "$CONFIG_PCMCIA" != "n" ]; then\r
++     "$CONFIG_ALL_PPC" = "y" -o "$CONFIG_PCMCIA" != "n" -o \\r
++     "$CONFIG_NET_WIRELESS" = "y" ]; then\r
+    define_bool CONFIG_NET_WIRELESS y\r
+ else\r
+    define_bool CONFIG_NET_WIRELESS n\r
+diff -urN linux-2.4.32/include/asm-mips/atheros/ar531xbsp.h linux-2.4.32.new/include/asm-mips/atheros/ar531xbsp.h\r
+--- linux-2.4.32/include/asm-mips/atheros/ar531xbsp.h  1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new/include/asm-mips/atheros/ar531xbsp.h      2005-12-24 20:29:06.898663096 +0000\r
+@@ -0,0 +1,16 @@\r
++#ifndef __ASM_ATHEROS_BSP_SUPPORT_H\r
++#define __ASM_ATHEROS_BSP_SUPPORT_H\r
++/*\r
++ * These are definitions and functions provided by the bsp to support the\r
++ * AR5312 WiSoC running LSDK.  For different BSP implementations, different\r
++ * BSP functions will be needed.\r
++ */\r
++\r
++extern unsigned int ar531x_sys_frequency(void);\r
++\r
++#ifdef CONFIG_KGDB\r
++extern  void kgdbInit(void);\r
++extern int kgdbEnabled(void);\r
++#endif\r
++\r
++#endif /* __ASM_ATHEROS_BSP_SUPPORT_H */\r
+diff -urN linux-2.4.32/include/asm-mips/bootinfo.h linux-2.4.32.new/include/asm-mips/bootinfo.h\r
+--- linux-2.4.32/include/asm-mips/bootinfo.h   2005-12-24 16:08:53.000000000 +0000\r
++++ linux-2.4.32.new/include/asm-mips/bootinfo.h       2005-12-24 21:28:51.899660104 +0000\r
+@@ -37,6 +37,7 @@\r
+ #define MACH_GROUP_HP_LJ       20 /* Hewlett Packard LaserJet               */\r
+ #define MACH_GROUP_LASAT       21\r
+ #define MACH_GROUP_TITAN       22 /* PMC-Sierra Titan                             */\r
++#define MACH_GROUP_AR531X      23 /* Atheros AR531X                         */\r
\r
+ /*\r
+  * Valid machtype values for group unknown (low order halfword of mips_machtype)\r
+@@ -201,6 +202,17 @@\r
+  */\r
+ #define       MACH_TITAN_YOSEMITE     1       /* PMC-Sierra Yosemite */\r
\r
++/*\r
++ * Valid machtype for group MACH_GROUP_AR5312\r
++ */\r
++#define MACH_ATHEROS_UNUSED     0\r
++#define MACH_ATHEROS_AP30       1       /* AP30 */\r
++#define MACH_ATHEROS_AP33     2       /* AP33 */\r
++#define MACH_ATHEROS_AP38       3       /* AP38 */\r
++#define MACH_ATHEROS_AP43       4       /* AP43 */\r
++#define MACH_ATHEROS_AP48       5       /* AP48 */\r
++#define MACH_ATHEROS_PB32       6       /* PB32 */\r
++\r
+ #define CL_SIZE                       (256)\r
\r
+ const char *get_system_type(void);\r
+diff -urN linux-2.4.32/include/asm-mips/serial.h linux-2.4.32.new/include/asm-mips/serial.h\r
+--- linux-2.4.32/include/asm-mips/serial.h     2005-01-19 14:10:12.000000000 +0000\r
++++ linux-2.4.32.new/include/asm-mips/serial.h 2005-12-24 21:28:51.901659800 +0000\r
+@@ -467,6 +467,11 @@\r
+ #define DDB5477_SERIAL_PORT_DEFNS\r
+ #endif\r
\r
++#if defined(CONFIG_AR531X)\r
++#undef RS_TABLE_SIZE\r
++#define RS_TABLE_SIZE 1\r
++#endif\r
++\r
+ #define SERIAL_PORT_DFNS                      \\r
+       ATLAS_SERIAL_PORT_DEFNS                 \\r
+       AU1000_SERIAL_PORT_DEFNS                \\r
+diff -urN linux-2.4.32/kernel/printk.c linux-2.4.32.new/kernel/printk.c\r
+--- linux-2.4.32/kernel/printk.c       2004-11-17 11:54:22.000000000 +0000\r
++++ linux-2.4.32.new/kernel/printk.c   2005-12-24 21:28:51.929655544 +0000\r
+@@ -384,6 +384,18 @@\r
+       _call_console_drivers(start_print, end, msg_level);\r
+ }\r
\r
++#if CONFIG_EARLY_PRINTK_HACK\r
++void putDebugChar(char byte);\r
++static void emit_log_char(char c)\r
++{\r
++      if (c == '\n') {\r
++              putDebugChar('\r');\r
++              putDebugChar('\n');\r
++      } else {\r
++              putDebugChar(c);\r
++      }\r
++}\r
++#else\r
+ static void emit_log_char(char c)\r
+ {\r
+       LOG_BUF(log_end) = c;\r
+@@ -395,6 +407,7 @@\r
+       if (logged_chars < LOG_BUF_LEN)\r
+               logged_chars++;\r
+ }\r
++#endif\r
\r
+ /*\r
+  * This is printk.  It can be called from any context.  We want it to work.\r
+@@ -700,3 +713,4 @@\r
+               tty->driver.write(tty, 0, msg, strlen(msg));\r
+       return;\r
+ }\r
++\r
diff --git a/openwrt/target/linux/linux-2.4/patches/ar531x/001-ar531x-ethernet.patch b/openwrt/target/linux/linux-2.4/patches/ar531x/001-ar531x-ethernet.patch
new file mode 100644 (file)
index 0000000..15dd777
--- /dev/null
@@ -0,0 +1,4890 @@
+diff -urN linux-2.4.32.new/arch/mips/ar531x/ae531xlnx.c linux-2.4.32.new-eth/arch/mips/ar531x/ae531xlnx.c\r
+--- linux-2.4.32.new/arch/mips/ar531x/ae531xlnx.c      1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new-eth/arch/mips/ar531x/ae531xlnx.c  2005-12-25 11:54:20.756273952 +0000\r
+@@ -0,0 +1,1534 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++/*\r
++ * Ethernet driver for Atheros' ae531x ethernet MAC.\r
++ * This is a fairly generic driver, but it's intended\r
++ * for use in typical Atheros products.\r
++ */\r
++\r
++#include <linux/config.h>\r
++#include <linux/types.h>\r
++#include <linux/delay.h>\r
++#include <linux/netdevice.h>\r
++#include <linux/etherdevice.h>\r
++#include <linux/init.h>\r
++#include <linux/skbuff.h>\r
++#include <asm/io.h>\r
++\r
++#include "ar531xlnx.h"\r
++#include "ae531xreg.h"\r
++#include "ae531xmac.h"\r
++\r
++/*\r
++ * A word about CONFIG_VENETDEV: It's intended to support two\r
++ * "virtualized ethernet devices" that share a single underlying MAC.\r
++ * To upper layers, it appears that the hardware supports two MACs,\r
++ * with enet0 used for LAN ports and enet1 used for a WAN port. This\r
++ * is useful, for instance, when building a 5-port router on hardware\r
++ * that uses only one of the AR5312's ethernet MACs.\r
++ *\r
++ * Virtualization is accomplished through trickery at the ethernet\r
++ * PHY layer.  We use PHY hardware to determine which port a packet\r
++ * was received on, and in order to direct a packet to a particular\r
++ * port or set of ports.\r
++ *\r
++ * The code is mostly written to be generalized to more than two\r
++ * virtual devices; but it's intended for one multi-port LAN enet\r
++ * device and one single-port WAN enet device.\r
++ */\r
++\r
++#define AE531X_LAN_PORT 0\r
++#ifdef CONFIG_VENETDEV\r
++#define AE531X_DEV_PER_MAC 2\r
++#define AE531X_WAN_PORT 1\r
++#else\r
++#define AE531X_DEV_PER_MAC 1\r
++#endif\r
++\r
++\r
++/*\r
++ * ae531x_MAC_state contains driver-specific linux-specific per-MAC information.\r
++ * The OSinfo member of ae531x_MAC_t points to one of these.\r
++ */\r
++typedef struct ae531x_MAC_state {\r
++    int                         irq;\r
++    struct tq_struct            restart_task;\r
++    struct net_device_stats     stats;\r
++    struct ae531x_dev_sw_state  *dev_sw_state[AE531X_DEV_PER_MAC];\r
++    int                         primary_dev;\r
++    ae531x_MAC_t                MACInfo; /* hardware state */\r
++} ae531x_MAC_state_t;\r
++\r
++/*\r
++ * ae531x_dev_sw_state contains driver-specific linux-specific per-device\r
++ * information.  The net_device priv member points to one of these, and\r
++ * this structure contains a pointer to the associated MAC information.\r
++ * In the case of CONFIG_VENETDEV, each virtual device has its own\r
++ * ae531x_dev_sw_state, and virtual devices that share a physical MAC\r
++ * point to the same ae531x_MAC_state.\r
++ */\r
++typedef struct ae531x_dev_sw_state {\r
++    int                     enetUnit;        /* system unit number "eth%d" */\r
++    int                     unit_on_MAC;     /* MAC-relative unit number */\r
++    struct net_device       *dev;\r
++    ae531x_MAC_state_t      *MAC_state;      /* underlying MAC hw/sw state */\r
++#ifdef CONFIG_VENETDEV\r
++    BOOL                    isLAN;           /* 0-->WAN; 1-->LAN */\r
++#endif\r
++} ae531x_dev_sw_state_t;\r
++\r
++/*\r
++ * Driver-independent linux-specific per-ethernet device software information.\r
++ * Regarding CONFIG_VENETDEV: If a system has 2 physical MACs, and each\r
++ * physical MAC has 2 virtual ethernet devices (one for LAN and one for WAN),\r
++ * then there are a total of 4 ethernet devices.\r
++ */\r
++static struct net_device *ae531x_MAC_dev[AR531X_NUM_ENET_MAC * AE531X_DEV_PER_MAC];\r
++\r
++/* Driver-dependent per-MAC information */\r
++static ae531x_MAC_state_t per_MAC_info[AR531X_NUM_ENET_MAC];\r
++\r
++/*\r
++ * Receive buffers need enough room to hold the following:\r
++ * 1) a max MTU-sized packet.  \r
++ * 2) space for an ethernet header\r
++ * 3) room at the beginning of the receive buffer in order\r
++ *    to facilitate cooperating drivers that need to PREpend\r
++ *    data.\r
++ * 4) Depending on configuration, we may need some additional\r
++ *    room at the END of the rx buffer for phy-supplied\r
++ *    trailers (if any). (c.f. CONFIG_VENETDEV)\r
++ *\r
++ * The DMA engine insists on 32-bit aligned RX buffers.\r
++ * TBDXXX: With current code, the IP stack ends up looking\r
++ * at misaligned headers with word operations.  The misaligned\r
++ * reads are software-emulated via handle_adel_int.  We'd\r
++ * rather align the buffers on a 16-bit boundary, but the\r
++ * DMA engine doesn't permit it???\r
++ */\r
++\r
++#ifdef CONFIG_VLAN_8021Q\r
++#define ETH_MAX_MTU 1522\r
++#define HLEN 18\r
++#else\r
++#define ETH_MAX_MTU 1518\r
++#define HLEN ETH_HLEN\r
++#endif\r
++\r
++#define AE531X_RX_BUF_SIZE \\r
++    (((2 + RXBUFF_RESERVE + HLEN + ETH_MAX_MTU + PHY_TRAILER_SIZE) + 3) & ~3)\r
++\r
++/* Forward references to local functions */\r
++static void ae531x_TxReap(ae531x_MAC_state_t *MAC_state);\r
++static int ae531x_phy_poll(void *data);\r
++static int ae531x_MAC_stop(struct net_device *dev);\r
++static int ae531x_MAC_open(struct net_device *dev);\r
++\r
++/* Global to track number of MACs */\r
++\r
++int ar531x_num_enet_macs;\r
++\r
++#undef DEBUG_VENETDEV\r
++#define AR531X_NAPI\r
++\r
++#if defined(CONFIG_VENETDEV) && defined(DEBUG_VENETDEV)\r
++static int cloned_counter;\r
++static int expand_counter;\r
++static int both_counter;\r
++#endif\r
++\r
++#ifdef AR531X_NAPI\r
++/*******************************************************************************\r
++* ae531x_MAC_poll checks for received packets, and sends data\r
++* up the stack.\r
++*/\r
++int\r
++ae531x_MAC_poll(struct net_device *dev, int *budget)\r
++{\r
++    struct sk_buff *skb;\r
++    struct sk_buff *newskb;\r
++    char *rxBufp;\r
++    int unused_length;\r
++    VIRT_ADDR   rxDesc;\r
++    int length;\r
++    ae531x_dev_sw_state_t *dev_sw_state;\r
++    ae531x_MAC_state_t *MAC_state;\r
++    ae531x_MAC_t *MACInfo;\r
++    u32 cmdsts;\r
++    int rx_limit;\r
++    int rx_received;\r
++    int rxDescCount;\r
++    struct net_device *rxdev;\r
++    int early_stop;\r
++    int retval;\r
++#ifdef CONFIG_VENETDEV\r
++    int i;\r
++#endif\r
++\r
++    ARRIVE();\r
++\r
++    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
++    MAC_state = dev_sw_state->MAC_state;\r
++    MACInfo = &MAC_state->MACInfo;\r
++    rx_limit = MAC_state->dev_sw_state[MAC_state->primary_dev]->dev->quota;\r
++    rx_received = 0;\r
++\r
++#ifdef CONFIG_VENETDEV\r
++    /*\r
++     * Non-primary devs don't explicitly get polled by the upper layers;\r
++     * rather, they rely on primary_dev polling to feed packets.  But in\r
++     * order to keep netif_receive_skb happy, we need to temporarily put the\r
++     * net_devices into "polling mode".  We pull them back out before\r
++     * leaving this function.\r
++     */\r
++    for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
++        if ((MAC_state->dev_sw_state[i]->dev) &&\r
++            (MAC_state->dev_sw_state[i]->unit_on_MAC != MAC_state->primary_dev)) {\r
++                netif_rx_schedule(MAC_state->dev_sw_state[i]->dev);\r
++        }\r
++    }\r
++#endif\r
++    rxDescCount = 0;\r
++\r
++    early_stop = 0;\r
++    do {\r
++        for(;;) {\r
++            // ae531x_AckIntr(MACInfo, (DmaIntRxCompleted | DmaIntRxNoBuffer));\r
++\r
++            rxDesc = MACInfo->rxQueue.curDescAddr;\r
++            cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(rxDesc));\r
++\r
++            AE531X_PRINT(AE531X_DEBUG_RX,\r
++                  ("examine rxDesc %p with cmdsts=0x%x\n",\r
++                   (void *)rxDesc, cmdsts));\r
++    \r
++            if (cmdsts & DescOwnByDma) {\r
++                /* There's nothing left to process in the RX ring */\r
++                goto rx_all_done;\r
++            }\r
++\r
++            rxDescCount++;\r
++\r
++            AE531X_CONSUME_DESC((&MACInfo->rxQueue));\r
++    \r
++            // A_DATA_CACHE_INVAL(rxDesc, AE531X_DESC_SIZE);\r
++\r
++            /*  Process a packet */\r
++            length = AE531X_DESC_STATUS_RX_SIZE(cmdsts) - ETH_CRC_LEN;\r
++            if ( (cmdsts & (DescRxFirst |DescRxLast | DescRxErrors)) ==\r
++                           (DescRxFirst | DescRxLast) ) {\r
++                /* Descriptor status indicates "NO errors" */\r
++                skb = AE531X_DESC_SWPTR_GET(rxDesc);\r
++    \r
++                /*\r
++                 * Allocate a replacement skb.\r
++                 * We want to get another buffer ready for Rx ASAP.\r
++                 */\r
++                newskb = (struct sk_buff *)ae531x_rxbuf_alloc(MACInfo, &rxBufp, &unused_length);\r
++                if(newskb == NULL ) {\r
++                    /*\r
++                     * Give this descriptor back to the DMA engine,\r
++                     * and drop the received packet.\r
++                     */\r
++                    MAC_state->stats.rx_dropped++;\r
++                    AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                              ("Can't allocate new skb\n"));\r
++                } else {\r
++                    AE531X_DESC_BUFPTR_SET(rxDesc, rxBufp);\r
++                    AE531X_DESC_SWPTR_SET(rxDesc, newskb);\r
++                }\r
++\r
++                AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma);\r
++              A_DATA_CACHE_FLUSH_INVAL(rxDesc, AE531X_DESC_SIZE);\r
++                // rxDesc = NULL; /* sanity -- cannot use rxDesc now */\r
++                sysWbFlush();\r
++    \r
++                if (newskb == NULL) {\r
++                    retval = 1;\r
++                    goto rx_no_skbs;\r
++                } else {\r
++                    /* Sync data cache w.r.t. DMA */\r
++                    // A_DATA_CACHE_INVAL(skb->data, length);\r
++        \r
++#ifdef CONFIG_VENETDEV\r
++                    /* Determine which associated device owns this rx buffer */\r
++                    {\r
++                        int fromLAN;\r
++\r
++                        fromLAN = phyDetermineSource(skb->data, length);\r
++\r
++                      if (fromLAN == -1) {\r
++                          /*\r
++                           * Could not determine source, so drop the packet\r
++                           */\r
++                          dev_kfree_skb(skb);\r
++                          continue;\r
++                      }\r
++\r
++                        length -= PHY_TRAILER_SIZE;\r
++                        if (fromLAN) {\r
++                            dev_sw_state = MAC_state->dev_sw_state[AE531X_LAN_PORT];\r
++                        } else {\r
++                            dev_sw_state = MAC_state->dev_sw_state[AE531X_WAN_PORT];\r
++                        }\r
++                    }\r
++#endif\r
++                    rxdev = dev_sw_state->dev;\r
++\r
++                    if (rxdev == NULL) {\r
++                        /*\r
++                         * We received a packet for a virtual enet device\r
++                         * that is no longer up.  Ignore it.\r
++                         */\r
++                        dev_kfree_skb(skb);\r
++                        continue;\r
++                    }\r
++\r
++                    /* Advance data pointer to show that there's data here */\r
++                    skb_put(skb, length);\r
++                    skb->protocol = eth_type_trans(skb, rxdev);\r
++                    skb->dev = rxdev;\r
++                    rxdev->last_rx = jiffies;\r
++                    rxdev->quota--;\r
++\r
++                    if (rx_limit-- < 0) {\r
++                        early_stop=1;\r
++                        /* We've done enough for now -- more later */\r
++                        AE531X_PRINT(AE531X_DEBUG_RX_STOP,\r
++                            ("Enet%d RX early stop.  Quota=%d rxDescCount=%d budget=%d\n",\r
++                             MACInfo->unit, dev->quota, rxDescCount, *budget));\r
++                    }\r
++                    rx_received++;\r
++        \r
++                    /* Send the data up the stack */\r
++                    AE531X_PRINT(AE531X_DEBUG_RX,\r
++                              ("Send data up stack: skb=%p data=%p length=%d\n",\r
++                               (void *)skb, (void *)skb->data, length));\r
++\r
++                    netif_receive_skb(skb);\r
++\r
++                    MAC_state->stats.rx_packets++;\r
++                    MAC_state->stats.rx_bytes += length;\r
++                }\r
++            } else {\r
++                /* Descriptor status indicates ERRORS */\r
++                MAC_state->stats.rx_errors++;\r
++    \r
++                if (cmdsts & (DescRxRunt | DescRxLateColl)) {\r
++                  AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                                 ("Runt | RX Late Collision Error\n"));\r
++                    MAC_state->stats.collisions++;\r
++                }\r
++    \r
++                if (cmdsts & DescRxLengthError) {\r
++                  AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                                 ("RX Length Error\n"));\r
++                    MAC_state->stats.rx_length_errors++;\r
++                }\r
++    \r
++                if (cmdsts & DescRxCrc) {\r
++                  AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                                 ("RX CRC Error\n"));\r
++                    MAC_state->stats.rx_crc_errors++;\r
++                }\r
++    \r
++                if (cmdsts & DescRxDribbling) {\r
++                  AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                                 ("Dribbling Error\n"));\r
++                    MAC_state->stats.rx_frame_errors++;\r
++                }\r
++    \r
++                AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                          ("Bad receive.  rxDesc=%p  cmdsts=0x%8.8x\n",\r
++                           (void *)rxDesc, cmdsts));\r
++\r
++              /* Give this one back */\r
++                AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma);\r
++              A_DATA_CACHE_FLUSH_INVAL(rxDesc, AE531X_DESC_SIZE);\r
++                sysWbFlush();\r
++            }\r
++        }\r
++    } while ((!early_stop) &&\r
++             ae531x_ReadDmaReg(MACInfo, DmaStatus) & DmaIntRxCompleted);\r
++\r
++rx_all_done:\r
++    AE531X_PRINT(AE531X_DEBUG_RX, \r
++             ("rx done (%d)\n", rxDescCount));\r
++    *budget -= rxDescCount;\r
++\r
++    if (!early_stop) {\r
++        netif_rx_complete(dev);\r
++\r
++        ae531x_SetDmaReg(MACInfo, DmaIntrEnb,\r
++                     DmaIeRxCompleted | DmaIeRxNoBuffer);\r
++        ae531x_WriteDmaReg(MACInfo, DmaRxPollDemand, 0);\r
++    }\r
++    \r
++    retval = early_stop;\r
++\r
++rx_no_skbs:\r
++\r
++#ifdef CONFIG_VENETDEV\r
++    for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
++        if ((MAC_state->dev_sw_state[i]->dev) &&\r
++            (MAC_state->dev_sw_state[i]->unit_on_MAC !=\r
++                                      MAC_state->primary_dev)) {\r
++                netif_rx_complete(MAC_state->dev_sw_state[i]->dev);\r
++        }\r
++    }\r
++#endif\r
++\r
++    LEAVE();\r
++    return retval;\r
++}\r
++#endif\r
++\r
++#ifndef AR531X_NAPI\r
++/*******************************************************************************\r
++* ae531x_MAC_recv checks for received packets, and sends data\r
++* up the stack.\r
++*/\r
++static void\r
++ae531x_MAC_recv(struct net_device *dev)\r
++{\r
++    struct sk_buff *skb;\r
++    struct sk_buff *newskb;\r
++    char *rxBufp;\r
++    int unused_length;\r
++    VIRT_ADDR   rxDesc;\r
++    int length;\r
++    ae531x_dev_sw_state_t *dev_sw_state;\r
++    ae531x_MAC_state_t *MAC_state;\r
++    ae531x_MAC_t *MACInfo;\r
++    u32 cmdsts;\r
++    int rx_limit;\r
++    int rx_received;\r
++    struct net_device *rxdev;\r
++    int retval;\r
++\r
++    ARRIVE();\r
++\r
++    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
++    MAC_state = dev_sw_state->MAC_state;\r
++    MACInfo = &MAC_state->MACInfo;\r
++    rx_limit = MAC_state->dev_sw_state[MAC_state->primary_dev]->dev->quota;\r
++    rx_received = 0;\r
++\r
++    for(;;) {\r
++      rxDesc = MACInfo->rxQueue.curDescAddr;\r
++      cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(rxDesc));\r
++\r
++      AE531X_PRINT(AE531X_DEBUG_RX,\r
++            ("examine rxDesc %p with cmdsts=0x%x\n",\r
++             (void *)rxDesc, cmdsts));\r
++\r
++      if (cmdsts & DescOwnByDma) {\r
++          /* There's nothing left to process in the RX ring */\r
++          break;\r
++      }\r
++\r
++      AE531X_CONSUME_DESC((&MACInfo->rxQueue));\r
++\r
++      // A_DATA_CACHE_INVAL(rxDesc, AE531X_DESC_SIZE);\r
++\r
++      /*  Process a packet */\r
++      length = AE531X_DESC_STATUS_RX_SIZE(cmdsts) - ETH_CRC_LEN;\r
++      if ( (cmdsts & (DescRxFirst |DescRxLast | DescRxErrors)) ==\r
++                     (DescRxFirst | DescRxLast) ) {\r
++          /* Descriptor status indicates "NO errors" */\r
++          skb = AE531X_DESC_SWPTR_GET(rxDesc);\r
++\r
++          /*\r
++           * Allocate a replacement skb.\r
++           * We want to get another buffer ready for Rx ASAP.\r
++           */\r
++          newskb = (struct sk_buff *)ae531x_rxbuf_alloc(MACInfo,\r
++                                                        &rxBufp,\r
++                                                        &unused_length);\r
++          if(newskb == NULL ) {\r
++              /*\r
++               * Give this descriptor back to the DMA engine,\r
++               * and drop the received packet.\r
++               */\r
++              MAC_state->stats.rx_dropped++;\r
++              AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                        ("Can't allocate new skb\n"));\r
++          } else {\r
++              AE531X_DESC_BUFPTR_SET(rxDesc, rxBufp);\r
++              AE531X_DESC_SWPTR_SET(rxDesc, newskb);\r
++          }\r
++\r
++          AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma);\r
++          A_DATA_CACHE_FLUSH_INVAL(rxDesc, AE531X_DESC_SIZE);\r
++          sysWbFlush();\r
++\r
++          if (newskb == NULL) {\r
++              break;\r
++          } else {\r
++#ifdef CONFIG_VENETDEV\r
++              /* Determine which associated device owns this rx buffer */\r
++              {\r
++                  int fromLAN;\r
++\r
++                  fromLAN = phyDetermineSource(skb->data, length);\r
++\r
++                  if (fromLAN == -1) {\r
++                      /*\r
++                       * Could not determine source, so drop the packet\r
++                       */\r
++                      dev_kfree_skb(skb);\r
++                      continue;\r
++                  }\r
++\r
++                  length -= PHY_TRAILER_SIZE;\r
++                  if (fromLAN) {\r
++                      dev_sw_state =\r
++                          MAC_state->dev_sw_state[AE531X_LAN_PORT];\r
++                  } else {\r
++                      dev_sw_state =\r
++                          MAC_state->dev_sw_state[AE531X_WAN_PORT];\r
++                  }\r
++              }\r
++#endif\r
++              rxdev = dev_sw_state->dev;\r
++\r
++              if (rxdev == NULL) {\r
++                  /*\r
++                   * We received a packet for a virtual enet device\r
++                   * that is no longer up.  Ignore it.\r
++                   */\r
++                  dev_kfree_skb(skb);\r
++                  continue;\r
++              }\r
++\r
++              /* Advance data pointer to show that there's data here */\r
++              skb_put(skb, length);\r
++              skb->protocol = eth_type_trans(skb, rxdev);\r
++              skb->dev = rxdev;\r
++              rxdev->last_rx = jiffies;\r
++              rxdev->quota--;\r
++\r
++              rx_received++;\r
++    \r
++              /* Send the data up the stack */\r
++              AE531X_PRINT(AE531X_DEBUG_RX,\r
++                        ("Send data up stack: skb=%p data=%p length=%d\n",\r
++                         (void *)skb, (void *)skb->data, length));\r
++\r
++              netif_rx(skb);\r
++\r
++              MAC_state->stats.rx_packets++;\r
++              MAC_state->stats.rx_bytes += length;\r
++          }\r
++      } else {\r
++          /* Descriptor status indicates ERRORS */\r
++          MAC_state->stats.rx_errors++;\r
++\r
++          if (cmdsts & (DescRxRunt | DescRxLateColl)) {\r
++              MAC_state->stats.collisions++;\r
++          }\r
++\r
++          if (cmdsts & DescRxLengthError) {\r
++              MAC_state->stats.rx_length_errors++;\r
++          }\r
++\r
++          if (cmdsts & DescRxCrc) {\r
++              MAC_state->stats.rx_crc_errors++;\r
++          }\r
++\r
++          if (cmdsts & DescRxDribbling) {\r
++              MAC_state->stats.rx_frame_errors++;\r
++          }\r
++\r
++          AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                    ("Bad receive.  rxDesc=%p  cmdsts=0x%8.8x\n",\r
++                     (void *)rxDesc, cmdsts));\r
++      }\r
++    }\r
++\r
++    LEAVE();\r
++    return;\r
++}\r
++#endif\r
++\r
++/*******************************************************************************\r
++* ae531x_restart stops all ethernet devices associated with a physical MAC,\r
++* then shuts down the MAC.  Then it re-opens all devices that were in use.\r
++* TBDXXX: needs testing!\r
++*/\r
++static void\r
++ae531x_restart(void *data)\r
++{\r
++    ae531x_MAC_t *MACInfo = (ae531x_MAC_t *)data;\r
++    ae531x_MAC_state_t *MAC_state = (ae531x_MAC_state_t *)MACInfo->OSinfo;\r
++    struct net_device *saved_dev[AE531X_DEV_PER_MAC];\r
++    int i;\r
++\r
++    for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
++        if ((saved_dev[i] = MAC_state->dev_sw_state[i]->dev) != NULL) {\r
++            ae531x_MAC_stop(saved_dev[i]);\r
++        }\r
++    }\r
++\r
++    for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
++        if (saved_dev[i])\r
++            ae531x_MAC_open(saved_dev[i]);\r
++    }\r
++}\r
++\r
++/*******************************************************************************\r
++* ae531x_MAC_intr handle interrupts from an ethernet MAC.\r
++* It checks MAC status registers, and dispatches as appropriate.\r
++*/\r
++void\r
++ae531x_MAC_intr(int cpl, void *dev_id, struct pt_regs *regs)\r
++{\r
++        ae531x_MAC_state_t *MAC_state;\r
++        ae531x_MAC_t *MACInfo;\r
++        u32 regIsr;\r
++        u32 regImr;\r
++        u32 pendIntrs;\r
++      struct net_device * primary_dev;\r
++\r
++        ARRIVE();\r
++\r
++        MACInfo = (ae531x_MAC_t *)dev_id;\r
++        MAC_state = (ae531x_MAC_state_t *)MACInfo->OSinfo;\r
++      primary_dev = MAC_state->dev_sw_state[MAC_state->primary_dev]->dev;\r
++\r
++        for(;;) {\r
++                /* Clear any unhandled intr causes. */\r
++                ae531x_WriteDmaReg(MACInfo, DmaStatus, UnhandledIntrMask);\r
++\r
++                regIsr = ae531x_ReadDmaReg(MACInfo, DmaStatus);\r
++\r
++                regImr = ae531x_ReadDmaReg(MACInfo, DmaIntrEnb);\r
++                pendIntrs = regIsr & regImr;\r
++\r
++                AE531X_PRINT(AE531X_DEBUG_INT,\r
++                          ("ethmac%d: intIsr=0x%8.8x intImr=0x%8.8x\n",\r
++                           MACInfo->unit, regIsr, regImr));\r
++\r
++                if ((pendIntrs & DmaAllIntCauseMask) == 0)\r
++                    break;\r
++\r
++                if ((pendIntrs & DmaIntRxCompleted) ||\r
++                    (pendIntrs & DmaIntRxNoBuffer)) {\r
++#ifdef AR531X_NAPI\r
++                    if (netif_rx_schedule_prep(primary_dev)) {\r
++                        ae531x_ClearDmaReg(MACInfo,\r
++                                           DmaIntrEnb,\r
++                                           DmaIeRxCompleted | DmaIeRxNoBuffer);\r
++                        ae531x_AckIntr(MACInfo,\r
++                                       DmaIntRxCompleted | DmaIntRxNoBuffer);\r
++                        (void)ae531x_ReadDmaReg(MACInfo, DmaIntrEnb);\r
++                        __netif_rx_schedule(primary_dev);\r
++                    } else {\r
++                        AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                                 ("%s: Interrupt (0x%8.8x/0x%8.8x) while in poll.  regs@%p, pc=%p, ra=%p\n",\r
++                               __FILE__,\r
++                               regIsr,\r
++                               ae531x_ReadDmaReg(MACInfo, DmaIntrEnb),\r
++                               (void *)regs,\r
++                               (void *)regs->cp0_epc,\r
++                               (void *)regs->regs[31]));\r
++                        ae531x_ClearDmaReg(MACInfo,\r
++                                           DmaIntrEnb,\r
++                                           DmaIeRxCompleted | DmaIeRxNoBuffer);\r
++                        ae531x_AckIntr(MACInfo,\r
++                                       DmaIntRxCompleted | DmaIntRxNoBuffer);\r
++                    }\r
++#else\r
++                  ae531x_MAC_recv(primary_dev);\r
++                  ae531x_AckIntr(MACInfo,\r
++                                   DmaIntRxCompleted | DmaIntRxNoBuffer);\r
++#endif\r
++                }\r
++\r
++                if (pendIntrs &\r
++                    (DmaIntTxStopped | DmaIntTxJabber | DmaIntTxUnderflow)) {\r
++                    AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                              ("ethmac%d: TX Error Intr (0x%x)\n",\r
++                               MACInfo->unit, pendIntrs));\r
++                    ae531x_AckIntr(MACInfo,\r
++                        (DmaIntTxStopped | DmaIntTxJabber | DmaIntTxUnderflow));\r
++                }\r
++\r
++                if (pendIntrs & DmaIntBusError) {\r
++                    AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                              ("ethmac%d: DMA Bus Error Intr (0x%x)\n",\r
++                               MACInfo->unit, pendIntrs));\r
++                    ae531x_AckIntr(MACInfo, DmaIntBusError);\r
++                    /* Reset the chip, if it's not already being done */\r
++                    if (ae531x_IsInResetMode(MACInfo)) {\r
++                        goto intr_done;\r
++                    }\r
++                    ae531x_BeginResetMode(MACInfo);\r
++                    schedule_task(&MAC_state->restart_task);\r
++                }\r
++\r
++                if (pendIntrs & DmaIntRxStopped) {\r
++                    AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                              ("ethmac%d: RX Stopped Intr (0x%x)\n",\r
++                               MACInfo->unit, pendIntrs));\r
++                    ae531x_AckIntr(MACInfo, DmaIntRxStopped);\r
++                }\r
++      }\r
++\r
++      ae531x_DmaIntEnable(MACInfo);\r
++\r
++intr_done:\r
++      LEAVE();\r
++}\r
++\r
++/*******************************************************************************\r
++* ae531x_MAC_get_stats returns statistics for a specified device\r
++*/\r
++static struct net_device_stats*\r
++ae531x_MAC_get_stats(struct net_device *dev)\r
++{\r
++        ae531x_dev_sw_state_t *dev_sw_state;\r
++        ae531x_MAC_state_t *MAC_state;\r
++\r
++        ARRIVE();\r
++        dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
++        MAC_state = dev_sw_state->MAC_state;\r
++\r
++        LEAVE();\r
++        return &MAC_state->stats;\r
++}\r
++\r
++#define AE531X_PHY_POLL_SECONDS 2\r
++\r
++/*******************************************************************************\r
++* ae531x_phy_poll periodically checks for changes in phy status\r
++* (e.g. dropped link).\r
++*/\r
++static int\r
++ae531x_phy_poll(void *data)\r
++{\r
++    ae531x_dev_sw_state_t *dev_sw_state = (ae531x_dev_sw_state_t *)data;\r
++    ae531x_MAC_t *MACInfo = &dev_sw_state->MAC_state->MACInfo;\r
++    int unit = dev_sw_state->enetUnit;\r
++\r
++#if defined(CONFIG_VENETDEV) && defined(DEBUG_VENETDEV)\r
++    int       previous_cloned = 0;\r
++    int       previous_expand = 0;\r
++    int       previous_both = 0;\r
++#endif\r
++\r
++    daemonize();\r
++    reparent_to_init();\r
++    spin_lock_irq(&current->sigmask_lock);\r
++    sigemptyset(&current->blocked);\r
++    recalc_sigpending(current);\r
++    spin_unlock_irq(&current->sigmask_lock);\r
++\r
++    snprintf(current->comm, sizeof(current->comm), "%s",\r
++           dev_sw_state->dev->name);\r
++\r
++    for(;;) {\r
++        if (MACInfo->port_is_up) {\r
++            phyCheckStatusChange(unit);\r
++        }\r
++\r
++#if defined(CONFIG_VENETDEV) && defined(DEBUG_VENETDEV)\r
++      if (cloned_counter != previous_cloned) {\r
++              printk("Cloned Counter: %d (delta %d)\n",\r
++                      cloned_counter, cloned_counter - previous_cloned);\r
++              previous_cloned = cloned_counter;\r
++      }\r
++      if (expand_counter != previous_expand) {\r
++              printk("Expand Counter: %d (delta %d)\n",\r
++                      expand_counter, expand_counter - previous_expand);\r
++              previous_expand = expand_counter;\r
++      }\r
++      if (both_counter != previous_both) {\r
++              printk("Expand & Cloned Counter: %d (delta %d)\n",\r
++                      both_counter, both_counter - previous_both);\r
++              previous_both = both_counter;\r
++      }\r
++#endif\r
++\r
++        set_current_state(TASK_UNINTERRUPTIBLE);\r
++        schedule_timeout(AE531X_PHY_POLL_SECONDS * HZ);\r
++    }\r
++\r
++    return 0;\r
++}\r
++\r
++\r
++/*******************************************************************************\r
++* ae531x_MAC_set_rx_mode is used to set the RX mode options, such as\r
++* promiscuous or multicast.\r
++*/\r
++static void\r
++ae531x_MAC_set_rx_mode(struct net_device *dev)\r
++{\r
++    ae531x_dev_sw_state_t *dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
++    ae531x_MAC_state_t *MAC_state=dev_sw_state->MAC_state;\r
++    ae531x_MAC_t *MACInfo = &MAC_state->MACInfo;\r
++\r
++    if (dev->flags & IFF_PROMISC) {\r
++      ae531x_SetMacReg(MACInfo, MacControl, MacPromiscuousModeOn);\r
++    } else {\r
++      ae531x_ClearMacReg(MACInfo, MacControl, MacPromiscuousModeOn);\r
++    }\r
++\r
++    if (dev->flags & IFF_MULTICAST) {\r
++      ae531x_SetMacReg(MACInfo, MacControl, MacMulticastFilterOff);\r
++    } else {\r
++      ae531x_ClearMacReg(MACInfo, MacControl, MacMulticastFilterOff);\r
++    }\r
++}\r
++\r
++/*******************************************************************************\r
++* ae531x_MAC_open is the standard Linux open function.  It puts\r
++* hardware into a known good state, allocates queues, starts\r
++* the phy polling task, and arranges for interrupts to be handled.\r
++*/\r
++static int\r
++ae531x_MAC_open(struct net_device *dev)\r
++{\r
++    ae531x_dev_sw_state_t *dev_sw_state;\r
++    ae531x_MAC_state_t *MAC_state;\r
++    ae531x_MAC_t *MACInfo;\r
++    int rv;\r
++    struct tq_struct *restart_task;\r
++    pid_t phy_poll_pid;\r
++\r
++    ARRIVE();\r
++\r
++    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
++    dev_sw_state->dev = dev;\r
++    MAC_state = dev_sw_state->MAC_state;\r
++    MACInfo = &MAC_state->MACInfo;\r
++\r
++    restart_task = &MAC_state->restart_task;\r
++    restart_task->routine = ae531x_restart;\r
++    restart_task->data = (void *)MACInfo;\r
++\r
++    AE531X_PRINT(AE531X_DEBUG_RESET,\r
++              ("ae531x_MAC_open eth%d ethmac%d macBase=0x%x dmaBase=0x%x irq=0x%x\n",\r
++               dev_sw_state->enetUnit,\r
++               MACInfo->unit,\r
++               MACInfo->macBase,\r
++               MACInfo->dmaBase,\r
++               MAC_state->irq));\r
++\r
++    if (!MACInfo->port_is_up) {\r
++        /* Bring MAC and PHY out of reset */\r
++        ae531x_reset(MACInfo);\r
++    \r
++        /* Attach interrupt handler */\r
++        rv = request_irq(MAC_state->irq, ae531x_MAC_intr, SA_INTERRUPT,\r
++                    "ae531x_MAC_intr", (void *)MACInfo);\r
++        if (rv < 0) {\r
++            AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                         ("request_irq(0x%x) failed (%d)\n",\r
++                          MAC_state->irq, rv));\r
++            goto open_failure;\r
++        }\r
++\r
++        /* Initialize PHY */\r
++        phySetup(MACInfo->unit, MACInfo->phyBase);\r
++\r
++        /* Start thread to poll for phy link status changes */\r
++        phy_poll_pid = kernel_thread(ae531x_phy_poll,\r
++                                   dev_sw_state,\r
++                                   CLONE_FS | CLONE_FILES);\r
++        if (phy_poll_pid < 0) {\r
++            AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                     ("ethmac%d unable to start Phy Poll thread\n",\r
++                     MACInfo->unit));\r
++        }\r
++\r
++        /* Allocate RX/TX Queues */\r
++        if (ae531x_AllocateQueues(MACInfo) < 0) {\r
++            AE531X_PRINT(AE531X_DEBUG_RESET, ("Queue allocation failed"));\r
++            free_irq(MAC_state->irq, (void *)MACInfo);\r
++            goto open_failure;\r
++        }\r
++    \r
++        /* Initialize DMA and descriptors */\r
++        ae531x_DmaReset(MACInfo);\r
++\r
++        /* Initialize MAC */\r
++        ae531x_MACReset(MACInfo);\r
++\r
++      /* Set RX mode */\r
++      ae531x_MAC_set_rx_mode(dev);\r
++\r
++        /* Enable Receive/Transmit */\r
++        ae531x_EnableComm(MACInfo);\r
++    \r
++        MAC_state->primary_dev = dev_sw_state->unit_on_MAC;\r
++        MACInfo->port_is_up = TRUE;\r
++    }\r
++\r
++    dev->trans_start = jiffies;\r
++\r
++    LEAVE();\r
++    return 0;\r
++\r
++open_failure:\r
++    LEAVE();\r
++    return -1;\r
++}\r
++\r
++/*\r
++ * Shut down MAC hardware.\r
++ */\r
++static void\r
++ae531x_MAC_shutdown(ae531x_MAC_state_t *MAC_state)\r
++{\r
++    ae531x_MAC_t *MACInfo;\r
++\r
++    MACInfo = &MAC_state->MACInfo;\r
++    MACInfo->port_is_up = FALSE;\r
++\r
++    /* Disable Receive/Transmit */\r
++    ae531x_DisableComm(MACInfo);\r
++\r
++    /* Disable Interrupts */\r
++    ae531x_DmaIntDisable(MACInfo);\r
++    sysWbFlush();\r
++    free_irq(MAC_state->irq, (void *)MACInfo);\r
++\r
++    /* Free Transmit & Receive skb's/descriptors */\r
++    ae531x_TxReap(MAC_state); /* one last time */\r
++    ae531x_FreeQueues(MACInfo);\r
++}\r
++\r
++/*******************************************************************************\r
++* ae531x_MAC_stop is the standard Linux stop function.  It undoes\r
++* everything set up by ae531x_MAC_open.\r
++*/\r
++static int\r
++ae531x_MAC_stop(struct net_device *dev)\r
++{\r
++    ae531x_dev_sw_state_t *dev_sw_state;\r
++    ae531x_MAC_state_t *MAC_state;\r
++    ae531x_MAC_t *MACInfo;\r
++    int i;\r
++\r
++    ARRIVE();\r
++\r
++    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
++    MAC_state = dev_sw_state->MAC_state;\r
++    MACInfo = &MAC_state->MACInfo;\r
++\r
++    for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
++        if ((MAC_state->dev_sw_state[i]->dev) &&\r
++            (MAC_state->dev_sw_state[i]->dev != dev_sw_state->dev)) {\r
++            break;\r
++        }\r
++    }\r
++\r
++    if (i < AE531X_DEV_PER_MAC) {\r
++        /* Physical MAC is still in use */\r
++        if (MAC_state->primary_dev == dev_sw_state->unit_on_MAC) {\r
++            /*\r
++             * If the primary_dev is being stopped\r
++             * then we need to assign a new one.\r
++             */\r
++            MAC_state->primary_dev = i;\r
++        }\r
++    } else {\r
++        /* Physical MAC is no longer in use */\r
++        ae531x_MAC_shutdown(MAC_state);\r
++    }\r
++\r
++    dev_sw_state->dev = NULL;\r
++\r
++    LEAVE();\r
++    return 0;\r
++}\r
++\r
++/*******************************************************************************\r
++* ae531x_rxbuf_alloc - Allocate an skb to be associated with an RX descriptor.\r
++*\r
++* RETURNS: A pointer to the skb.  Also returns a pointer to the underlying\r
++* buffer and the size of that buffer. \r
++*/\r
++void *\r
++ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBuffp, int *rxBuffSizep)\r
++{\r
++    struct sk_buff *skb;\r
++    char *rxBuff;\r
++    int rxBuffSize;\r
++\r
++    skb = dev_alloc_skb(AE531X_RX_BUF_SIZE);\r
++    if (skb) {\r
++      /* Add 2 to align the IP header on a DWORD boundary */\r
++        skb_reserve(skb, RXBUFF_RESERVE + 2);\r
++\r
++        rxBuffSize = skb_tailroom(skb);\r
++        rxBuff = skb->tail;\r
++\r
++        *rxBuffp = rxBuff;\r
++        *rxBuffSizep = rxBuffSize;\r
++\r
++      A_DATA_CACHE_INVAL(rxBuff, rxBuffSize);\r
++    }\r
++\r
++    return skb;\r
++}\r
++\r
++/*******************************************************************************\r
++* ae531x_swptr_free - Free the skb, if any, associated with a descriptor.\r
++*/\r
++void\r
++ae531x_swptr_free(VIRT_ADDR desc)\r
++{\r
++    struct sk_buff *skb;\r
++\r
++    skb = (struct sk_buff *)AE531X_DESC_SWPTR_GET(desc);\r
++    if (skb) {\r
++        AE531X_DESC_SWPTR_SET(desc, NULL);\r
++        kfree_skb(skb);\r
++    }\r
++}\r
++\r
++/*******************************************************************************\r
++*\r
++* ae531x_TxReap - the driver Tx completion routine.\r
++*\r
++* This routine reaps sk_buffs which have already been transmitted.\r
++*\r
++*/\r
++static void\r
++ae531x_TxReap(ae531x_MAC_state_t *MAC_state)\r
++{\r
++    AE531X_QUEUE      *txq;\r
++    VIRT_ADDR         txDesc;\r
++    UINT32            cmdsts;\r
++    struct            sk_buff *skb;\r
++    int               reaped;\r
++    ae531x_MAC_t      *MACInfo;\r
++    static int        aeUselessReap = 0;\r
++\r
++    ARRIVE();\r
++\r
++    MACInfo = &MAC_state->MACInfo;\r
++    txq = &MACInfo->txQueue;\r
++    reaped = 0;\r
++\r
++    while (1) {\r
++        txDesc = AE531X_QUEUE_ELE_NEXT_GET(txq, txq->reapDescAddr);\r
++        if (txDesc == txq->curDescAddr) {\r
++            break;\r
++        }\r
++\r
++        cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(txDesc));\r
++        if (cmdsts & DescOwnByDma) {\r
++            break;\r
++        }\r
++\r
++        /* Release sk_buff associated with completed transmit */\r
++        skb = (struct sk_buff *)AE531X_DESC_SWPTR_GET(txDesc);\r
++\r
++        if (skb) {\r
++            kfree_skb(skb);\r
++            AE531X_DESC_SWPTR_SET(txDesc, NULL);\r
++        }\r
++\r
++        /* Update statistics according to completed transmit desc */\r
++        if (cmdsts & DescTxErrors) {\r
++            AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                    ("enetmac%d Tx prior error: 0x%8.8x <0x%8.8x> 0x%8.8x\n",\r
++                    MACInfo->unit,\r
++                    cmdsts,\r
++                    DescTxErrors,\r
++                    (int)txDesc));\r
++            MAC_state->stats.tx_errors++;\r
++            if (cmdsts & (DescTxLateCollision | DescTxExcCollisions)) {\r
++                MAC_state->stats.tx_aborted_errors++;\r
++            }\r
++            if (cmdsts & (DescTxLostCarrier | DescTxNoCarrier)) {\r
++                MAC_state->stats.tx_carrier_errors++;\r
++            }\r
++        } else {\r
++            MAC_state->stats.tx_bytes += AE531X_DESC_STATUS_RX_SIZE(cmdsts);\r
++            MAC_state->stats.tx_packets++;\r
++        }\r
++\r
++        MAC_state->stats.collisions +=\r
++            ((cmdsts & DescTxCollMask) >> DescTxCollShift);\r
++\r
++        txq->reapDescAddr = txDesc;\r
++        reaped++;\r
++    }\r
++\r
++    if (reaped > 0) {\r
++        int i;\r
++\r
++        AE531X_PRINT(AE531X_DEBUG_TX_REAP,\r
++             ("reaped %d\n", reaped));\r
++\r
++        /*\r
++         * Re-start transmit queues for all ethernet devices\r
++         * associated with this MAC.\r
++         */\r
++        for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
++            if (MAC_state->dev_sw_state[i]->dev)\r
++                netif_start_queue(MAC_state->dev_sw_state[i]->dev);\r
++        }\r
++    } else {\r
++        aeUselessReap++;\r
++    }\r
++\r
++    LEAVE();\r
++}\r
++\r
++/*******************************************************************************\r
++* ae531x_MAC_start_xmit sends a packet.\r
++*/\r
++static int\r
++ae531x_MAC_start_xmit(struct sk_buff *skb, struct net_device *dev)\r
++{\r
++    ae531x_dev_sw_state_t *dev_sw_state;\r
++    ae531x_MAC_state_t *MAC_state;\r
++    ae531x_MAC_t *MACInfo;\r
++    u32 buf;\r
++    u32 ctrlen;\r
++    u32 length;\r
++    int mtu;\r
++    int max_buf_size;\r
++    VIRT_ADDR txDesc;\r
++\r
++    ARRIVE();\r
++\r
++    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
++    MAC_state = dev_sw_state->MAC_state;\r
++    MACInfo = &MAC_state->MACInfo;\r
++\r
++    length = skb->len;\r
++\r
++    /* Check if this port is up, else toss packet */\r
++    if (!MACInfo->port_is_up) {\r
++        buf = virt_to_bus(skb->data);\r
++        AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                  ("eth%d Tx Down, dropping buf=0x%8.8x, length=0x%8.8x, skb=%p\n",\r
++                   dev_sw_state->enetUnit, buf, length, (void *)skb));\r
++\r
++        MAC_state->stats.tx_dropped++;\r
++        MAC_state->stats.tx_carrier_errors++;\r
++        goto dropFrame;\r
++    }\r
++\r
++    if (ae531x_IsInResetMode(MACInfo)) {\r
++        AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                  ("eth%d Tx: In Chip reset - drop frame\n",\r
++                   dev_sw_state->enetUnit));\r
++\r
++        MAC_state->stats.tx_dropped++;\r
++        MAC_state->stats.tx_aborted_errors++;\r
++        goto dropFrame;\r
++    }\r
++\r
++    /* Check if we can transport this packet */\r
++    length = max((u32)60, length);  /* total length */\r
++    mtu = dev->mtu;\r
++    max_buf_size = mtu + HLEN;\r
++    if (length > max_buf_size) {\r
++        AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                  ("eth%d Tx: length %d too long.  mtu=%d, trailer=%d\n",\r
++                   dev_sw_state->enetUnit, length, mtu, PHY_TRAILER_SIZE));\r
++\r
++        MAC_state->stats.tx_errors++;\r
++        MAC_state->stats.tx_aborted_errors++;\r
++\r
++        goto dropFrame;\r
++    }\r
++\r
++    /* Reap any old, completed Tx descriptors */\r
++    ae531x_TxReap(MAC_state);\r
++\r
++    txDesc = MACInfo->txQueue.curDescAddr;\r
++    if (txDesc == MACInfo->txQueue.reapDescAddr) {\r
++        int i;\r
++\r
++        AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                  ("eth%d Tx: cannot get txDesc\n",\r
++                   dev_sw_state->enetUnit));\r
++\r
++        MAC_state->stats.tx_dropped++;\r
++        MAC_state->stats.tx_fifo_errors++;\r
++\r
++        /*\r
++         * Stop transmit queues for any ethernet devices\r
++         * associated with this MAC.\r
++         */\r
++        for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
++            if (MAC_state->dev_sw_state[i]->dev)\r
++                netif_stop_queue(MAC_state->dev_sw_state[i]->dev);\r
++        }\r
++        goto dropFrame;\r
++    }\r
++\r
++#ifdef CONFIG_VENETDEV\r
++    {\r
++        struct sk_buff *newskb;\r
++\r
++      if (skb_cloned(skb) || (skb_tailroom(skb) < PHY_TRAILER_SIZE)) {\r
++#ifdef DEBUG_VENETDEV\r
++              if (skb_cloned(skb)) {\r
++                      cloned_counter++;\r
++                      if (skb_tailroom(skb) < PHY_TRAILER_SIZE) {\r
++                              both_counter++;\r
++                      }\r
++              } else {\r
++                      expand_counter++;\r
++              }\r
++#endif\r
++              newskb = skb_copy_expand(skb, 0, PHY_TRAILER_SIZE, GFP_ATOMIC);\r
++              if (newskb == NULL) {\r
++                  goto dropFrame;\r
++              }\r
++\r
++              dev_kfree_skb(skb);\r
++              skb = newskb;\r
++      }\r
++\r
++        phySetDestinationPort(skb->data, length, dev_sw_state->isLAN);\r
++        skb_put(skb, PHY_TRAILER_SIZE);\r
++        length += PHY_TRAILER_SIZE;\r
++    }\r
++#endif\r
++\r
++    /* We won't fail now; so consume this descriptor */\r
++    AE531X_CONSUME_DESC((&MACInfo->txQueue));\r
++\r
++    /* Update the descriptor */\r
++    buf = virt_to_bus(skb->data);\r
++    A_DATA_CACHE_FLUSH(skb->data, skb->len);\r
++    AE531X_DESC_BUFPTR_SET(txDesc, buf);\r
++    AE531X_DESC_SWPTR_SET(txDesc, skb);\r
++    ctrlen = AE531X_DESC_CTRLEN_GET(txDesc);\r
++    ctrlen = (ctrlen & (DescEndOfRing)) |\r
++                            DescTxFirst |\r
++                             DescTxLast |\r
++                        DescTxIntEnable;\r
++\r
++    ctrlen |= ((length << DescSize1Shift) & DescSize1Mask);\r
++\r
++    AE531X_DESC_CTRLEN_SET(txDesc, ctrlen);\r
++    AE531X_DESC_STATUS_SET(txDesc, DescOwnByDma);\r
++\r
++    AE531X_PRINT(AE531X_DEBUG_TX,\r
++              ("eth%d Tx: Desc=0x%8.8x, L=0x%8.8x, D=0x%8.8x, d=0x%8.8x, length=0x%8.8x\n",\r
++               dev_sw_state->enetUnit,\r
++               (UINT32)txDesc,\r
++               AE531X_DESC_CTRLEN_GET(txDesc),\r
++               buf,\r
++               AE531X_DESC_LNKBUF_GET(txDesc),\r
++               length));\r
++\r
++    /* Must not use txDesc after this point */\r
++    A_DATA_CACHE_FLUSH_INVAL(txDesc, AE531X_DESC_SIZE);\r
++\r
++    /* Alert DMA engine to resume Tx */\r
++    ae531x_WriteDmaReg(MACInfo, DmaTxPollDemand, 0);\r
++    sysWbFlush();\r
++\r
++    MAC_state->stats.tx_packets++;\r
++    MAC_state->stats.tx_bytes += length;\r
++\r
++    /* Tell upper layers to keep it coming */\r
++    dev->trans_start = jiffies;\r
++\r
++    LEAVE();\r
++    return 0;\r
++\r
++dropFrame:\r
++    dev_kfree_skb(skb);\r
++\r
++    LEAVE();\r
++    return 0;\r
++}\r
++\r
++\r
++/*******************************************************************************\r
++* ae531x_MAC_tx_timeout handles transmit timeouts\r
++*/\r
++static void\r
++ae531x_MAC_tx_timeout(struct net_device *dev)\r
++{\r
++    ae531x_dev_sw_state_t *dev_sw_state;\r
++    ae531x_MAC_state_t *MAC_state;\r
++    ae531x_MAC_t *MACInfo;\r
++\r
++    ARRIVE();\r
++\r
++    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
++    MAC_state = dev_sw_state->MAC_state;\r
++    MACInfo = &MAC_state->MACInfo;\r
++\r
++    AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++             ("enet%d: Tx timeout\n", dev_sw_state->enetUnit));\r
++\r
++    ae531x_restart(MACInfo);\r
++\r
++    LEAVE();\r
++}\r
++\r
++\r
++/*******************************************************************************\r
++* ae531x_MAC_do_ioctl is a placeholder for future ioctls.\r
++*/\r
++static int\r
++ae531x_MAC_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)\r
++{\r
++        int rv;\r
++        ae531x_MAC_t *MACInfo;\r
++        struct ioctl_data {\r
++                u32 unit;\r
++                u32 addr;\r
++                u32 data;\r
++        } *req;\r
++        ae531x_dev_sw_state_t *dev_sw_state;\r
++        ae531x_MAC_state_t *MAC_state;\r
++\r
++        ARRIVE();\r
++\r
++        dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
++        MAC_state = dev_sw_state->MAC_state;\r
++        MACInfo = &MAC_state->MACInfo;\r
++\r
++        req = (struct ioctl_data *)ifr->ifr_data;\r
++\r
++        switch( cmd ) {\r
++        default:\r
++            AE531X_PRINT(AE531X_DEBUG_ERROR,\r
++                     ("Unsupported ioctl: 0x%x\n", cmd));\r
++            rv = -EOPNOTSUPP;\r
++        }\r
++\r
++        LEAVE();\r
++        return rv;\r
++}\r
++\r
++/*******************************************************************************\r
++* ae531x_MAC_set_mac_address sets a new hardware address for the device\r
++*/\r
++static int\r
++ae531x_MAC_set_mac_address(struct net_device *dev, void *addr)\r
++{\r
++      struct sockaddr *saddr = (struct sockaddr *)addr;\r
++\r
++      /* update dev struct */\r
++      memcpy(dev->dev_addr, &saddr->sa_data[0], dev->addr_len);\r
++\r
++      return 0;\r
++}\r
++\r
++/******************************************************************************\r
++* macAddrGet - Given a MACInfo pointer, return a pointer to an\r
++* array of chars that holds the corresponding MAC address.\r
++*/\r
++char *macAddrGet(ae531x_MAC_t *MACInfo)\r
++{\r
++    // return enet_mac_address_get(MACInfo->unit);\r
++    return ae531x_MAC_dev[MACInfo->unit]->dev_addr;\r
++}\r
++\r
++static void\r
++ae531x_MAC_setup_fntable(struct net_device *dev)\r
++{\r
++    /* Set a default (should be overridden by software) */\r
++    u8 default_MAC_address[] = { 0x00, 0x03, 0x7f, 0xe0, 0x02, 0xbF };\r
++\r
++    ARRIVE();\r
++\r
++    dev->get_stats            = ae531x_MAC_get_stats;\r
++    dev->open                 = ae531x_MAC_open;\r
++    dev->stop                 = ae531x_MAC_stop;\r
++    dev->hard_start_xmit      = ae531x_MAC_start_xmit;\r
++    dev->do_ioctl             = ae531x_MAC_do_ioctl;\r
++#ifdef AR531X_NAPI\r
++    dev->poll                 = ae531x_MAC_poll;\r
++    dev->weight                       = 16;\r
++#endif\r
++    dev->tx_timeout           = ae531x_MAC_tx_timeout;\r
++    dev->features             = NETIF_F_HW_CSUM |\\r
++                                 NETIF_F_HIGHDMA;\r
++    dev->set_mac_address      = ae531x_MAC_set_mac_address;\r
++    dev->set_multicast_list   = ae531x_MAC_set_rx_mode;\r
++\r
++    /* Copy default MAC address into device descriptor */\r
++    memcpy(dev->dev_addr, default_MAC_address, dev->addr_len );\r
++\r
++    LEAVE();\r
++}\r
++\r
++/*\r
++ * ae531x_twisted_enet() returns 1 for chips where there is only one usable\r
++ * MAC, and that MAC is 1.\r
++ */\r
++static BOOL\r
++ae531x_twisted_enet(void)\r
++{\r
++    int wisoc_revision;\r
++    int flash_bus_width;\r
++\r
++    wisoc_revision = (sysRegRead(AR531X_REV) & AR531X_REV_MAJ) >>\r
++                                                             AR531X_REV_MAJ_S;\r
++    if (wisoc_revision == AR531X_REV_MAJ_AR2313)\r
++        return TRUE;\r
++\r
++    flash_bus_width = sysRegRead(AR531X_FLASHCTL0) & FLASHCTL_MWx16;\r
++\r
++    if (flash_bus_width == 0) {\r
++      printk("Found AR2312-01\n");\r
++      return TRUE;            /* AR2312-01 has 8 bit flash bus */\r
++    } else {\r
++      printk("Found AR2312-00\n");\r
++      return FALSE;\r
++    }\r
++}\r
++\r
++int\r
++ae531x_MAC_setup(void)\r
++{\r
++    int i;\r
++    int next_dev;\r
++    int rev;\r
++    struct net_device *dev;\r
++    ae531x_dev_sw_state_t *dev_sw_state;\r
++    ae531x_MAC_state_t *MAC_state;\r
++    ae531x_MAC_t *MACInfo;\r
++\r
++    ARRIVE();\r
++\r
++#if 0\r
++    /*\r
++     * This does not work since the AR2312 and AR5312 both have the same\r
++     * revision information in the CPU :-(\r
++     */\r
++    rev = (sysRegRead(AR531X_REV) & AR531X_REV_CHIP);\r
++\r
++    if ((rev & AR531X_REV_MIN) == AR5312_REV_MIN_SINGLE_ENET) {\r
++      ar531x_num_enet_macs = 1;\r
++    } else {\r
++      ar531x_num_enet_macs = 2;\r
++    }\r
++#else\r
++    /*\r
++     * Need to select the number of ethernet MACs based on the config\r
++     * information (sadly)\r
++     */\r
++#ifdef CONFIG_AR5312\r
++    ar531x_num_enet_macs = 2;\r
++#else\r
++    ar531x_num_enet_macs = 1;\r
++#endif\r
++#endif\r
++\r
++    next_dev = 0;\r
++    for (i=0; i<ar531x_num_enet_macs; i++) {\r
++\r
++        dev = ae531x_MAC_dev[next_dev] =\r
++            init_etherdev(NULL, sizeof(ae531x_dev_sw_state_t));\r
++\r
++        if (dev == NULL) {\r
++            LEAVE();\r
++            return -1;\r
++        }\r
++\r
++        ae531x_MAC_setup_fntable(dev);\r
++\r
++        dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
++        dev_sw_state->enetUnit = next_dev;\r
++        dev_sw_state->unit_on_MAC = 0;\r
++        MAC_state = &per_MAC_info[i];\r
++        dev_sw_state->MAC_state = MAC_state;\r
++        MAC_state->dev_sw_state[AE531X_LAN_PORT] = dev_sw_state;\r
++        MAC_state->primary_dev = -1;\r
++\r
++        next_dev++;\r
++\r
++#ifdef CONFIG_VENETDEV\r
++        {\r
++            ae531x_dev_sw_state_t *lan_dev_sw_state;\r
++\r
++            lan_dev_sw_state = dev_sw_state;\r
++    \r
++            dev = ae531x_MAC_dev[next_dev] =\r
++                init_etherdev(NULL, sizeof(ae531x_dev_sw_state_t));\r
++\r
++            if (dev == NULL) {\r
++                LEAVE();\r
++                return -1;\r
++            }\r
++    \r
++            ae531x_MAC_setup_fntable(dev);\r
++    \r
++            dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
++            dev_sw_state->enetUnit = next_dev;\r
++            dev_sw_state->unit_on_MAC = 1;\r
++            dev_sw_state->MAC_state = MAC_state;\r
++            MAC_state->dev_sw_state[AE531X_WAN_PORT] = dev_sw_state;\r
++            lan_dev_sw_state->isLAN = TRUE; /* enet0 is LAN */\r
++            dev_sw_state->isLAN = FALSE ;     /* enet1 is WAN */\r
++\r
++            next_dev++;\r
++        }\r
++#endif\r
++\r
++        /* Initialize per-MAC information */\r
++        MACInfo = &MAC_state->MACInfo;\r
++        MACInfo->unit = i;\r
++\r
++      if (ar531x_num_enet_macs == 1) {\r
++          if (ae531x_twisted_enet()) {\r
++                MACInfo->macBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_MAC_OFFSET);\r
++                MACInfo->dmaBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_DMA_OFFSET);\r
++                MACInfo->phyBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET);\r
++                MAC_state->irq = AR531X_IRQ_ENET1_INTRS;\r
++          } else {\r
++                MACInfo->macBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_MAC_OFFSET);\r
++                MACInfo->dmaBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_DMA_OFFSET);\r
++                MACInfo->phyBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET);\r
++                MAC_state->irq = AR531X_IRQ_ENET0_INTRS;\r
++          }\r
++      } else {\r
++            if (MACInfo->unit == 0) {\r
++                MACInfo->macBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_MAC_OFFSET);\r
++                MACInfo->dmaBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_DMA_OFFSET);\r
++                MACInfo->phyBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET);\r
++                MAC_state->irq = AR531X_IRQ_ENET0_INTRS;\r
++            } else {\r
++                MACInfo->macBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_MAC_OFFSET);\r
++                MACInfo->dmaBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_DMA_OFFSET);\r
++                MACInfo->phyBase =\r
++                      (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_PHY_OFFSET);\r
++                MAC_state->irq = AR531X_IRQ_ENET1_INTRS;\r
++            }\r
++      }\r
++        MACInfo->OSinfo = (void *)MAC_state;\r
++    }\r
++\r
++    LEAVE();\r
++    return 0;\r
++}\r
++\r
++module_init(ae531x_MAC_setup);\r
++\r
+diff -urN linux-2.4.32.new/arch/mips/ar531x/ae531xmac.c linux-2.4.32.new-eth/arch/mips/ar531x/ae531xmac.c\r
+--- linux-2.4.32.new/arch/mips/ar531x/ae531xmac.c      1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new-eth/arch/mips/ar531x/ae531xmac.c  2005-12-25 11:54:20.771271672 +0000\r
+@@ -0,0 +1,942 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++\r
++/*\r
++ * Ethernet driver for Atheros' ae531x ethernet MAC.\r
++ */\r
++\r
++#if linux\r
++#include <linux/config.h>\r
++#include <linux/types.h>\r
++#include <linux/delay.h>\r
++#include <linux/netdevice.h>\r
++#include <linux/etherdevice.h>\r
++#include <linux/init.h>\r
++#include <asm/io.h>\r
++\r
++#include "ar531xlnx.h"\r
++#endif /* linux */\r
++\r
++#include "ae531xreg.h"\r
++#include "ae531xmac.h"\r
++\r
++int ae531x_MAC_debug = AE531X_DEBUG_ERROR;\r
++\r
++/*\r
++ * These externs are for functions that this layer relies on\r
++ * that have OS-dependent implementations.\r
++ */\r
++extern UINT8 *macAddrGet(ae531x_MAC_t *MACInfo);\r
++\r
++/* Forward references to local functions */\r
++static void ae531x_QueueDestroy(AE531X_QUEUE *q);\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_ReadMacReg - read AE MAC register\r
++*\r
++* RETURNS: register value\r
++*/\r
++UINT32\r
++ae531x_ReadMacReg(ae531x_MAC_t *MACInfo, UINT32 reg)\r
++{\r
++    UINT32 addr = MACInfo->macBase+reg;\r
++    UINT32 data;\r
++\r
++    data = RegRead(addr);\r
++    return data;\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_WriteMacReg - write AE MAC register\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_WriteMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data)\r
++{\r
++    UINT32 addr = MACInfo->macBase+reg;\r
++\r
++    RegWrite(data, addr);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_SetMacReg - set bits in AE MAC register\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_SetMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)\r
++{\r
++    UINT32 addr = MACInfo->macBase+reg;\r
++    UINT32 data = RegRead(addr);\r
++\r
++    data |= val;\r
++    RegWrite(data, addr);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_ClearMacReg - clear bits in AE MAC register\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_ClearMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)\r
++{\r
++    UINT32 addr = MACInfo->macBase+reg;\r
++    UINT32 data = RegRead(addr);\r
++\r
++    data &= ~val;\r
++    RegWrite(data, addr);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_ReadDmaReg - read AE DMA register\r
++*\r
++* RETURNS: register value\r
++*/\r
++UINT32\r
++ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg)\r
++{\r
++    UINT32 addr = MACInfo->dmaBase+reg;\r
++    UINT32 data = RegRead(addr);\r
++\r
++    return data;\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_WriteDmaReg - write AE DMA register\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data)\r
++{\r
++    UINT32 addr = MACInfo->dmaBase+reg;\r
++\r
++    RegWrite(data, addr);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++ *\r
++ * ae531x_AckIntr - clear interrupt bits in the status register.\r
++ * Note: Interrupt bits are *cleared* by writing a 1.\r
++ */\r
++void\r
++ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 data)\r
++{\r
++      ae531x_WriteDmaReg(MACInfo, DmaStatus, data);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_SetDmaReg - set bits in an AE DMA register\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)\r
++{\r
++    UINT32 addr = MACInfo->dmaBase+reg;\r
++    UINT32 data = RegRead(addr);\r
++\r
++    data |= val;\r
++    RegWrite(data, addr);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_ClearDmaReg - clear bits in an AE DMA register\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)\r
++{\r
++    UINT32 addr = MACInfo->dmaBase+reg;\r
++    UINT32 data = RegRead(addr);\r
++\r
++    data &= ~val;\r
++    RegWrite(data, addr);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_ReadMiiReg - read PHY registers via AE MAC Mii addr/data registers\r
++*\r
++* RETURNS: register value\r
++*/\r
++UINT32\r
++ae531x_ReadMiiReg(UINT32 phyBase, UINT32 reg)\r
++{\r
++    UINT32 data;\r
++    UINT32 addr = phyBase+reg;\r
++\r
++    data = RegRead(addr);\r
++    return data;\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_WriteMiiReg - write PHY registers via AE MAC Mii addr/data registers\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_WriteMiiReg(UINT32 phyBase, UINT32 reg, UINT32 data)\r
++{\r
++    UINT32 addr = phyBase+reg;\r
++\r
++    RegWrite(data, addr);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_MiiRead - read AE Mii register\r
++*\r
++* RETURNS: register value\r
++*/\r
++UINT16\r
++ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg)\r
++{\r
++    UINT32 addr;\r
++    UINT16 data;\r
++\r
++    addr = ((phyAddr << MiiDevShift) & MiiDevMask) | ((reg << MiiRegShift) & MiiRegMask);\r
++\r
++    ae531x_WriteMiiReg(phyBase, MacMiiAddr, addr );\r
++    do {\r
++        /* nop */\r
++    } while ((ae531x_ReadMiiReg(phyBase, MacMiiAddr ) & MiiBusy) == MiiBusy);\r
++\r
++    data = ae531x_ReadMiiReg(phyBase, MacMiiData) & 0xFFFF;\r
++\r
++    return data;\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_MiiWrite - write AE Mii register\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, UINT16 data)\r
++{\r
++    UINT32 addr;\r
++\r
++    ae531x_WriteMiiReg(phyBase, MacMiiData, data );\r
++\r
++    addr = ((phyAddr << MiiDevShift) & MiiDevMask) |\r
++        ((reg << MiiRegShift) & MiiRegMask) | MiiWrite;\r
++    ae531x_WriteMiiReg(phyBase, MacMiiAddr, addr );\r
++\r
++    do {\r
++        /* nop */\r
++    } while ((ae531x_ReadMiiReg(phyBase, MacMiiAddr ) & MiiBusy) == MiiBusy);\r
++}\r
++\r
++\r
++/*******************************************************************************\r
++* ae531x_BeginResetMode - enter a special "reset mode" in which\r
++*    -no interrupts are expected from the device\r
++*    -the device will not transmit nor receive\r
++*    -attempts to send or receive will return with an error and\r
++*    -the device will be reset at the next convenient opportunity.\r
++*/\r
++void\r
++ae531x_BeginResetMode(ae531x_MAC_t *MACInfo)\r
++{\r
++    /* Set the reset flag */\r
++    MACInfo->aeProcessRst = 1;\r
++}\r
++\r
++\r
++/*******************************************************************************\r
++* ae531x_EndResetMode - exit the special "reset mode" entered\r
++* earlier via a call to ae531x_BeginResetMode.\r
++*/\r
++void\r
++ae531x_EndResetMode(ae531x_MAC_t *MACInfo)\r
++{\r
++    MACInfo->aeProcessRst = 0;\r
++}\r
++\r
++\r
++/*******************************************************************************\r
++* ae531x_IsInResetMode - determine whether or not the device is\r
++* currently in "reset mode" (i.e. that a device reset is pending)\r
++*/\r
++BOOL\r
++ae531x_IsInResetMode(ae531x_MAC_t *MACInfo)\r
++{\r
++    return MACInfo->aeProcessRst;\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_DmaRxStart - Start Rx\r
++*\r
++* RETURNS: N/A\r
++*/\r
++static void\r
++ae531x_DmaRxStart(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_SetDmaReg(MACInfo, DmaControl, DmaRxStart);\r
++    sysWbFlush();\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_DmaRxStop - Stop Rx\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_DmaRxStop(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_ClearDmaReg(MACInfo, DmaControl, DmaRxStart);\r
++    sysWbFlush();\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_DmaTxStart - Start Tx\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_DmaTxStart(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_SetDmaReg(MACInfo, DmaControl, DmaTxStart);\r
++    sysWbFlush();\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_DmaTxStop - Stop Tx\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_DmaTxStop(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_ClearDmaReg(MACInfo, DmaControl, DmaTxStart);\r
++    sysWbFlush();\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_DmaIntEnable - Enable DMA interrupts\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntEnable);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_DmaIntDisable - Disable DMA interrupts\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_DmaIntClear - Clear DMA interrupts\r
++*\r
++* RETURNS: N/A\r
++*/\r
++static void\r
++ae531x_DmaIntClear(ae531x_MAC_t *MACInfo)\r
++{\r
++    /* clear all interrupt requests */\r
++    ae531x_WriteDmaReg(MACInfo, DmaStatus,\r
++                      ae531x_ReadDmaReg(MACInfo, DmaStatus));  \r
++}\r
++\r
++\r
++/******************************************************************************\r
++* Initialize generic queue data\r
++*/\r
++void\r
++ae531x_QueueInit(AE531X_QUEUE *q, char *pMem, int count)\r
++{\r
++    ARRIVE();\r
++    q->firstDescAddr = pMem;\r
++    q->lastDescAddr = (VIRT_ADDR)((UINT32)q->firstDescAddr +\r
++                                  (count - 1) * AE531X_QUEUE_ELE_SIZE);\r
++    q->curDescAddr = q->firstDescAddr;\r
++    q->count = count;\r
++    LEAVE();\r
++}\r
++\r
++\r
++/******************************************************************************\r
++* ae531x_TxQueueCreate - create a circular queue of descriptors for Transmit\r
++*/\r
++static int\r
++ae531x_TxQueueCreate(ae531x_MAC_t *MACInfo,\r
++                  AE531X_QUEUE *q,\r
++                  char *pMem,\r
++                  int count)\r
++{\r
++    int         i;\r
++    VIRT_ADDR   descAddr;\r
++\r
++    ARRIVE();\r
++\r
++    ae531x_QueueInit(q, pMem, count);\r
++    q->reapDescAddr = q->lastDescAddr;\r
++\r
++    /* Initialize Tx buffer descriptors.  */\r
++    for (i=0, descAddr=q->firstDescAddr;\r
++         i<count;\r
++         i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE))\r
++    {\r
++        /* Update the size, BUFPTR, and SWPTR fields */\r
++\r
++        AE531X_DESC_STATUS_SET(descAddr, 0);\r
++        AE531X_DESC_CTRLEN_SET(descAddr, 0);\r
++\r
++        AE531X_DESC_BUFPTR_SET(descAddr, (UINT32)0);\r
++        AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0);\r
++        AE531X_DESC_SWPTR_SET(descAddr, (void *)0);\r
++    } /* for each desc */\r
++\r
++    /* Make the queue circular */\r
++    AE531X_DESC_CTRLEN_SET(q->lastDescAddr,\r
++                       DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr));\r
++\r
++    AE531X_PRINT(AE531X_DEBUG_RESET,\r
++            ("ethmac%d Txbuf begin = %x, end = %x\n",\r
++            MACInfo->unit,\r
++            (UINT32)q->firstDescAddr,\r
++            (UINT32)q->lastDescAddr));\r
++\r
++    LEAVE();\r
++    return 0;\r
++}\r
++\r
++\r
++/******************************************************************************\r
++* ae531x_RxQueueCreate - create a circular queue of Rx descriptors\r
++*/\r
++int\r
++ae531x_RxQueueCreate(ae531x_MAC_t *MACInfo,\r
++                  AE531X_QUEUE *q,\r
++                  char *pMem,\r
++                  int count)\r
++{\r
++    int               i;\r
++    VIRT_ADDR         descAddr;\r
++\r
++    ARRIVE();\r
++\r
++    ae531x_QueueInit(q, pMem, count);\r
++    q->reapDescAddr = NULL;\r
++\r
++\r
++    /* Initialize Rx buffer descriptors */\r
++    for (i=0, descAddr=q->firstDescAddr;\r
++         i<count;\r
++         i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE))\r
++    {\r
++        void *swptr;\r
++        char *rxBuffer;\r
++        int  rxBufferSize;\r
++\r
++        swptr = ae531x_rxbuf_alloc(MACInfo, &rxBuffer, &rxBufferSize);\r
++        if (swptr == NULL) {\r
++                AE531X_PRINT(AE531X_DEBUG_RESET,\r
++                          ("ethmac%d RX queue: ae531x_rxbuf_alloc failed\n",\r
++                           MACInfo->unit));\r
++                ae531x_QueueDestroy(q);\r
++                return -1;\r
++        }\r
++        AE531X_DESC_SWPTR_SET(descAddr, swptr);\r
++\r
++        AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma);\r
++        AE531X_DESC_CTRLEN_SET(descAddr, rxBufferSize);\r
++        AE531X_DESC_BUFPTR_SET(descAddr, virt_to_bus(rxBuffer));\r
++        AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0);\r
++    } /* for each desc */\r
++\r
++    /* Make the queue circular */\r
++    AE531X_DESC_CTRLEN_SET(q->lastDescAddr,\r
++                       DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr));\r
++\r
++    AE531X_PRINT(AE531X_DEBUG_RESET,\r
++              ("ethmac%d Rxbuf begin = %x, end = %x\n",\r
++              MACInfo->unit,\r
++              (UINT32)q->firstDescAddr,\r
++              (UINT32)q->lastDescAddr));\r
++\r
++    LEAVE();\r
++    return 0;\r
++}\r
++\r
++\r
++/******************************************************************************\r
++* ae531x_QueueDestroy -- Free all buffers and descriptors associated \r
++* with a queue.\r
++*/\r
++static void\r
++ae531x_QueueDestroy(AE531X_QUEUE *q)\r
++{\r
++    int i;\r
++    int count;\r
++    VIRT_ADDR    descAddr;\r
++\r
++    ARRIVE();\r
++\r
++    count = q->count;\r
++\r
++    for (i=0, descAddr=q->firstDescAddr;\r
++         i<count;\r
++         i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE)) {\r
++\r
++        AE531X_DESC_STATUS_SET(descAddr, 0);\r
++        AE531X_DESC_CTRLEN_SET(descAddr, 0);\r
++        AE531X_DESC_BUFPTR_SET(descAddr, (UINT32)0);\r
++        AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0);\r
++\r
++        ae531x_swptr_free(descAddr); /* Free OS-specific software pointer */\r
++    }\r
++\r
++    LEAVE();\r
++}\r
++\r
++static void\r
++ae531x_TxQueueDestroy(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_QueueDestroy(&MACInfo->txQueue);\r
++}\r
++\r
++static void\r
++ae531x_RxQueueDestroy(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_QueueDestroy(&MACInfo->rxQueue);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++* ae531x_AllocateQueues - Allocate receive and transmit queues\r
++*/\r
++int\r
++ae531x_AllocateQueues(ae531x_MAC_t *MACInfo)\r
++{\r
++    size_t QMemSize;\r
++    char *pTxBuf = NULL;\r
++    char *pRxBuf = NULL;\r
++\r
++    ARRIVE();\r
++\r
++    MACInfo->txDescCount = AE531X_TX_DESC_COUNT_DEFAULT;\r
++    QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->txDescCount;\r
++    pTxBuf = MALLOC(QMemSize);\r
++    if (pTxBuf == NULL) {\r
++        AE531X_PRINT(AE531X_DEBUG_RESET,\r
++                  ("ethmac%d Failed to allocate TX queue\n", MACInfo->unit));\r
++        goto AllocQFail;\r
++    }\r
++\r
++    if (ae531x_TxQueueCreate(MACInfo, &MACInfo->txQueue, pTxBuf,\r
++                          MACInfo->txDescCount) < 0)\r
++    {\r
++        AE531X_PRINT(AE531X_DEBUG_RESET,\r
++                ("ethmac%d Failed to create TX queue\n", MACInfo->unit));\r
++        goto AllocQFail;\r
++    }\r
++\r
++    MACInfo->rxDescCount = AE531X_RX_DESC_COUNT_DEFAULT;\r
++    QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->rxDescCount;\r
++    pRxBuf = MALLOC(QMemSize);\r
++    if (pRxBuf == NULL) {\r
++        AE531X_PRINT(AE531X_DEBUG_RESET,\r
++                  ("ethmac%d Failed to allocate RX queue\n", MACInfo->unit));\r
++        goto AllocQFail;\r
++    }\r
++\r
++    if (ae531x_RxQueueCreate(MACInfo, &MACInfo->rxQueue, pRxBuf,\r
++                          MACInfo->rxDescCount) < 0)\r
++    {\r
++        AE531X_PRINT(AE531X_DEBUG_RESET,\r
++                ("ethmac%d Failed to create RX queue\n", MACInfo->unit));\r
++        goto AllocQFail;\r
++    }\r
++\r
++    AE531X_PRINT(AE531X_DEBUG_RESET,\r
++            ("ethmac%d Memory setup complete.\n", MACInfo->unit));\r
++\r
++    LEAVE();\r
++    return 0;\r
++\r
++AllocQFail:\r
++    MACInfo->txDescCount = 0; /* sanity */\r
++    MACInfo->rxDescCount = 0; /* sanity */\r
++\r
++    if (pTxBuf) {\r
++        FREE(pTxBuf);\r
++    }\r
++    if (pRxBuf) {\r
++        FREE(pRxBuf);\r
++    }\r
++    \r
++    LEAVE();\r
++    return -1;\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_FreeQueues - Free Transmit & Receive queues\r
++*/\r
++void\r
++ae531x_FreeQueues(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_TxQueueDestroy(MACInfo);\r
++    FREE(MACInfo->txQueue.firstDescAddr);\r
++\r
++    ae531x_RxQueueDestroy(MACInfo);\r
++    FREE(MACInfo->rxQueue.firstDescAddr);\r
++}\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_DmaReset - Reset DMA and TLI controllers\r
++*\r
++* RETURNS: N/A\r
++*/\r
++void\r
++ae531x_DmaReset(ae531x_MAC_t *MACInfo)\r
++{\r
++    int        i;\r
++    UINT32     descAddr;\r
++\r
++    ARRIVE();\r
++\r
++    /* Disable device interrupts prior to any errors during stop */\r
++    intDisable(MACInfo->ilevel);\r
++\r
++    /* Disable MAC rx and tx */\r
++    ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable));\r
++\r
++    /* Reset dma controller */\r
++    ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaResetOn);\r
++\r
++    /* Delay 2 usec */\r
++    sysUDelay(2);\r
++\r
++    /* Flush the rx queue */\r
++    descAddr = (UINT32)MACInfo->rxQueue.firstDescAddr;\r
++    MACInfo->rxQueue.curDescAddr = MACInfo->rxQueue.firstDescAddr;\r
++    for (i=0;\r
++         i<(MACInfo->rxDescCount);\r
++         i++, descAddr += AE531X_QUEUE_ELE_SIZE) {\r
++            AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma);\r
++    }\r
++\r
++    /* Flush the tx queue */\r
++    descAddr = (UINT32)MACInfo->txQueue.firstDescAddr;\r
++    MACInfo->txQueue.curDescAddr = MACInfo->txQueue.firstDescAddr;\r
++    MACInfo->txQueue.reapDescAddr = MACInfo->txQueue.lastDescAddr;\r
++    for (i=0;\r
++         i<(MACInfo->txDescCount);\r
++         i++, descAddr += AE531X_QUEUE_ELE_SIZE) {\r
++            AE531X_DESC_STATUS_SET (descAddr, 0);\r
++    }\r
++\r
++    /* Set init register values  */\r
++    ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaBusModeInit);\r
++\r
++    /* Install the first Tx and Rx queues on the device */\r
++    ae531x_WriteDmaReg(MACInfo, DmaRxBaseAddr,\r
++                      (UINT32)MACInfo->rxQueue.firstDescAddr);\r
++    ae531x_WriteDmaReg(MACInfo, DmaTxBaseAddr,\r
++                      (UINT32)MACInfo->txQueue.firstDescAddr);\r
++\r
++    ae531x_WriteDmaReg(MACInfo, DmaControl, DmaStoreAndForward);\r
++\r
++    ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable);\r
++\r
++    AE531X_PRINT(AE531X_DEBUG_RESET,\r
++              ("ethmac%d: DMA RESET!\n", MACInfo->unit));\r
++\r
++    /* Turn on device interrupts -- enable most errors */\r
++    ae531x_DmaIntClear(MACInfo);    /* clear interrupt requests  */\r
++    ae531x_DmaIntEnable(MACInfo);   /* enable interrupts */\r
++    /* Enable receive interrupts separately (they are not part\r
++     * of the main group since they are enabled & disabled by\r
++     * the polling routine.\r
++     */\r
++    ae531x_SetDmaReg(MACInfo, DmaIntrEnb,\r
++              (DmaIntRxNoBuffer | DmaIntRxCompleted));\r
++\r
++    ae531x_EndResetMode(MACInfo);\r
++\r
++    intEnable(MACInfo->ilevel);\r
++\r
++    LEAVE();\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae531x_MACAddressSet - Set the ethernet address\r
++*\r
++* Sets the ethernet address according to settings in flash.\r
++*\r
++* RETURNS: void\r
++*/\r
++static void\r
++ae531x_MACAddressSet(ae531x_MAC_t *MACInfo)\r
++{\r
++    unsigned int    data;\r
++    UINT8 *macAddr;\r
++\r
++    ARRIVE();\r
++        \r
++    macAddr = macAddrGet(MACInfo);\r
++\r
++    /* set our MAC address  */\r
++    data = (macAddr[5]<<8) | macAddr[4];\r
++    ae531x_WriteMacReg(MACInfo, MacAddrHigh, data );\r
++\r
++    data = (macAddr[3]<<24) | (macAddr[2]<<16) | (macAddr[1]<<8) | macAddr[0];\r
++    ae531x_WriteMacReg(MACInfo, MacAddrLow, data );\r
++\r
++    AE531X_PRINT(AE531X_DEBUG_RESET,\r
++              ("ethmac%d Verify MAC address %8.8X %8.8X \n",\r
++               MACInfo->unit,\r
++               ae531x_ReadMacReg(MACInfo, MacAddrLow),\r
++               ae531x_ReadMacReg(MACInfo, MacAddrHigh)));\r
++\r
++    AE531X_PRINT(AE531X_DEBUG_RESET,\r
++              ("  sb = %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",\r
++               0xff&macAddr[0],\r
++               0xff&macAddr[1],\r
++               0xff&macAddr[2],\r
++               0xff&macAddr[3],\r
++               0xff&macAddr[4],\r
++               0xff&macAddr[5]));\r
++    LEAVE();\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* ae_SetMACFromPhy - read Phy settings and update Mac\r
++*                    with current duplex and speed.\r
++*\r
++* RETURNS:\r
++*/\r
++static void\r
++ae531x_SetMACFromPhy(ae531x_MAC_t *MACInfo)\r
++{\r
++    UINT32  macCtl;\r
++    BOOL    fullDuplex;\r
++\r
++    ARRIVE();\r
++\r
++    /* Get duplex mode from Phy */\r
++    fullDuplex = phyIsFullDuplex(MACInfo->unit);\r
++\r
++    /* Flag is set for full duplex mode, else cleared */\r
++    macCtl = ae531x_ReadMacReg(MACInfo, MacControl);\r
++\r
++    if (fullDuplex) {\r
++        /* set values of control registers */\r
++        macCtl &= ~MacDisableRxOwn;\r
++        macCtl |= MacFullDuplex;\r
++        ae531x_WriteMacReg(MACInfo, MacControl, macCtl);\r
++        ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitFdx);\r
++#if 0\r
++      printk ("[Full Duplex] CTRL=%#x FLOW=%#x\n", macCtl,\r
++              MacFlowControlInitFdx);\r
++#endif\r
++    } else {\r
++        /* set values of control registers */\r
++        ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitHdx);\r
++        macCtl |= MacDisableRxOwn;\r
++        macCtl &= ~MacFullDuplex;\r
++        ae531x_WriteMacReg(MACInfo, MacControl, macCtl);\r
++#if 0\r
++      printk ("[Half Duplex] CTRL=%#x FLOW=%#x\n", macCtl,\r
++              MacFlowControlInitHdx);\r
++#endif\r
++    }\r
++\r
++    LEAVE();\r
++}\r
++\r
++\r
++/******************************************************************************\r
++* ae531x_MACReset -- sets MAC address and duplex.\r
++*/\r
++void\r
++ae531x_MACReset(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_MACAddressSet(MACInfo);\r
++\r
++    ae531x_SetMACFromPhy(MACInfo);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++* ae531x_EnableComm -- enable Transmit and Receive\r
++*/\r
++void\r
++ae531x_EnableComm(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_SetMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable));\r
++    ae531x_DmaRxStart(MACInfo);     /* start receiver  */\r
++    ae531x_DmaTxStart(MACInfo);     /* start transmitter */\r
++}\r
++\r
++\r
++/******************************************************************************\r
++* ae531x_DisableComm -- disable Transmit and Receive\r
++*/\r
++void\r
++ae531x_DisableComm(ae531x_MAC_t *MACInfo)\r
++{\r
++    ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable));\r
++}\r
++\r
++\r
++/******************************************************************************\r
++* ae531x_reset -- Cold reset ethernet interface\r
++*/\r
++void\r
++ae531x_reset(ae531x_MAC_t *MACInfo)\r
++{\r
++    UINT32 mask = 0;\r
++    UINT32 regtmp;\r
++   \r
++    if (ar531x_num_enet_macs == 2) {\r
++        if (MACInfo->unit == 0) {\r
++            mask = AR531X_RESET_ENET0 | AR531X_RESET_EPHY0;\r
++        } else {\r
++            mask = AR531X_RESET_ENET1 | AR531X_RESET_EPHY1;\r
++        }\r
++    } else {\r
++            mask = AR531X_RESET_ENET0 | AR531X_RESET_EPHY0 |\r
++                   AR531X_RESET_ENET1 | AR531X_RESET_EPHY1;\r
++    }\r
++\r
++    /* Put into reset */\r
++    regtmp = sysRegRead(AR531X_RESET);\r
++    sysRegWrite(AR531X_RESET, regtmp | mask);\r
++    sysMsDelay(15);\r
++\r
++    /* Pull out of reset */\r
++    regtmp = sysRegRead(AR531X_RESET);\r
++    sysRegWrite(AR531X_RESET, regtmp & ~mask);\r
++    sysUDelay(25);\r
++\r
++    /* Enable */\r
++    if (ar531x_num_enet_macs == 2) {\r
++        if (MACInfo->unit == 0) {\r
++            mask = AR531X_ENABLE_ENET0;\r
++        } else {\r
++            mask = AR531X_ENABLE_ENET1;\r
++        }\r
++    } else {\r
++            mask = AR531X_ENABLE_ENET0 | AR531X_ENABLE_ENET1;\r
++    }\r
++    regtmp = sysRegRead(AR531X_ENABLE);\r
++    sysRegWrite(AR531X_ENABLE, regtmp | mask);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++* ae531x_unitLinkLost -- Called from PHY layer to notify the MAC layer\r
++* that there are no longer any live links associated with a MAC.\r
++*/\r
++void\r
++ae531x_unitLinkLost(int ethUnit)\r
++{\r
++    AE531X_PRINT(AE531X_DEBUG_LINK_CHANGE,\r
++             ("enetmac%d link down\n", ethUnit));\r
++}\r
++\r
++\r
++/******************************************************************************\r
++* ae531x_unitLinkGained -- Called from PHY layer to notify the MAC layer\r
++* that there are 1 or more live links associated with a MAC.\r
++*/\r
++void\r
++ae531x_unitLinkGained(int ethUnit)\r
++{\r
++    AE531X_PRINT(AE531X_DEBUG_LINK_CHANGE,\r
++             ("enet%d link up\n", ethUnit));\r
++}\r
++\r
++/******************************************************************************\r
++* ae531x_ethMacDefault -- Called from PHY layer to determine the default\r
++* ethernet MAC.  On some "twisted" platforms, the only usable MAC is 1,\r
++* while on others the usable MAC is 0.  Future boards may allow both MACs\r
++* to be used; in this case, return -1 to indicate that there IS NO default\r
++* MAC.\r
++*\r
++* Note: one some AR2312 platforms the PHY needs to be accessed through\r
++* MAC 0, even though the MAC itself is addressed through MAC 1. Since this\r
++* function is used by the PHY layer to determine which MAC it should use,\r
++* the twisted case is limited to the one where the PHY is actually addressed\r
++* through MAC 1 rather than MAC 0.\r
++*/\r
++int\r
++ae531x_ethMacDefault(void)\r
++{\r
++    /*\r
++     * Where there are two MACs, there is no real default\r
++     */\r
++    if (ar531x_num_enet_macs == 2)\r
++        return -1;\r
++\r
++    /*\r
++     * All single MAC platforms seem to address the PHY through MAC 0,\r
++     * even when they use MAC 1 for the actual MAC functions.\r
++     */\r
++    return 0;\r
++}\r
+diff -urN linux-2.4.32.new/arch/mips/ar531x/ae531xmac.h linux-2.4.32.new-eth/arch/mips/ar531x/ae531xmac.h\r
+--- linux-2.4.32.new/arch/mips/ar531x/ae531xmac.h      1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new-eth/arch/mips/ar531x/ae531xmac.h  2005-12-25 11:54:20.819264376 +0000\r
+@@ -0,0 +1,208 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++/*\r
++ * See README to understand the decomposition of the ethernet driver.\r
++ *\r
++ * This file contains OS-independent pure software definitions for\r
++ * ethernet support on the AR531X platform.\r
++ */\r
++\r
++#ifndef _AE531XMAC_H_\r
++#define _AE531XMAC_H_\r
++\r
++/*\r
++ * DEBUG switches to control verbosity.\r
++ * Just modify the value of ae531x_MAC_debug.\r
++ */\r
++#define AE531X_DEBUG_ALL         0xffffffff\r
++#define AE531X_DEBUG_ERROR       0x00000001 /* Unusual conditions and Errors */\r
++#define AE531X_DEBUG_ARRIVE      0x00000002 /* Arrive into a function */\r
++#define AE531X_DEBUG_LEAVE       0x00000004 /* Leave a function */\r
++#define AE531X_DEBUG_RESET       0x00000008 /* Reset */\r
++#define AE531X_DEBUG_TX          0x00000010 /* Transmit */\r
++#define AE531X_DEBUG_TX_REAP     0x00000020 /* Transmit Descriptor Reaping */\r
++#define AE531X_DEBUG_RX          0x00000040 /* Receive */\r
++#define AE531X_DEBUG_RX_STOP     0x00000080 /* Receive Early Stop */\r
++#define AE531X_DEBUG_INT         0x00000100 /* Interrupts */\r
++#define AE531X_DEBUG_LINK_CHANGE 0x00000200 /* PHY Link status changed */\r
++\r
++extern int ae531x_MAC_debug;\r
++\r
++extern int ar531x_num_enet_macs;\r
++\r
++#define AE531X_PRINT(FLG, X)                            \\r
++{                                                   \\r
++    if (ae531x_MAC_debug & (FLG)) {                  \\r
++        DEBUG_PRINTF("%s#%d:%s ",                   \\r
++                     __FILE__,                      \\r
++                     __LINE__,                      \\r
++                     __FUNCTION__);                 \\r
++        DEBUG_PRINTF X;                             \\r
++    }                                               \\r
++}\r
++\r
++#define ARRIVE() AE531X_PRINT(AE531X_DEBUG_ARRIVE, ("Arrive{\n"))\r
++#define LEAVE() AE531X_PRINT(AE531X_DEBUG_LEAVE, ("}Leave\n"))\r
++\r
++#define RegRead(addr) \\r
++      (*(volatile unsigned int *)(addr))\r
++\r
++#define RegWrite(val,addr)    \\r
++      ((*(volatile unsigned int *)(addr)) = (val))\r
++\r
++/*****************************************************************\r
++ * Phy code is broken out into a separate layer, so that different\r
++ * PHY hardware can easily be supported.\r
++ *\r
++ * These functions are provided by the PHY layer for use by the MAC layer.\r
++ *   phySetup             -- Set phy hardware appropriately for a MAC unit\r
++ *\r
++ *   phyCheckStatusChange -- Look for dropped/initiated links on any\r
++ *                           phy port associated with a MAC unit\r
++ *\r
++ *   phyIsSpeed100        -- Determines whether or not a PHY is up and\r
++ *                           running at 100Mbit\r
++ *\r
++ *   phyIsFullDuplex      -- Determines whether or not a PHY is up and\r
++ *                           running in Full Duplex mode\r
++ *\r
++ */\r
++#ifdef CONFIG_MARVELL_ENET_PHY\r
++/*\r
++ * Mapping of generic phy APIs to Marvell Ethernet Switch phy functions.\r
++ */\r
++#include "mvPhy.h"\r
++#define phySetup(ethUnit, phyBase)      mv_phySetup((ethUnit), (phyBase))\r
++#define phyCheckStatusChange(ethUnit)   mv_phyCheckStatusChange(ethUnit)\r
++#define phyIsSpeed100(ethUnit)          mv_phyIsSpeed100(ethUnit)\r
++#define phyIsFullDuplex(ethUnit)        mv_phyIsFullDuplex(ethUnit)\r
++\r
++#ifdef CONFIG_VENETDEV\r
++#define PHY_TRAILER_SIZE    MV_PHY_TRAILER_SIZE\r
++extern int mv_phyDetermineSource(char *data, int len);\r
++extern void mv_phySetDestinationPort(char *data, int len, int fromLAN);\r
++#define phyDetermineSource(data, len) mv_phyDetermineSource((data), (len))\r
++#define phySetDestinationPort(data, len, fromLAN) mv_phySetDestinationPort((data), (len), (fromLAN))\r
++#else\r
++#define PHY_TRAILER_SIZE    0\r
++#endif\r
++#endif /* CONFIG_MARVELL_ENET_PHY */\r
++\r
++#if defined(CONFIG_KENDIN_ENET_PHY) || defined(CONFIG_REALTEK_ENET_PHY)\r
++/*\r
++ * Mapping of generic phy APIs to Kendin KS8721B and RealTek RTL8201BL phys.\r
++ */\r
++#include "rtPhy.h"\r
++#define phySetup(ethUnit, phyBase)      rt_phySetup((ethUnit), (phyBase))\r
++#define phyCheckStatusChange(ethUnit)   rt_phyCheckStatusChange(ethUnit)\r
++#define phyIsSpeed100(ethUnit)          rt_phyIsSpeed100(ethUnit)\r
++#define phyIsFullDuplex(ethUnit)        rt_phyIsFullDuplex(ethUnit)\r
++#endif\r
++\r
++#if !defined(PHY_TRAILER_SIZE)\r
++#define PHY_TRAILER_SIZE    0\r
++#endif\r
++\r
++/*****************************************************************\r
++ * MAC-independent interface to be used by PHY code\r
++ *\r
++ * These functions are provided by the MAC layer for use by the PHY layer.\r
++ */\r
++#define phyRegRead ae531x_MiiRead\r
++#define phyRegWrite ae531x_MiiWrite\r
++#define phyLinkLost(ethUnit) ae531x_unitLinkLost(ethUnit)\r
++#define phyLinkGained(ethUnit) ae531x_unitLinkGained(ethUnit)\r
++#define phyEthMacDefault() ae531x_ethMacDefault()\r
++\r
++void ae531x_unitLinkLost(int unit);\r
++void ae531x_unitLinkGained(int unit);\r
++int ae531x_ethMacDefault(void);\r
++\r
++\r
++/* RXBUFF_RESERVE enables building header on WLAN-side in place */\r
++#define RXBUFF_RESERVE   96\r
++#define ETH_CRC_LEN       4\r
++\r
++/*****************************************************************\r
++ * Descriptor queue\r
++ */\r
++typedef struct ae531x_queue {\r
++    VIRT_ADDR   firstDescAddr;  /* descriptor array address */\r
++    VIRT_ADDR   lastDescAddr;   /* last descriptor address */\r
++    VIRT_ADDR   curDescAddr;    /* current descriptor address */\r
++    VIRT_ADDR   reapDescAddr;   /* current tail of tx descriptors reaped */\r
++    UINT16      count;          /* number of elements */\r
++} AE531X_QUEUE;\r
++\r
++/* Given a descriptor, return the next one in a circular list */\r
++#define AE531X_QUEUE_ELE_NEXT_GET(q, descAddr)                          \\r
++        ((descAddr) == (q)->lastDescAddr) ? (q)->firstDescAddr :    \\r
++        (VIRT_ADDR)((UINT32)(descAddr) + AE531X_QUEUE_ELE_SIZE)\r
++\r
++/* Move the "current descriptor" forward to the next one */\r
++#define AE531X_CONSUME_DESC(q)    \\r
++         q->curDescAddr = AE531X_QUEUE_ELE_NEXT_GET(q, q->curDescAddr)\r
++\r
++/*****************************************************************\r
++ * Per-ethernet-MAC OS-independent information\r
++ */\r
++typedef struct ae531x_MAC_s {\r
++    u32             unit;          /* MAC unit ID */\r
++    u32             macBase;       /* MAC base address */\r
++    u32             dmaBase;       /* DMA base address */\r
++    u32             phyBase;       /* PHY base address */\r
++    AE531X_QUEUE    txQueue;       /* Transmit descriptor queue */\r
++    AE531X_QUEUE    rxQueue;       /* Receive descriptor queue */\r
++    UINT16          txDescCount;   /* Transmit descriptor count */\r
++    UINT16          rxDescCount;   /* Receive descriptor count */\r
++    BOOL            aeProcessRst;  /* flag to indicate reset in progress */\r
++    BOOL            port_is_up;    /* flag to indicate port is up */\r
++    void            *OSinfo;       /* OS-dependent data */\r
++} ae531x_MAC_t;\r
++\r
++#define       AE531X_TX_DESC_COUNT_DEFAULT    64     /* Transmit descriptors */\r
++#define AE531X_RX_DESC_COUNT_DEFAULT  64     /* Receive descriptors */\r
++\r
++\r
++/*****************************************************************\r
++ * Interfaces exported by the OS-independent MAC layer\r
++ */\r
++void ae531x_BeginResetMode(ae531x_MAC_t *MACInfo);\r
++void ae531x_EndResetMode(ae531x_MAC_t *MACInfo);\r
++BOOL ae531x_IsInResetMode(ae531x_MAC_t *MACInfo);\r
++int ae531x_RxQueueCreate(ae531x_MAC_t *MACInfo, AE531X_QUEUE *q,\r
++                  char *pMem, int count);\r
++int ae531x_QueueDelete(struct ae531x_queue *q);\r
++void ae531x_DmaReset(ae531x_MAC_t *MACInfo);\r
++void ae531x_MACReset(ae531x_MAC_t *MACInfo);\r
++void ae531x_EnableComm(ae531x_MAC_t *MACInfo);\r
++void ae531x_DisableComm(ae531x_MAC_t *MACInfo);\r
++void ae531x_reset(ae531x_MAC_t *MACInfo);\r
++int ae531x_AllocateQueues(ae531x_MAC_t *MACInfo);\r
++void ae531x_FreeQueues(ae531x_MAC_t *MACInfo);\r
++void ae531x_QueueInit(AE531X_QUEUE *q, char *pMem, int count);\r
++UINT32 ae531x_ReadMacReg(ae531x_MAC_t *MACInfo, UINT32 reg);\r
++void ae531x_WriteMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data);\r
++void ae531x_SetMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);\r
++void ae531x_ClearMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);\r
++void ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);\r
++void ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);\r
++UINT32 ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg);\r
++void ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data);\r
++UINT32 ae531x_ReadMiiReg(UINT32 phyBase, UINT32 reg);\r
++void ae531x_WriteMiiReg(UINT32 phyBase, UINT32 reg, UINT32 data);\r
++UINT16 ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg);\r
++void ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, UINT16 data);\r
++void ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo);\r
++void ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo);\r
++void ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 val);\r
++void *ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBptr, int *rxBSize);\r
++void ae531x_swptr_free(VIRT_ADDR txDesc);\r
++\r
++#endif /* _AE531XMAC_H_ */\r
+diff -urN linux-2.4.32.new/arch/mips/ar531x/ae531xreg.h linux-2.4.32.new-eth/arch/mips/ar531x/ae531xreg.h\r
+--- linux-2.4.32.new/arch/mips/ar531x/ae531xreg.h      1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new-eth/arch/mips/ar531x/ae531xreg.h  2005-12-25 11:54:20.834262096 +0000\r
+@@ -0,0 +1,437 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++/*\r
++ * See README to understand the decomposition of the ethernet driver.\r
++ *\r
++ * Register definitions for Atheros AR531X Ethernet MAC.\r
++ */\r
++\r
++#ifndef _AE531XREG_H_\r
++#define _AE531XREG_H_\r
++\r
++#define AE531X_MAC_OFFSET 0x0000\r
++#define AE531X_PHY_OFFSET 0x0000 /* Same as MAC offset */\r
++#define AE531X_DMA_OFFSET 0x1000\r
++\r
++/***********************************************************/\r
++/* MAC110 registers, base address is BAR+AE531X_MAC_OFFSET */\r
++/***********************************************************/\r
++#define MacControl            0x00  /* control */\r
++#define MacAddrHigh           0x04  /* address high */\r
++#define MacAddrLow            0x08  /* address low */\r
++#define MacMultiHashHigh      0x0C  /* multicast hash table high */\r
++#define MacMultiHashLow       0x10  /* multicast hash table low */\r
++#define MacMiiAddr            0x14  /* MII address */\r
++#define MacMiiData            0x18  /* MII data */\r
++#define MacFlowControl        0x1C  /* Flow control */\r
++#define MacVlan1Tag           0x4C  /* VLAN1 tag */\r
++#define MacVlan2Tag           0x50  /* VLAN2 tag */\r
++\r
++\r
++/***************************************************************/\r
++/* DMA engine registers, base address is BAR+AE531X_DMA_OFFSET */\r
++/***************************************************************/\r
++#define DmaBusMode      0x00 /* CSR0 - Bus Mode */\r
++#define DmaTxPollDemand 0x04 /* CSR1 - Transmit Poll Demand */\r
++#define DmaRxPollDemand 0x08 /* CSR2 - Receive Poll Demand */\r
++#define DmaRxBaseAddr   0x0C /* CSR3 - Receive list base address */\r
++#define DmaTxBaseAddr   0x10 /* CSR4 - Transmit list base address */\r
++#define DmaStatus       0x14 /* CSR5 - Dma status */\r
++#define DmaControl      0x18 /* CSR6 - Dma control */\r
++#define DmaIntrEnb      0x1C /* CSR7 - Interrupt enable */\r
++#define DmaOverflowCnt  0x20 /* CSR8 - Missed Frame and Buff Overflow counter */\r
++#define DmaTxCurrAddr   0x50 /* CSR20 - Current host transmit buffer address */\r
++#define DmaRxCurrAddr   0x54 /* CSR21 - Current host receive buffer address */\r
++\r
++/**********************************************************/\r
++/* MAC Control register layout                            */\r
++/**********************************************************/\r
++#define MacFilterOff           0x80000000 /* Receive all incoming packets RW */\r
++#define MacFilterOn                     0 /* Receive filtered packets only 0 */\r
++#define MacBigEndian           0x40000000 /* Big endian mode RW */\r
++#define MacLittleEndian                 0 /* Little endian 0 */\r
++#define MacHeartBeatOff        0x10000000 /* Heartbeat signal qual disable RW*/\r
++#define MacHeartBeatOn                  0 /* Heartbeat signal qual enable 0 */\r
++#define MacSelectSrl           0x08000000 /* Select SRL port RW */\r
++#define MacSelectMii                    0 /* Select MII port 0 */\r
++#define MacDisableRxOwn        0x00800000 /* Disable receive own packets RW */\r
++#define MacEnableRxOwn                  0 /* Enable receive own packets 0 */\r
++#define MacLoopbackExt         0x00400000 /* External loopback RW */\r
++#define MacLoopbackInt         0x00200000 /* Internal loopback */\r
++#define MacLoopbackOff                  0 /* Normal mode 00 */\r
++#define MacFullDuplex          0x00100000 /* Full duplex mode RW */\r
++#define MacHalfDuplex                   0 /* Half duplex mode 0 */\r
++#define MacMulticastFilterOff  0x00080000 /* Pass all multicast packets RW */\r
++#define MacMulticastFilterOn            0 /* Pass filtered mcast packets 0 */\r
++#define MacPromiscuousModeOn   0x00040000 /* Receive all valid packets RW 1 */\r
++#define MacPromiscuousModeOff           0 /* Receive filtered packets only */\r
++#define MacFilterInverse       0x00020000 /* Inverse filtering RW */\r
++#define MacFilterNormal                 0 /* Normal filtering 0 */\r
++#define MacBadFramesEnable     0x00010000 /* Pass bad frames RW */\r
++#define MacBadFramesDisable             0 /* Do not pass bad frames 0 */\r
++#define MacPerfectFilterOff    0x00008000 /* Hash filtering only RW */\r
++#define MacPerfectFilterOn              0 /* Both perfect and hash filtering 0 */\r
++#define MacHashFilterOn        0x00002000 /* perform hash filtering RW */\r
++#define MacHashFilterOff                0 /* perfect filtering only 0 */\r
++#define MacLateCollisionOn     0x00001000 /* Enable late collision control RW */\r
++#define MacLateCollisionOff             0 /* Disable late collision control 0 */\r
++#define MacBroadcastDisable    0x00000800 /* Disable reception of bcast frames RW */\r
++#define MacBroadcastEnable              0 /* Enable broadcast frames 0 */\r
++#define MacRetryDisable        0x00000400 /* Disable retransmission RW */\r
++#define MacRetryEnable                  0 /* Enable retransmission 0 */\r
++#define MacPadStripEnable      0x00000100 /* Pad stripping enable RW */\r
++#define MacPadStripDisable              0 /* Pad stripping disable 0 */\r
++#define MacBackoff                      0 /* Backoff Limit RW 00 */\r
++#define MacDeferralCheckEnable 0x00000020 /* Deferral check enable RW */\r
++#define MacDeferralCheckDisable         0 /* Deferral check disable 0 */\r
++#define MacTxEnable            0x00000008 /* Transmitter enable RW */\r
++#define MacTxDisable                    0 /* Transmitter disable 0 */\r
++#define MacRxEnable            0x00000004 /* Receiver enable RW */\r
++#define MacRxDisable                    0 /* Receiver disable 0 */\r
++\r
++\r
++/**********************************************************/\r
++/* MII address register layout                            */\r
++/**********************************************************/\r
++#define MiiDevMask   0x0000F800 /* MII device address */\r
++#define MiiDevShift          11\r
++#define MiiRegMask   0x000007C0 /* MII register */\r
++#define MiiRegShift           6\r
++#define MiiWrite     0x00000002 /* Write to register */\r
++#define MiiRead               0 /* Read from register */\r
++#define MiiBusy      0x00000001 /* MII interface is busy */\r
++\r
++/**********************************************************/\r
++/* MII Data register layout                               */\r
++/**********************************************************/\r
++#define MiiDataMask  0x0000FFFF /* MII Data */\r
++\r
++/**********************************************************/\r
++/* MAC flow control register layout                       */\r
++/**********************************************************/\r
++#define MacPauseTimeMask      0xFFFF0000  /* PAUSE TIME field in ctrl frame */\r
++#define MacPauseTimeShift             15\r
++#define MacControlFrameEnable 0x00000004  /* Enable pass ctrl frames to host */\r
++#define MacControlFrameDisable         0  /* Do not pass ctrl frames to host */\r
++#define MacFlowControlEnable  0x00000002  /* Enable flow control */\r
++#define MacFlowControlDisable          0  /* Disable flow control */\r
++#define MacSendPauseFrame     0x00000001  /* send pause frame */\r
++\r
++/**********************************************************/\r
++/* DMA bus mode register layout                           */\r
++/**********************************************************/\r
++#define DmaRxAlign16            0x01000000 /* Force all rx buffers to align on odd hw bndry */\r
++#define DmaBigEndianDes         0x00100000 /* Big endian data buffer descriptors RW */\r
++#define DmaLittleEndianDesc              0 /* Little endian data descriptors */\r
++#define DmaBurstLength32        0x00002000 /* Dma burst length 32 RW */\r
++#define DmaBurstLength16        0x00001000 /* Dma burst length 16 */\r
++#define DmaBurstLength8         0x00000800 /* Dma burst length 8 */\r
++#define DmaBurstLength4         0x00000400 /* Dma burst length 4 */\r
++#define DmaBurstLength2         0x00000200 /* Dma burst length 2 */\r
++#define DmaBurstLength1         0x00000100 /* Dma burst length 1 */\r
++#define DmaBurstLength0         0x00000000 /* Dma burst length 0 */\r
++#define DmaBigEndianData        0x00000080 /* Big endian data buffers RW */\r
++#define DmaLittleEndianData              0 /* Little endian data buffers 0 */\r
++#define DmaDescriptorSkip16     0x00000040 /* number of dwords to skip RW */\r
++#define DmaDescriptorSkip8      0x00000020 /* between two unchained descriptors */\r
++#define DmaDescriptorSkip4      0x00000010\r
++#define DmaDescriptorSkip2      0x00000008\r
++#define DmaDescriptorSkip1      0x00000004\r
++#define DmaDescriptorSkip0               0\r
++#define DmaReceivePriorityOff   0x00000002 /* equal rx and tx priorities RW */\r
++#define DmaReceivePriorityOn             0 /* Rx has prioryty over Tx 0 */\r
++#define DmaResetOn              0x00000001 /* Reset DMA engine RW */\r
++#define DmaResetOff                      0\r
++\r
++/**********************************************************/\r
++/* DMA Status register layout                             */\r
++/**********************************************************/\r
++#define DmaRxAbort        0x01000000 /* receiver bus abort R 0 */\r
++#define DmaTxAbort        0x00800000 /* transmitter bus abort R 0 */\r
++#define DmaTxState        0x00700000 /* Transmit process state R 000 */\r
++#define DmaTxStopped      0x00000000 /* Stopped */\r
++#define DmaTxFetching     0x00100000 /* Running - fetching the descriptor */\r
++#define DmaTxWaiting      0x00200000 /* Running - waiting for end of transmission */\r
++#define DmaTxReading      0x00300000 /* Running - reading the data from memory */\r
++#define DmaTxSuspended    0x00600000 /* Suspended */\r
++#define DmaTxClosing      0x00700000 /* Running - closing descriptor */\r
++#define DmaRxState        0x000E0000 /* Receive process state 000 */\r
++#define DmaRxStopped      0x00000000 /* Stopped */\r
++#define DmaRxFetching     0x00020000 /* Running - fetching the descriptor */\r
++#define DmaRxChecking     0x00040000 /* Running - checking for end of packet */\r
++#define DmaRxWaiting      0x00060000 /* Running - waiting for packet */\r
++#define DmaRxSuspended    0x00080000 /* Suspended */\r
++#define DmaRxClosing      0x000A0000 /* Running - closing descriptor */\r
++#define DmaRxFlushing     0x000C0000 /* Running - flushing the current frame */\r
++#define DmaRxQueuing      0x000E0000 /* Running - queuing the recieve frame into host memory */\r
++#define DmaIntNormal      0x00010000 /* Normal interrupt summary RW 0 */\r
++#define DmaIntAbnormal    0x00008000 /* Abnormal interrupt summary RW 0 */\r
++#define DmaIntEarlyRx     0x00004000 /* Early receive interrupt (Normal) RW 0 */\r
++#define DmaIntBusError    0x00002000 /* Fatal bus error (Abnormal) RW 0 */\r
++#define DmaIntEarlyTx     0x00000400 /* Early transmit interrupt RW 0 */\r
++#define DmaIntRxStopped   0x00000100 /* Receive process stopped (Abnormal) RW 0 */\r
++#define DmaIntRxNoBuffer  0x00000080 /* Receive buffer unavailable (Abnormal) RW 0*/\r
++#define DmaIntRxCompleted 0x00000040 /* Completion of frame reception(Normal) RW 0*/\r
++#define DmaIntTxUnderflow 0x00000020 /* Transmit underflow (Abnormal) RW 0 */\r
++#define DmaIntTxJabber    0x00000008 /* Transmit Jabber Timeout (Abnormal) RW 0 */ \r
++#define DmaIntTxNoBuffer  0x00000004 /* Transmit buffer unavailable (Normal) RW 0*/\r
++#define DmaIntTxStopped   0x00000002 /* Transmit process stopped (Abnormal) RW 0 */\r
++#define DmaIntTxCompleted 0x00000001 /* Transmit completed (Normal) RW 0 */\r
++\r
++/**********************************************************/\r
++/* DMA control register layout                            */\r
++/**********************************************************/\r
++#define DmaStoreAndForward 0x00200000 /* Store and forward RW 0 */\r
++#define DmaTxThreshCtl256  0x0000c000 /* Non-SF threshold is 256 words */\r
++#define DmaTxThreshCtl128  0x00008000 /* Non-SF threshold is 128 words */\r
++#define DmaTxThreshCtl064  0x00004000 /* Non-SF threshold is 64 words */\r
++#define DmaTxThreshCtl032  0x00000000 /* Non-SF threshold is 32 words */\r
++#define DmaTxStart         0x00002000 /* Start/Stop transmission RW 0 */\r
++#define DmaTxSecondFrame   0x00000004 /* Operate on second frame RW 0 */\r
++#define DmaRxStart         0x00000002 /* Start/Stop reception RW 0 */\r
++\r
++/**********************************************************/\r
++/* DMA interrupt enable register layout                   */\r
++/**********************************************************/\r
++#define DmaIeNormal      DmaIntNormal      /* Normal interrupt enable RW 0 */\r
++#define DmaIeAbnormal    DmaIntAbnormal    /* Abnormal interrupt enable RW 0 */\r
++#define DmaIeEarlyRx     DmaIntEarlyRx     /* Early receive interrupt enable RW 0 */\r
++#define DmaIeBusError    DmaIntBusError    /* Fatal bus error enable RW 0 */\r
++#define DmaIeEarlyTx     DmaIntEarlyTx     /* Early transmit interrupt enable RW 0 */\r
++#define DmaIeRxStopped   DmaIntRxStopped   /* Receive process stopped enable RW 0 */\r
++#define DmaIeRxNoBuffer  DmaIntRxNoBuffer  /* Receive buffer unavailable enable RW 0 */\r
++#define DmaIeRxCompleted DmaIntRxCompleted /* Completion of frame reception enable RW 0 */\r
++#define DmaIeTxUnderflow DmaIntTxUnderflow /* Transmit underflow enable RW 0 */\r
++#define DmaIeTxJabber    DmaIntTxJabber    /* Transmit jabber timeout RW 0 */\r
++#define DmaIeTxNoBuffer  DmaIntTxNoBuffer  /* Transmit buffer unavailable enable RW 0 */\r
++#define DmaIeTxStopped   DmaIntTxStopped   /* Transmit process stopped enable RW 0 */\r
++#define DmaIeTxCompleted DmaIntTxCompleted /* Transmit completed enable RW 0 */\r
++\r
++/****************************************************************/\r
++/* DMA Missed Frame and Buffer Overflow Counter register layout */\r
++/****************************************************************/\r
++#define DmaRxBufferMissedFrame  0xffff0000  /* cleared on read */\r
++#define DmaMissedFrameShift             16\r
++#define DmaRxBufferOverflowCnt  0x0000ffff  /* cleared on read */\r
++#define DmaMissedFrameCountMask 0x0000ffff\r
++\r
++/**********************************************************/\r
++/* DMA Engine descriptor layout                           */\r
++/**********************************************************/\r
++/* status word of DMA descriptor */\r
++#define DescOwnByDma         0x80000000 /* Descriptor is owned by DMA engine */\r
++#define DescFrameLengthMask  0x3FFF0000 /* Receive descriptor frame length */\r
++#define DescFrameLengthShift         16\r
++#define DescError            0x00008000 /* Error summary bit OR of following bits */\r
++#define DescRxTruncated      0x00004000 /* Rx - no more descs for receive frame */\r
++#define DescRxLengthError    0x00001000 /* Rx - frame size not matching with length field */\r
++#define DescRxRunt           0x00000800 /* Rx - runt frame, damaged by a\r
++                                           collision or term before 64 bytes */\r
++#define DescRxMulticast      0x00000400 /* Rx - received frame is multicast */\r
++#define DescRxFirst          0x00000200 /* Rx - first descriptor of the frame */\r
++#define DescRxLast           0x00000100 /* Rx - last descriptor of the frame */\r
++#define DescRxLongFrame      0x00000080 /* Rx - frame is longer than 1518 bytes */\r
++#define DescRxLateColl       0x00000040 /* Rx - frame was damaged by a late collision */\r
++#define DescRxFrameEther     0x00000020 /* Rx - Frame type Ethernet 802.3*/ \r
++#define DescRxMiiError       0x00000008 /* Rx - error reported by MII interface */\r
++#define DescRxDribbling      0x00000004 /* Rx - frame contains noninteger multiple of 8 bits */\r
++#define DescRxCrc            0x00000002 /* Rx - CRC error */\r
++#define DescTxTimeout        0x00004000 /* Tx - Transmit jabber timeout */\r
++#define DescTxLostCarrier    0x00000800 /* Tx - carrier lost during tramsmission */\r
++#define DescTxNoCarrier      0x00000400 /* Tx - no carrier signal from tranceiver */\r
++#define DescTxLateCollision  0x00000200 /* Tx - transmission aborted due to collision */\r
++#define DescTxExcCollisions  0x00000100 /* Tx - transmission aborted after 16 collisions */\r
++#define DescTxHeartbeatFail  0x00000080 /* Tx - heartbeat collision check failure */\r
++#define DescTxCollMask       0x00000078 /* Tx - Collision count */\r
++#define DescTxCollShift               3\r
++#define DescTxExcDeferral    0x00000004 /* Tx - excessive deferral */\r
++#define DescTxUnderflow      0x00000002 /* Tx - late data arrival from memory */\r
++#define DescTxDeferred       0x00000001 /* Tx - frame transmision deferred */\r
++\r
++/* length word of DMA descriptor */\r
++#define DescTxIntEnable      0x80000000 /* Tx - interrupt on completion */\r
++#define DescTxLast           0x40000000 /* Tx - Last segment of the frame */\r
++#define DescTxFirst          0x20000000 /* Tx - First segment of the frame */\r
++#define DescTxDisableCrc     0x04000000 /* Tx - Add CRC disabled (first segment only) */\r
++#define DescEndOfRing        0x02000000 /* End of descriptors ring */\r
++#define DescChain            0x01000000 /* Second buffer address is chain address */\r
++#define DescTxDisablePadd    0x00800000 /* disable padding */\r
++#define DescSize2Mask        0x003FF800 /* Buffer 2 size */\r
++#define DescSize2Shift               11\r
++#define DescSize1Mask        0x000007FF /* Buffer 1 size */\r
++#define DescSize1Shift                0\r
++\r
++/**********************************************************/\r
++/* Initial register values                                */\r
++/**********************************************************/\r
++/* Full-duplex mode with perfect filter on */\r
++#define MacControlInitFdx \\r
++       ( MacFilterOn \\r
++       | MacLittleEndian \\r
++       | MacHeartBeatOn \\r
++       | MacSelectMii \\r
++       | MacEnableRxOwn \\r
++       | MacLoopbackOff \\r
++       | MacFullDuplex \\r
++       | MacMulticastFilterOn \\r
++       | MacPromiscuousModeOff \\r
++       | MacFilterNormal \\r
++       | MacBadFramesDisable \\r
++       | MacPerfectFilterOn \\r
++       | MacHashFilterOff \\r
++       | MacLateCollisionOff \\r
++       | MacBroadcastEnable \\r
++       | MacRetryEnable \\r
++       | MacPadStripDisable \\r
++       | MacDeferralCheckDisable \\r
++       | MacTxEnable \\r
++       | MacRxEnable)\r
++\r
++/* Full-duplex mode */\r
++#define MacFlowControlInitFdx \\r
++        ( MacControlFrameDisable \\r
++        | MacFlowControlEnable)\r
++\r
++/* Half-duplex mode with perfect filter on */\r
++#define MacControlInitHdx \\r
++       ( MacFilterOn \\r
++       | MacLittleEndian \\r
++       | MacHeartBeatOn \\r
++       | MacSelectMii \\r
++       | MacDisableRxOwn \\r
++       | MacLoopbackOff \\r
++       | MacHalfDuplex \\r
++       | MacMulticastFilterOn \\r
++       | MacPromiscuousModeOff \\r
++       | MacFilterNormal \\r
++       | MacBadFramesDisable \\r
++       | MacPerfectFilterOn \\r
++       | MacHashFilterOff \\r
++       | MacLateCollisionOff \\r
++       | MacBroadcastEnable \\r
++       | MacRetryEnable \\r
++       | MacPadStripDisable \\r
++       | MacDeferralCheckDisable \\r
++       | MacTxEnable \\r
++       | MacRxEnable)\r
++\r
++/* Half-duplex mode */\r
++#define MacFlowControlInitHdx \\r
++        ( MacControlFrameDisable \\r
++        | MacFlowControlDisable)\r
++\r
++/* Bus Mode Rx odd half word align */\r
++#define DmaBusModeInit  \\r
++       ( DmaLittleEndianDesc \\r
++       | DmaRxAlign16 \\r
++       | DmaBurstLength4 \\r
++       | DmaBigEndianData \\r
++       | DmaDescriptorSkip1 \\r
++       | DmaReceivePriorityOn \\r
++       | DmaResetOff)\r
++\r
++#define DmaControlInit (DmaStoreAndForward)\r
++\r
++/* Interrupt groups */\r
++#define DmaIntEnable \\r
++     ( DmaIeNormal \\r
++     | DmaIeAbnormal \\r
++     | DmaIntBusError \\r
++     | DmaIntRxStopped \\r
++     | DmaIntTxUnderflow \\r
++     | DmaIntTxStopped)\r
++\r
++#define DmaIntDisable 0\r
++\r
++#define DmaAllIntCauseMask \\r
++      ( DmaIeNormal  \\r
++      | DmaIeAbnormal  \\r
++      | DmaIntEarlyRx  \\r
++      | DmaIntBusError \\r
++      | DmaIntEarlyTx  \\r
++      | DmaIntRxStopped \\r
++      | DmaIntRxNoBuffer \\r
++      | DmaIntRxCompleted \\r
++      | DmaIntTxUnderflow \\r
++      | DmaIntTxJabber \\r
++      | DmaIntTxNoBuffer \\r
++      | DmaIntTxStopped \\r
++      | DmaIntTxCompleted)\r
++\r
++#define UnhandledIntrMask    \\r
++       (DmaAllIntCauseMask   \\r
++       & ~(DmaIntRxNoBuffer  \\r
++         | DmaIntTxStopped   \\r
++         | DmaIntTxJabber    \\r
++         | DmaIntTxUnderflow \\r
++         | DmaIntBusError    \\r
++         | DmaIntRxCompleted ))\r
++\r
++#define DescRxErrors    \\r
++      (DescRxTruncated  \\r
++     | DescRxRunt       \\r
++     | DescRxLateColl   \\r
++     | DescRxMiiError   \\r
++     | DescRxCrc)\r
++\r
++#define DescTxErrors        \\r
++     ( DescTxTimeout        \\r
++     | DescTxLateCollision  \\r
++     | DescTxExcCollisions  \\r
++     | DescTxExcDeferral    \\r
++     | DescTxUnderflow)\r
++\r
++/**********************************************************/\r
++/* Descriptor Layout                                      */\r
++/**********************************************************/\r
++#define AE531X_DESC_STATUS     0x00 /* Status offset */\r
++#define AE531X_DESC_CTRLEN     0x04 /* Control and Length offset */ \r
++#define AE531X_DESC_BUFPTR     0x08 /* Buffer pointer offset */\r
++#define AE531X_DESC_LNKBUF     0x0c /* Link field offset, or ptr to 2nd buf */\r
++#define AE531X_DESC_SWPTR      0x10 /* OS-Dependent software pointer */\r
++\r
++#define AE531X_DESC_SIZE       0x10 /* 4 words, 16 bytes */\r
++#define AE531X_QUEUE_ELE_SIZE  0x14 /* with software pointer extension */\r
++\r
++/* Accessors to the dma descriptor fields */\r
++#define AE531X_DESC_STATUS_GET(ptr) \\r
++    *(volatile UINT32 *)((UINT32)(ptr) + AE531X_DESC_STATUS)\r
++\r
++#define AE531X_DESC_STATUS_SET(ptr, val)  \\r
++    AE531X_DESC_STATUS_GET(ptr) = (val)\r
++\r
++#define AE531X_DESC_CTRLEN_GET(ptr) \\r
++    *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_CTRLEN)\r
++\r
++#define AE531X_DESC_CTRLEN_SET(ptr, val)  \\r
++    AE531X_DESC_CTRLEN_GET(ptr) = (val)\r
++\r
++#define AE531X_DESC_BUFPTR_GET(ptr) \\r
++    *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_BUFPTR)\r
++\r
++#define AE531X_DESC_BUFPTR_SET(ptr,val)  \\r
++    AE531X_DESC_BUFPTR_GET(ptr) = (UINT32)(val)\r
++\r
++#define AE531X_DESC_LNKBUF_GET(ptr)  \\r
++    *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_LNKBUF)\r
++\r
++#define AE531X_DESC_LNKBUF_SET(ptr, val)  \\r
++    AE531X_DESC_LNKBUF_GET(ptr) = (val)\r
++\r
++#define AE531X_DESC_SWPTR_GET(ptr) \\r
++    (void *)(*(volatile UINT32 *) ((UINT32)ptr + AE531X_DESC_SWPTR))\r
++\r
++#define AE531X_DESC_SWPTR_SET(ptr,val)   \\r
++    AE531X_DESC_SWPTR_GET(ptr) = (void *)(val)\r
++\r
++/* Get size of Rx data from desc, in bytes */\r
++#define AE531X_DESC_STATUS_RX_SIZE(x) \\r
++        (((x) & DescFrameLengthMask) >> DescFrameLengthShift)\r
++\r
++#endif /* _AE531XREG_H_ */\r
+diff -urN linux-2.4.32.new/arch/mips/ar531x/Makefile linux-2.4.32.new-eth/arch/mips/ar531x/Makefile\r
+--- linux-2.4.32.new/arch/mips/ar531x/Makefile 2005-12-24 20:29:42.010325312 +0000\r
++++ linux-2.4.32.new-eth/arch/mips/ar531x/Makefile     2005-12-25 12:03:16.213872024 +0000\r
+@@ -28,6 +28,13 @@\r
+       ar531xirq.o     \\r
+       ar531xintr.o    \\r
+       ar531xgpio.o    \\r
+-      ar531xksyms.o\r
++      ar531xksyms.o   \\r
++       ae531xlnx.o     \\r
++       ae531xmac.o\r
\r
+ include $(TOPDIR)/Rules.make\r
++obj-$(CONFIG_MARVELL_ENET_PHY)  += mvPhy.o\r
++obj-$(CONFIG_KENDIN_ENET_PHY))  += rtPhy.o\r
++obj-$(CONFIG_REALTEK_ENET_PHY)  += rtPhy.o\r
++\r
++\r
+diff -urN linux-2.4.32.new/arch/mips/ar531x/mvPhy.c linux-2.4.32.new-eth/arch/mips/ar531x/mvPhy.c\r
+--- linux-2.4.32.new/arch/mips/ar531x/mvPhy.c  1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new-eth/arch/mips/ar531x/mvPhy.c      2005-12-25 11:54:39.730389448 +0000\r
+@@ -0,0 +1,1237 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++/*\r
++* Manage the ethernet PHY switch, Marvell 88E6060.\r
++* \r
++* This module is intended to be largely OS and platform-independent.\r
++*/\r
++\r
++#if defined(linux)\r
++#include <linux/config.h>\r
++#include <linux/types.h>\r
++#include <linux/netdevice.h>\r
++#include <linux/etherdevice.h>\r
++#include <linux/delay.h>\r
++\r
++#include "ar531xlnx.h"\r
++#endif\r
++\r
++#if defined(__ECOS)\r
++#include "ae531xecos.h"\r
++#endif\r
++\r
++\r
++#include "ae531xmac.h"\r
++#include "ae531xreg.h"\r
++#include "mvPhy.h"\r
++\r
++#if /* DEBUG */ 1\r
++#define MV_DEBUG_ERROR     0x00000001\r
++#define MV_DEBUG_PHYSETUP  0x00000002\r
++#define MV_DEBUG_PHYCHANGE 0x00000004\r
++\r
++int mvPhyDebug = MV_DEBUG_ERROR;\r
++\r
++#define MV_PRINT(FLG, X)                            \\r
++{                                                   \\r
++    if (mvPhyDebug & (FLG)) {                       \\r
++        DEBUG_PRINTF X;                             \\r
++    }                                               \\r
++}\r
++#else\r
++#define MV_PRINT(FLG, X)\r
++#endif\r
++\r
++#ifdef CONFIG_VENETDEV\r
++/*\r
++ * On AR5312 with CONFIG_VENETDEV==1,\r
++ *   ports 0..3 are LAN ports  (accessed through ae0)\r
++ *   port 4 is the WAN port.   (accessed through ae1)\r
++ * \r
++ * The phy switch settings in the mvPhyInfo table are set accordingly.\r
++ */\r
++#define MV_WAN_PORT          4\r
++#define MV_IS_LAN_PORT(port) ((port) <  MV_WAN_PORT)\r
++#define MV_IS_WAN_PORT(port) ((port) == MV_WAN_PORT)\r
++#endif\r
++\r
++/*\r
++ * Track per-PHY port information.\r
++ */\r
++typedef struct {\r
++    BOOL   isEnetPort;       /* normal enet port */\r
++    BOOL   isPhyAlive;       /* last known state of link */\r
++    int    ethUnit;          /* MAC associated with this phy port */\r
++    UINT32 phyBase;\r
++    UINT32 phyAddr;          /* PHY registers associated with this phy port */\r
++    UINT32 switchPortAddr;   /* switch port regs assoc'ed with this phy port */\r
++    UINT32 VLANTableSetting; /* Value to be written to VLAN table */\r
++} mvPhyInfo_t;\r
++\r
++/******************************************************************************\r
++ * Per-PHY information, indexed by PHY unit number.\r
++ *\r
++ * This table is board-dependent.  It includes information\r
++ * about which enet MAC controls which PHY port.\r
++ */\r
++mvPhyInfo_t mvPhyInfo[] = {\r
++    /*\r
++     * On AP30/AR5312, all PHYs are associated with MAC0.\r
++     * AP30/AR5312's MAC1 isn't used for anything.\r
++     * CONFIG_VENETDEV==1 (router) configuration:\r
++     *    Ports 0,1,2, and 3 are "LAN ports"\r
++     *    Port 4 is a WAN port\r
++     *    Port 5 connects to MAC0 in the AR5312\r
++     * CONFIG_VENETDEV==0 (bridge) configuration:\r
++     *    Ports 0,1,2,3,4 are "LAN ports"\r
++     *    Port 5 connects to the MAC0 in the AR5312\r
++     */\r
++    {isEnetPort: TRUE,   /* phy port 0 -- LAN port 0 */\r
++     isPhyAlive: FALSE,\r
++     ethUnit: 0,\r
++     phyBase: 0,\r
++     phyAddr: 0x10,\r
++     switchPortAddr: 0x18,\r
++#ifdef CONFIG_VENETDEV\r
++     VLANTableSetting: 0x2e\r
++#else\r
++     VLANTableSetting: 0x3e\r
++#endif\r
++    },\r
++\r
++    {isEnetPort: TRUE,   /* phy port 1 -- LAN port 1 */\r
++     isPhyAlive: FALSE,\r
++     ethUnit: 0,\r
++     phyBase: 0,\r
++     phyAddr: 0x11,\r
++     switchPortAddr: 0x19,\r
++#ifdef CONFIG_VENETDEV\r
++     VLANTableSetting: 0x2d\r
++#else\r
++     VLANTableSetting: 0x3d\r
++#endif\r
++    },\r
++\r
++    {isEnetPort: TRUE,   /* phy port 2 -- LAN port 2 */\r
++     isPhyAlive: FALSE,\r
++     ethUnit: 0,\r
++     phyBase: 0,\r
++     phyAddr: 0x12, \r
++     switchPortAddr: 0x1a,\r
++#ifdef CONFIG_VENETDEV\r
++     VLANTableSetting: 0x2b\r
++#else\r
++     VLANTableSetting: 0x3b\r
++#endif\r
++    },\r
++\r
++    {isEnetPort: TRUE,   /* phy port 3 -- LAN port 3 */\r
++     isPhyAlive: FALSE,\r
++     ethUnit: 0,\r
++     phyBase: 0,\r
++     phyAddr: 0x13, \r
++     switchPortAddr: 0x1b,\r
++#ifdef CONFIG_VENETDEV\r
++     VLANTableSetting: 0x27\r
++#else\r
++     VLANTableSetting: 0x37\r
++#endif\r
++    },\r
++\r
++    {isEnetPort: TRUE,   /* phy port 4 -- WAN port or LAN port 4 */\r
++     isPhyAlive: FALSE,\r
++     ethUnit: 0,\r
++     phyBase: 0,\r
++     phyAddr: 0x14, \r
++     switchPortAddr: 0x1c,\r
++#ifdef CONFIG_VENETDEV\r
++     VLANTableSetting: 0x1020  /* WAN port */\r
++#else\r
++     VLANTableSetting: 0x2f    /* LAN port 4 */\r
++#endif\r
++    },\r
++\r
++    {isEnetPort: FALSE,  /* phy port 5 -- CPU port (no RJ45 connector) */\r
++     isPhyAlive: TRUE,\r
++     ethUnit: 0,\r
++     phyBase: 0,\r
++     phyAddr: 0x15, \r
++     switchPortAddr: 0x1d,\r
++#ifdef CONFIG_VENETDEV\r
++     VLANTableSetting: 0x0f    /* Send only to LAN ports */\r
++#else\r
++     VLANTableSetting: 0x1f    /* Send to all ports */\r
++#endif\r
++    },\r
++};\r
++\r
++#define MV_PHY_MAX (sizeof(mvPhyInfo) / sizeof(mvPhyInfo[0]))\r
++\r
++/* Range of valid PHY IDs is [MIN..MAX] */\r
++#define MV_ID_MIN 0\r
++#define MV_ID_MAX (MV_PHY_MAX-1)\r
++\r
++/* Convenience macros to access myPhyInfo */\r
++#define MV_IS_ENET_PORT(phyUnit) (mvPhyInfo[phyUnit].isEnetPort)\r
++#define MV_IS_PHY_ALIVE(phyUnit) (mvPhyInfo[phyUnit].isPhyAlive)\r
++#define MV_ETHUNIT(phyUnit) (mvPhyInfo[phyUnit].ethUnit)\r
++#define MV_PHYBASE(phyUnit) (mvPhyInfo[phyUnit].phyBase)\r
++#define MV_PHYADDR(phyUnit) (mvPhyInfo[phyUnit].phyAddr)\r
++#define MV_SWITCH_PORT_ADDR(phyUnit) (mvPhyInfo[phyUnit].switchPortAddr)\r
++#define MV_VLAN_TABLE_SETTING(phyUnit) (mvPhyInfo[phyUnit].VLANTableSetting)\r
++\r
++#define MV_IS_ETHUNIT(phyUnit, ethUnit) \\r
++    (MV_IS_ENET_PORT(phyUnit) &&        \\r
++    MV_ETHUNIT(phyUnit) == (ethUnit))\r
++\r
++\r
++/* Forward references */\r
++BOOL       mv_phyIsLinkAlive(int phyUnit);\r
++LOCAL void mv_VLANInit(int ethUnit);\r
++LOCAL void mv_enableConfiguredPorts(int ethUnit);\r
++LOCAL void mv_verifyReady(int ethUnit);\r
++BOOL       mv_phySetup(int ethUnit, UINT32 phyBase);\r
++BOOL       mv_phyIsFullDuplex(int ethUnit);\r
++BOOL       mv_phyIsSpeed100(int phyUnit);\r
++LOCAL BOOL mv_validPhyId(int phyUnit);\r
++void       mv_flushATUDB(int phyUnit);\r
++void       mv_phyCheckStatusChange(int ethUnit);\r
++#if DEBUG\r
++void       mv_phyShow(int phyUnit);\r
++void       mv_phySet(int phyUnit, UINT32 regnum, UINT32 value);\r
++void       mv_switchPortSet(int phyUnit, UINT32 regnum, UINT32 value);\r
++void       mv_switchGlobalSet(int phyUnit, UINT32 regnum, UINT32 value);\r
++void       mv_showATUDB(int phyUnit);\r
++void       mv_countGoodFrames(int phyUnit);\r
++void       mv_countBadFrames(int phyUnit);\r
++void       mv_showFrameCounts(int phyUnit);\r
++#endif\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* mv_phyIsLinkAlive - test to see if the specified link is alive\r
++*\r
++* RETURNS:\r
++*    TRUE  --> link is alive\r
++*    FALSE --> link is down\r
++*/\r
++BOOL\r
++mv_phyIsLinkAlive(int phyUnit)\r
++{\r
++    UINT16 phyHwStatus;\r
++    UINT32 phyBase;\r
++    UINT32 phyAddr;\r
++\r
++    phyBase = MV_PHYBASE(phyUnit);\r
++    phyAddr = MV_PHYADDR(phyUnit);\r
++\r
++    phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);\r
++\r
++    if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) {\r
++        return TRUE;\r
++    } else {\r
++        return FALSE;\r
++    }\r
++}\r
++\r
++/******************************************************************************\r
++*\r
++* mv_VLANInit - initialize "port-based VLANs" for the specified enet unit.\r
++*/\r
++LOCAL void\r
++mv_VLANInit(int ethUnit)\r
++{\r
++    int     phyUnit;\r
++    UINT32  phyBase;\r
++    UINT32  switchPortAddr;\r
++\r
++    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
++        if (MV_ETHUNIT(phyUnit) != ethUnit) {\r
++            continue;\r
++        }\r
++\r
++        phyBase        = MV_PHYBASE(phyUnit);\r
++        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
++\r
++        phyRegWrite(phyBase, switchPortAddr, MV_PORT_BASED_VLAN_MAP,\r
++                    MV_VLAN_TABLE_SETTING(phyUnit));\r
++    }\r
++}\r
++\r
++#define phyPortConfigured(phyUnit) TRUE /* TBDFREEDOM2 */\r
++\r
++/******************************************************************************\r
++*\r
++* mv_enableConfiguredPorts - enable whichever PHY ports are supposed\r
++* to be enabled according to administrative configuration.\r
++*/\r
++LOCAL void\r
++mv_enableConfiguredPorts(int ethUnit)\r
++{\r
++    int     phyUnit;\r
++    UINT32  phyBase;\r
++    UINT32  switchPortAddr;\r
++    UINT16  portControl;\r
++    UINT16  portAssociationVector;\r
++\r
++    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
++        if (MV_ETHUNIT(phyUnit) != ethUnit) {\r
++            continue;\r
++        }\r
++\r
++        phyBase        = MV_PHYBASE(phyUnit);\r
++        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
++\r
++        if (phyPortConfigured(phyUnit)) {\r
++\r
++            portControl = MV_PORT_CONTROL_PORT_STATE_FORWARDING;\r
++#ifdef CONFIG_VENETDEV\r
++            if (!MV_IS_ENET_PORT(phyUnit)) {       /* CPU port */\r
++                portControl |= MV_PORT_CONTROL_INGRESS_TRAILER\r
++                            | MV_PORT_CONTROL_EGRESS_MODE;\r
++            }\r
++#endif\r
++            phyRegWrite(phyBase, switchPortAddr, MV_PORT_CONTROL, portControl);\r
++\r
++            if (MV_IS_ENET_PORT(phyUnit)) {\r
++                portAssociationVector = 1 << phyUnit;\r
++            } else {\r
++                /* Disable learning on the CPU port */\r
++                portAssociationVector = 0;\r
++            }\r
++            phyRegWrite(phyBase, switchPortAddr,\r
++                MV_PORT_ASSOCIATION_VECTOR, portAssociationVector);\r
++        }\r
++    }\r
++}\r
++\r
++/******************************************************************************\r
++*\r
++* mv_verifyReady - validates that we're dealing with the device\r
++* we think we're dealing with, and that it's ready.\r
++*/\r
++LOCAL void\r
++mv_verifyReady(int ethUnit)\r
++{\r
++    int     phyUnit;\r
++    UINT16  globalStatus;\r
++    UINT32  phyBase = 0;\r
++    UINT32  phyAddr;\r
++    UINT32  switchPortAddr;\r
++    UINT16  phyID1;\r
++    UINT16  phyID2;\r
++    UINT16  switchID;\r
++\r
++    /*\r
++     * The first read to the Phy port registers always fails and\r
++     * returns 0.   So get things started with a bogus read.\r
++     */\r
++    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
++        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
++            continue;\r
++        }\r
++        phyBase = MV_PHYBASE(phyUnit);\r
++        phyAddr = MV_PHYADDR(phyUnit);\r
++    \r
++        (void)phyRegRead(phyBase, phyAddr, MV_PHY_ID1); /* returns 0 */\r
++        break;\r
++    }\r
++\r
++    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
++        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
++            continue;\r
++        }\r
++\r
++        /*******************/\r
++        /* Verify phy port */\r
++        /*******************/\r
++        phyBase = MV_PHYBASE(phyUnit);\r
++        phyAddr = MV_PHYADDR(phyUnit);\r
++    \r
++        phyID1 = phyRegRead(phyBase, phyAddr, MV_PHY_ID1);\r
++        if (phyID1 != MV_PHY_ID1_EXPECTATION) {\r
++            MV_PRINT(MV_DEBUG_PHYSETUP,\r
++                      ("Invalid PHY ID1 for ethmac%d port%d.  Expected 0x%04x, read 0x%04x\n",\r
++                       ethUnit,\r
++                       phyUnit,\r
++                       MV_PHY_ID1_EXPECTATION,\r
++                       phyID1));\r
++            return;\r
++        }\r
++    \r
++        phyID2 = phyRegRead(phyBase, phyAddr, MV_PHY_ID2);\r
++        if ((phyID2 & MV_OUI_LSB_MASK) != MV_OUI_LSB_EXPECTATION) {\r
++            MV_PRINT(MV_DEBUG_PHYSETUP,\r
++                      ("Invalid PHY ID2 for ethmac%d port %d.  Expected 0x%04x, read 0x%04x\n",\r
++                       ethUnit,\r
++                       phyUnit,\r
++                       MV_OUI_LSB_EXPECTATION,\r
++                       phyID2));\r
++            return;\r
++        }\r
++    \r
++        MV_PRINT(MV_DEBUG_PHYSETUP,\r
++                  ("Found PHY ethmac%d port%d: model 0x%x revision 0x%x\n",\r
++                   ethUnit,\r
++                   phyUnit,\r
++                   (phyID2 & MV_MODEL_NUM_MASK) >> MV_MODEL_NUM_SHIFT,\r
++                   (phyID2 & MV_REV_NUM_MASK) >> MV_REV_NUM_SHIFT));\r
++    \r
++    \r
++        /**********************/\r
++        /* Verify switch port */\r
++        /**********************/\r
++        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
++    \r
++        switchID = phyRegRead(phyBase, switchPortAddr, MV_SWITCH_ID);\r
++        if ((switchID & MV_SWITCH_ID_DEV_MASK) !=\r
++            MV_SWITCH_ID_DEV_EXPECTATION) {\r
++    \r
++            MV_PRINT(MV_DEBUG_PHYSETUP,\r
++                      ("Invalid switch ID for ethmac%d port %d.  Expected 0x%04x, read 0x%04x\n",\r
++                       ethUnit,\r
++                       phyUnit,\r
++                       MV_SWITCH_ID_DEV_EXPECTATION,\r
++                       switchID));\r
++            return;\r
++        }\r
++    \r
++        MV_PRINT(MV_DEBUG_PHYSETUP,\r
++                  ("Found PHY switch for enet %d port %d deviceID 0x%x revision 0x%x\n",\r
++                    ethUnit,\r
++                    phyUnit,\r
++                    (switchID & MV_SWITCH_ID_DEV_MASK) >> MV_SWITCH_ID_DEV_SHIFT,\r
++                    (switchID & MV_SWITCH_ID_REV_MASK) >> MV_SWITCH_ID_REV_SHIFT))\r
++    }\r
++    \r
++    /*******************************/\r
++    /* Verify that switch is ready */\r
++    /*******************************/\r
++    if (phyBase) {\r
++        globalStatus = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
++                                  MV_SWITCH_GLOBAL_STATUS);\r
++\r
++        if (!(globalStatus & MV_SWITCH_STATUS_READY_MASK)) {\r
++            MV_PRINT(MV_DEBUG_PHYSETUP,\r
++                      ("PHY switch for ethmac%d NOT ready!\n",\r
++                       ethUnit));\r
++        }\r
++    } else {\r
++        MV_PRINT(MV_DEBUG_PHYSETUP,\r
++                  ("No ports configured for ethmac%d\n", ethUnit));\r
++    }\r
++}\r
++\r
++/******************************************************************************\r
++*\r
++* mv_phySetup - reset and setup the PHY switch.\r
++*\r
++* Resets each PHY port.\r
++*\r
++* RETURNS:\r
++*    TRUE  --> at least 1 PHY with LINK\r
++*    FALSE --> no LINKs on this ethernet unit\r
++*/\r
++BOOL\r
++mv_phySetup(int ethUnit, UINT32 phyBase)\r
++{\r
++    int     phyUnit;\r
++    int     liveLinks = 0;\r
++    BOOL    foundPhy = FALSE;\r
++    UINT32  phyAddr;\r
++    UINT16  atuControl;\r
++\r
++    /*\r
++     * Allow platform-specific code to determine the default Ethernet MAC\r
++     * at run-time.  If phyEthMacDefault returns a negative value, use the\r
++     * static mvPhyInfo table "as is".  But if phyEthMacDefault returns a\r
++     * non-negative value, use it as the default ethernet unit.\r
++     */\r
++    {\r
++        int ethMacDefault = phyEthMacDefault();\r
++\r
++        if (ethMacDefault >= 0) {\r
++            for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
++                MV_ETHUNIT(phyUnit)=ethMacDefault;\r
++            }\r
++        }\r
++    }\r
++\r
++    /*\r
++     * See if there's any configuration data for this enet,\r
++     * and set up phyBase in table.\r
++     */\r
++    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
++        if (MV_ETHUNIT(phyUnit) != ethUnit) {\r
++            continue;\r
++        }\r
++\r
++        MV_PHYBASE(phyUnit) = phyBase;\r
++        foundPhy = TRUE;\r
++    }\r
++\r
++    if (!foundPhy) {\r
++        return FALSE; /* No PHY's configured for this ethUnit */\r
++    }\r
++\r
++    /* Verify that the switch is what we think it is, and that it's ready */\r
++    mv_verifyReady(ethUnit);\r
++\r
++    /* Initialize global switch settings */\r
++    atuControl  = MV_ATUCTRL_AGE_TIME_DEFAULT << MV_ATUCTRL_AGE_TIME_SHIFT;\r
++    atuControl |= MV_ATUCTRL_ATU_SIZE_DEFAULT << MV_ATUCTRL_ATU_SIZE_SHIFT;\r
++    // atuControl |= MV_ATUCTRL_ATU_LEARNDIS;\r
++    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_CONTROL, atuControl);\r
++\r
++    /* Reset PHYs and start autonegoation on each. */\r
++    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
++        if (MV_ETHUNIT(phyUnit) != ethUnit) {\r
++            continue;\r
++        }\r
++\r
++        phyBase = MV_PHYBASE(phyUnit);\r
++        phyAddr = MV_PHYADDR(phyUnit);\r
++\r
++        phyRegWrite(phyBase, phyAddr, MV_PHY_CONTROL,\r
++                    MV_CTRL_SOFTWARE_RESET | MV_CTRL_AUTONEGOTIATION_ENABLE);\r
++    }\r
++\r
++    {\r
++      int timeout;\r
++      UINT16  phyHwStatus;\r
++\r
++      /*\r
++       * Wait 5 seconds for ALL associated PHYs to finish autonegotiation.\r
++       */\r
++      timeout=50;\r
++      for (phyUnit=0; (phyUnit < MV_PHY_MAX) && (timeout > 0); phyUnit++) {\r
++          if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
++              continue;\r
++          }\r
++          for (;;) {\r
++              phyBase = MV_PHYBASE(phyUnit);\r
++              phyAddr = MV_PHYADDR(phyUnit);\r
++\r
++              phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);\r
++\r
++              if (MV_AUTONEG_DONE(phyHwStatus)) {\r
++                  break;\r
++              }\r
++\r
++              if (--timeout == 0) {\r
++                  break;\r
++              }\r
++\r
++              sysMsDelay(100);\r
++          }\r
++      }\r
++    }\r
++\r
++    /*\r
++     * All PHYs have had adequate time to autonegotiate.\r
++     * Now initialize software status.\r
++     *\r
++     * It's possible that some ports may take a bit longer\r
++     * to autonegotiate; but we can't wait forever.  They'll\r
++     * get noticed by mv_phyCheckStatusChange during regular\r
++     * polling activities.\r
++     */\r
++    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
++        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
++            continue;\r
++        }\r
++\r
++        if (mv_phyIsLinkAlive(phyUnit)) {\r
++            liveLinks++;\r
++            MV_IS_PHY_ALIVE(phyUnit) = TRUE;\r
++#ifdef DEBUG\r
++          mv_phyShow(phyUnit);\r
++#endif\r
++        } else {\r
++            MV_IS_PHY_ALIVE(phyUnit) = FALSE;\r
++        }\r
++\r
++        MV_PRINT(MV_DEBUG_PHYSETUP,\r
++            ("ethmac%d: Phy Status=%4.4x\n",\r
++            ethUnit, \r
++            phyRegRead(MV_PHYBASE(phyUnit),\r
++                       MV_PHYADDR(phyUnit),\r
++                       MV_PHY_SPECIFIC_STATUS)));\r
++\r
++    }\r
++\r
++#ifdef DEBUG\r
++    /* PHY 5 is the connection to the CPU */\r
++    mv_phyShow(5);\r
++#endif\r
++\r
++    mv_VLANInit(ethUnit);\r
++\r
++    mv_enableConfiguredPorts(ethUnit);\r
++\r
++    return (liveLinks > 0);\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* mv_phyIsDuplexFull - Determines whether the phy ports associated with the\r
++* specified device are FULL or HALF duplex.\r
++*\r
++* RETURNS:\r
++*    TRUE --> at least one associated PHY in FULL DUPLEX\r
++*    FALSE --> all half duplex, or no links\r
++*/\r
++BOOL\r
++mv_phyIsFullDuplex(int ethUnit)\r
++{\r
++    int     phyUnit;\r
++    UINT32  phyBase;\r
++    UINT32  phyAddr;\r
++    UINT16  phyHwStatus;\r
++\r
++    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
++\r
++        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
++            continue;\r
++        }\r
++\r
++        if (mv_phyIsLinkAlive(phyUnit)) {\r
++\r
++            phyBase = MV_PHYBASE(phyUnit);\r
++            phyAddr = MV_PHYADDR(phyUnit);\r
++\r
++            phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);\r
++\r
++            if (phyHwStatus & MV_STATUS_RESOLVED_DUPLEX_FULL) {\r
++                return TRUE;\r
++            }\r
++        }\r
++    }\r
++\r
++    return FALSE;\r
++}\r
++\r
++/******************************************************************************\r
++*\r
++* mv_phyIsSpeed100 - Determines the speed of a phy port\r
++*\r
++* RETURNS:\r
++*    TRUE --> PHY operating at 100 Mbit\r
++*    FALSE --> link down, or not operating at 100 Mbit\r
++*/\r
++BOOL\r
++mv_phyIsSpeed100(int phyUnit)\r
++{\r
++    UINT16  phyHwStatus;\r
++    UINT32  phyBase;\r
++    UINT32  phyAddr;\r
++\r
++    if (MV_IS_ENET_PORT(phyUnit)) {\r
++        if (mv_phyIsLinkAlive(phyUnit)) {\r
++\r
++            phyBase = MV_PHYBASE(phyUnit);\r
++            phyAddr = MV_PHYADDR(phyUnit);\r
++\r
++            phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);\r
++\r
++            if (phyHwStatus & MV_STATUS_RESOLVED_SPEED_100) {\r
++                return TRUE;\r
++            }\r
++        }\r
++    }\r
++\r
++    return FALSE;\r
++}\r
++\r
++#ifdef CONFIG_VENETDEV\r
++/******************************************************************************\r
++*\r
++* mv_phyDetermineSource - Examine a received frame's Egress Trailer\r
++* to determine whether it came from a LAN or WAN port.\r
++*\r
++* RETURNS:\r
++*    Returns 1-->LAN, 0-->WAN, -1-->ERROR\r
++*/\r
++int\r
++mv_phyDetermineSource(char *data, int len)\r
++{\r
++    unsigned char *phyTrailer;\r
++    unsigned char incomingPort;\r
++\r
++    phyTrailer = &data[len - MV_PHY_TRAILER_SIZE];\r
++\r
++    /* ASSERT(phyTrailer[0] == MV_EGRESS_TRAILER_VALID); */\r
++    if (phyTrailer[0] != MV_EGRESS_TRAILER_VALID) {\r
++      printk(KERN_ERR "PHY trailer invalid; got %#02x, expected %#02x\n",\r
++             phyTrailer[0], MV_EGRESS_TRAILER_VALID);\r
++      return -1;\r
++    }\r
++\r
++    incomingPort = phyTrailer[1];\r
++    if (MV_IS_LAN_PORT(incomingPort)) {\r
++        return 1;\r
++    } else {\r
++        /* ASSERT(MV_IS_WAN_PORT(incomingPort)); */\r
++      if (!MV_IS_WAN_PORT(incomingPort)) {\r
++          printk(KERN_ERR "incoming port was %d; expected 0-4\n", incomingPort);\r
++          return -1;\r
++      }\r
++        return 0;\r
++    }\r
++}\r
++\r
++\r
++/******************************************************************************\r
++*\r
++* mv_phySetDestinationPort - Set the Ingress Trailer to force the\r
++* frame to be sent to LAN or WAN, as specified.\r
++*\r
++*/\r
++void\r
++mv_phySetDestinationPort(char *data, int len, int fromLAN)\r
++{\r
++    char *phyTrailer;\r
++\r
++    phyTrailer = &data[len];\r
++    if (fromLAN) {\r
++        /* LAN ports: Use default settings, as per mvPhyInfo */\r
++        phyTrailer[0] = 0x00;\r
++        phyTrailer[1] = 0x00;\r
++    } else {\r
++        /* WAN port: Direct to WAN port */\r
++        phyTrailer[0] = MV_INGRESS_TRAILER_OVERRIDE;\r
++        phyTrailer[1] = 1 << MV_WAN_PORT;\r
++    }\r
++    phyTrailer[2] = 0x00;\r
++    phyTrailer[3] = 0x00;\r
++}\r
++#endif\r
++\r
++\r
++/*****************************************************************************\r
++*\r
++* Validate that the specified PHY unit number is a valid PHY ID.\r
++* Print a message if it is invalid.\r
++* RETURNS\r
++*   TRUE  --> valid\r
++*   FALSE --> invalid\r
++*/\r
++LOCAL BOOL\r
++mv_validPhyId(int phyUnit)\r
++{\r
++    if ((phyUnit >= MV_ID_MIN) && (phyUnit <= MV_ID_MAX)) {\r
++        return TRUE;\r
++    } else {\r
++        PRINTF("PHY unit number must be in the range [%d..%d]\n",\r
++            MV_ID_MIN, MV_ID_MAX);\r
++        return FALSE;\r
++    } \r
++}\r
++\r
++\r
++/*****************************************************************************\r
++*\r
++* mv_waitWhileATUBusy - spins until the ATU completes\r
++* its previous operation.\r
++*/\r
++LOCAL void\r
++mv_waitWhileATUBusy(UINT32 phyBase)\r
++{\r
++    BOOL   isBusy;\r
++    UINT16 ATUOperation;\r
++\r
++    do {\r
++\r
++        ATUOperation = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
++                                  MV_ATU_OPERATION);\r
++\r
++        isBusy = (ATUOperation & MV_ATU_BUSY_MASK) == MV_ATU_IS_BUSY;\r
++\r
++    } while(isBusy);\r
++}\r
++\r
++/*****************************************************************************\r
++*\r
++* mv_flushATUDB - flushes ALL entries in the Address Translation Unit\r
++* DataBase associated with phyUnit.  [Since we use a single DB for\r
++* all PHYs, this flushes the entire shared DataBase.]\r
++*\r
++* The current implementation flushes even more than absolutely needed --\r
++* it flushes all entries for all phyUnits on the same ethernet as the\r
++* specified phyUnit.\r
++*\r
++* It is called only when a link failure is detected on a port that was\r
++* previously working.  In other words, when the cable is unplugged.\r
++*/\r
++void\r
++mv_flushATUDB(int phyUnit)\r
++{\r
++    UINT32 phyBase;\r
++\r
++    if (!mv_validPhyId(phyUnit)) {\r
++        PRINTF("Invalid port number: %d\n", phyUnit);\r
++        return;\r
++    }\r
++\r
++    phyBase = MV_PHYBASE(phyUnit);\r
++    \r
++    /* Wait for previous operation (if any) to complete */\r
++    mv_waitWhileATUBusy(phyBase);\r
++\r
++    /* Tell hardware to flush all entries */\r
++    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, \r
++                MV_ATU_OP_FLUSH_ALL | MV_ATU_IS_BUSY);\r
++\r
++    mv_waitWhileATUBusy(phyBase);\r
++}\r
++ \r
++/*****************************************************************************\r
++*\r
++* mv_phyCheckStatusChange -- checks for significant changes in PHY state.\r
++*\r
++* A "significant change" is:\r
++*     dropped link (e.g. ethernet cable unplugged) OR\r
++*     autonegotiation completed + link (e.g. ethernet cable plugged in)\r
++*/\r
++void\r
++mv_phyCheckStatusChange(int ethUnit)\r
++{\r
++    int           phyUnit;\r
++    UINT16        phyHwStatus;\r
++    mvPhyInfo_t   *lastStatus;\r
++    int           linkCount   = 0;\r
++    int           lostLinks   = 0;\r
++    int           gainedLinks = 0;\r
++    UINT32        phyBase;\r
++    UINT32        phyAddr;\r
++\r
++    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
++        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
++            continue;\r
++        }\r
++\r
++        phyBase = MV_PHYBASE(phyUnit);\r
++        phyAddr = MV_PHYADDR(phyUnit);\r
++\r
++        lastStatus = &mvPhyInfo[phyUnit];\r
++        phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);\r
++\r
++        if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */\r
++            /* See if we've lost link */\r
++            if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) {\r
++                linkCount++;\r
++            } else {\r
++                lostLinks++;\r
++                mv_flushATUDB(phyUnit);\r
++                MV_PRINT(MV_DEBUG_PHYCHANGE,("\nethmac%d port%d down\n",\r
++                                               ethUnit, phyUnit));\r
++                lastStatus->isPhyAlive = FALSE;\r
++            }\r
++        } else { /* last known link status was DEAD */\r
++            /* Check for AutoNegotiation complete */\r
++            if (MV_AUTONEG_DONE(phyHwStatus)) {\r
++                gainedLinks++;\r
++              linkCount++;\r
++                MV_PRINT(MV_DEBUG_PHYCHANGE,("\nethmac%d port%d up\n",\r
++                                               ethUnit, phyUnit));\r
++                lastStatus->isPhyAlive = TRUE;\r
++            }\r
++        }\r
++    }\r
++\r
++    if (linkCount == 0) {\r
++        if (lostLinks) {\r
++            /* We just lost the last link for this MAC */\r
++            phyLinkLost(ethUnit);\r
++        }\r
++    } else {\r
++        if (gainedLinks == linkCount) {\r
++            /* We just gained our first link(s) for this MAC */\r
++            phyLinkGained(ethUnit);\r
++        }\r
++    }\r
++}\r
++\r
++#if DEBUG\r
++\r
++/* Define the registers of interest for a phyShow command */\r
++typedef struct mvRegisterTableEntry_s {\r
++    UINT32 regNum;\r
++    char  *regIdString;\r
++} mvRegisterTableEntry_t;\r
++\r
++mvRegisterTableEntry_t mvPhyRegisterTable[] = {\r
++    {MV_PHY_CONTROL,                 "PHY Control                     "},\r
++    {MV_PHY_STATUS,                  "PHY Status                      "},\r
++    {MV_PHY_ID1,                     "PHY Identifier 1                "},\r
++    {MV_PHY_ID2,                     "PHY Identifier 2                "},\r
++    {MV_AUTONEG_ADVERT,              "Auto-Negotiation Advertisement  "},\r
++    {MV_LINK_PARTNER_ABILITY,        "Link Partner Ability            "},\r
++    {MV_AUTONEG_EXPANSION,           "Auto-Negotiation Expansion      "},\r
++    {MV_NEXT_PAGE_TRANSMIT,          "Next Page Transmit              "},\r
++    {MV_LINK_PARTNER_NEXT_PAGE,      "Link Partner Next Page          "},\r
++    {MV_PHY_SPECIFIC_CONTROL_1,      "PHY-Specific Control Register 1 "},\r
++    {MV_PHY_SPECIFIC_STATUS,         "PHY-Specific Status             "},\r
++    {MV_PHY_INTERRUPT_ENABLE,        "PHY Interrupt Enable            "},\r
++    {MV_PHY_INTERRUPT_STATUS,        "PHY Interrupt Status            "},\r
++    {MV_PHY_INTERRUPT_PORT_SUMMARY,  "PHY Interrupt Port Summary      "},\r
++    {MV_RECEIVE_ERROR_COUNTER,       "Receive Error Counter           "},\r
++    {MV_LED_PARALLEL_SELECT,         "LED Parallel Select             "},\r
++    {MV_LED_STREAM_SELECT_LEDS,      "LED Stream Select               "},\r
++    {MV_PHY_LED_CONTROL,             "PHY LED Control                 "},\r
++    {MV_PHY_MANUAL_LED_OVERRIDE,     "PHY Manual LED Override         "},\r
++    {MV_VCT_CONTROL,                 "VCT Control                     "},\r
++    {MV_VCT_STATUS,                  "VCT Status                      "},\r
++    {MV_PHY_SPECIFIC_CONTROL_2,      "PHY-Specific Control Register 2 "},\r
++};\r
++int mvPhyNumRegs = sizeof(mvPhyRegisterTable) / sizeof(mvPhyRegisterTable[0]);\r
++\r
++\r
++mvRegisterTableEntry_t mvSwitchPortRegisterTable[] = {\r
++    {MV_PORT_STATUS,              "Port Status             "},\r
++    {MV_SWITCH_ID,                "Switch ID               "},\r
++    {MV_PORT_CONTROL,             "Port Control            "},\r
++    {MV_PORT_BASED_VLAN_MAP,      "Port-Based VLAN Map     "},\r
++    {MV_PORT_ASSOCIATION_VECTOR,  "Port Association Vector "},\r
++    {MV_RX_COUNTER,               "RX Counter              "},\r
++    {MV_TX_COUNTER,               "TX Counter              "},\r
++};\r
++int mvSwitchPortNumRegs =\r
++    sizeof(mvSwitchPortRegisterTable) / sizeof(mvSwitchPortRegisterTable[0]);\r
++\r
++\r
++mvRegisterTableEntry_t mvSwitchGlobalRegisterTable[] = {\r
++    {MV_SWITCH_GLOBAL_STATUS,  "Switch Global Status  "},\r
++    {MV_SWITCH_MAC_ADDR0,      "Switch MAC Addr 0 & 1 "},\r
++    {MV_SWITCH_MAC_ADDR2,      "Switch MAC Addr 2 & 3 "},\r
++    {MV_SWITCH_MAC_ADDR4,      "Switch MAC Addr 4 & 5 "},\r
++    {MV_SWITCH_GLOBAL_CONTROL, "Switch Global Control "},\r
++    {MV_ATU_CONTROL,           "ATU Control           "},\r
++    {MV_ATU_OPERATION,         "ATU Operation         "},\r
++    {MV_ATU_DATA,              "ATU Data              "},\r
++    {MV_ATU_MAC_ADDR0,         "ATU MAC Addr 0 & 1    "},\r
++    {MV_ATU_MAC_ADDR2,         "ATU MAC Addr 2 & 3    "},\r
++    {MV_ATU_MAC_ADDR4,         "ATU MAC Addr 4 & 5    "},\r
++};\r
++int mvSwitchGlobalNumRegs =\r
++    sizeof(mvSwitchGlobalRegisterTable) / sizeof(mvSwitchGlobalRegisterTable[0]);\r
++\r
++\r
++/*****************************************************************************\r
++*\r
++* mv_phyShow - Dump the state of a PHY.\r
++* There are two sets of registers for each phy port:\r
++*  "phy registers" and\r
++*  "switch port registers"\r
++* We dump 'em all, plus the switch global registers.\r
++*/\r
++void\r
++mv_phyShow(int phyUnit)\r
++{\r
++    int     i;\r
++    UINT16  value;\r
++    UINT32  phyBase;\r
++    UINT32  phyAddr;\r
++    UINT32  switchPortAddr;\r
++\r
++    if (!mv_validPhyId(phyUnit)) {\r
++        return;\r
++    }\r
++\r
++    phyBase        = MV_PHYBASE(phyUnit);\r
++    phyAddr        = MV_PHYADDR(phyUnit);\r
++    switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
++\r
++    PRINTF("PHY state for PHY%d (ethmac%d, phyBase 0x%8x, phyAddr 0x%x, switchAddr 0x%x)\n",\r
++           phyUnit,\r
++           MV_ETHUNIT(phyUnit),\r
++           MV_PHYBASE(phyUnit),\r
++           MV_PHYADDR(phyUnit),\r
++           MV_SWITCH_PORT_ADDR(phyUnit));\r
++\r
++    PRINTF("PHY Registers:\n");\r
++    for (i=0; i < mvPhyNumRegs; i++) {\r
++\r
++        value = phyRegRead(phyBase, phyAddr, mvPhyRegisterTable[i].regNum);\r
++\r
++        PRINTF("Reg %02d (0x%02x) %s = 0x%08x\n",\r
++               mvPhyRegisterTable[i].regNum,\r
++               mvPhyRegisterTable[i].regNum,\r
++               mvPhyRegisterTable[i].regIdString,\r
++               value);\r
++    }\r
++\r
++    PRINTF("Switch Port Registers:\n");\r
++    for (i=0; i < mvSwitchPortNumRegs; i++) {\r
++\r
++        value = phyRegRead(phyBase, switchPortAddr,\r
++                           mvSwitchPortRegisterTable[i].regNum);\r
++\r
++        PRINTF("Reg %02d (0x%02x) %s = 0x%08x\n",\r
++               mvSwitchPortRegisterTable[i].regNum,\r
++               mvSwitchPortRegisterTable[i].regNum,\r
++               mvSwitchPortRegisterTable[i].regIdString,\r
++               value);\r
++    }\r
++\r
++    PRINTF("Switch Global Registers:\n");\r
++    for (i=0; i < mvSwitchGlobalNumRegs; i++) {\r
++\r
++        value = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
++                           mvSwitchGlobalRegisterTable[i].regNum);\r
++\r
++        PRINTF("Reg %02d (0x%02x) %s = 0x%08x\n",\r
++               mvSwitchGlobalRegisterTable[i].regNum,\r
++               mvSwitchGlobalRegisterTable[i].regNum,\r
++               mvSwitchGlobalRegisterTable[i].regIdString,\r
++               value);\r
++    }\r
++}\r
++\r
++/*****************************************************************************\r
++*\r
++* mv_phySet - Modify the value of a PHY register (debug only).\r
++*/\r
++void\r
++mv_phySet(int phyUnit, UINT32 regnum, UINT32 value)\r
++{\r
++    UINT32  phyBase;\r
++    UINT32  phyAddr;\r
++\r
++    if (mv_validPhyId(phyUnit)) {\r
++\r
++        phyBase = MV_PHYBASE(phyUnit);\r
++        phyAddr = MV_PHYADDR(phyUnit);\r
++\r
++        phyRegWrite(phyBase, phyAddr, regnum, value);\r
++    }\r
++}\r
++\r
++\r
++/*****************************************************************************\r
++*\r
++* mv_switchPortSet - Modify the value of a switch port register (debug only).\r
++*/\r
++void\r
++mv_switchPortSet(int phyUnit, UINT32 regnum, UINT32 value)\r
++{\r
++    UINT32  phyBase;\r
++    UINT32  switchPortAddr;\r
++\r
++    if (mv_validPhyId(phyUnit)) {\r
++\r
++        phyBase = MV_PHYBASE(phyUnit);\r
++        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
++\r
++        phyRegWrite(phyBase, switchPortAddr, regnum, value);\r
++    }\r
++}\r
++ \r
++/*****************************************************************************\r
++*\r
++* mv_switchGlobalSet - Modify the value of a switch global register\r
++* (debug only).\r
++*/\r
++void\r
++mv_switchGlobalSet(int phyUnit, UINT32 regnum, UINT32 value)\r
++{\r
++    UINT32  phyBase;\r
++\r
++    if (mv_validPhyId(phyUnit)) {\r
++\r
++        phyBase = MV_PHYBASE(phyUnit);\r
++\r
++        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, regnum, value);\r
++    }\r
++}\r
++\r
++/*****************************************************************************\r
++*\r
++* mv_showATUDB - Dump the contents of the Address Translation Unit DataBase\r
++* for the PHY switch associated with the specified phy.\r
++*/\r
++void\r
++mv_showATUDB(int phyUnit)\r
++{\r
++    UINT32 phyBase;\r
++    UINT16 ATUData;\r
++    UINT16 ATUMac0;\r
++    UINT16 ATUMac2;\r
++    UINT16 ATUMac4;\r
++    int portVec;\r
++    int entryState;\r
++\r
++    if (!mv_validPhyId(phyUnit)) {\r
++        PRINTF("Invalid port number: %d\n", phyUnit);\r
++        return;\r
++    }\r
++\r
++    phyBase = MV_PHYBASE(phyUnit);\r
++    \r
++    /* Wait for previous operation (if any) to complete */\r
++    mv_waitWhileATUBusy(phyBase);\r
++\r
++    /* Initialize ATU MAC to all 1's */\r
++    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0, 0xffff);\r
++    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2, 0xffff);\r
++    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4, 0xffff);\r
++\r
++    PRINTF("   MAC ADDRESS    EntryState PortVector\n");\r
++\r
++    for(;;) {\r
++        /* Tell hardware to get next MAC info */\r
++        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, \r
++                    MV_ATU_OP_GET_NEXT | MV_ATU_IS_BUSY);\r
++\r
++        mv_waitWhileATUBusy(phyBase);\r
++\r
++        ATUData = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_DATA);\r
++        entryState = (ATUData & MV_ENTRYSTATE_MASK) >> MV_ENTRYSTATE_SHIFT;\r
++\r
++        if (entryState == 0) {\r
++            /* We've hit the end of the list */\r
++            break;\r
++        }\r
++\r
++        ATUMac0 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0);\r
++        ATUMac2 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2);\r
++        ATUMac4 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4);\r
++\r
++        portVec    = (ATUData & MV_PORTVEC_MASK) >> MV_PORTVEC_SHIFT;\r
++\r
++        PRINTF("%02x:%02x:%02x:%02x:%02x:%02x    0x%02x       0x%02x\n",\r
++               ATUMac0 >> 8,    /* MAC byte 0 */\r
++               ATUMac0 & 0xff,  /* MAC byte 1 */\r
++               ATUMac2 >> 8,    /* MAC byte 2 */\r
++               ATUMac2 & 0xff,  /* MAC byte 3 */\r
++               ATUMac4 >> 8,    /* MAC byte 4 */\r
++               ATUMac4 & 0xff,  /* MAC byte 5 */\r
++               entryState,\r
++               portVec);\r
++    }\r
++}\r
++\r
++LOCAL BOOL countingGoodFrames;\r
++\r
++/*****************************************************************************\r
++*\r
++* mv_countGoodFrames - starts counting GOOD RX/TX frames per port\r
++*/\r
++void\r
++mv_countGoodFrames(int phyUnit)\r
++{\r
++    UINT32 phyBase;\r
++    UINT16 globalControl;\r
++\r
++    if (mv_validPhyId(phyUnit)) {\r
++        /*\r
++         * Guarantee that counters are cleared by\r
++         * forcing CtrMode to toggle and end on GOODFRAMES.\r
++         */\r
++\r
++        phyBase = MV_PHYBASE(phyUnit);\r
++\r
++        /* Read current Switch Global Control Register */\r
++        globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
++                                   MV_SWITCH_GLOBAL_CONTROL);\r
++\r
++        /* Set CtrMode to count BAD frames */\r
++        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |\r
++                         MV_CTRMODE_BADFRAMES);\r
++\r
++        /* Push new value out to hardware */\r
++        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
++                    MV_SWITCH_GLOBAL_CONTROL, globalControl);\r
++\r
++        /* Now toggle CtrMode to count GOOD frames */\r
++        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |\r
++                         MV_CTRMODE_GOODFRAMES);\r
++\r
++        /* Push new value out to hardware */\r
++        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
++                    MV_SWITCH_GLOBAL_CONTROL, globalControl);\r
++\r
++        countingGoodFrames = TRUE;\r
++    }\r
++}\r
++\r
++/*****************************************************************************\r
++*\r
++* mv_countBadFrames - starts counting BAD RX/TX frames per port\r
++*/\r
++void\r
++mv_countBadFrames(int phyUnit)\r
++{\r
++    UINT32 phyBase;\r
++    UINT16 globalControl;\r
++\r
++    if (mv_validPhyId(phyUnit)) {\r
++        /*\r
++         * Guarantee that counters are cleared by\r
++         * forcing CtrMode to toggle and end on BADFRAMES.\r
++         */\r
++\r
++        phyBase = MV_PHYBASE(phyUnit);\r
++\r
++        /* Read current Switch Global Control Register */\r
++        globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
++                                   MV_SWITCH_GLOBAL_CONTROL);\r
++\r
++        /* Set CtrMode to count GOOD frames */\r
++        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |\r
++                         MV_CTRMODE_GOODFRAMES);\r
++\r
++        /* Push new value out to hardware */\r
++        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
++                    MV_SWITCH_GLOBAL_CONTROL, globalControl);\r
++\r
++        /* Now toggle CtrMode to count BAD frames */\r
++        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |\r
++                         MV_CTRMODE_BADFRAMES);\r
++\r
++        /* Push new value out to hardware */\r
++        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
++                    MV_SWITCH_GLOBAL_CONTROL, globalControl);\r
++\r
++        countingGoodFrames = FALSE;\r
++    }\r
++}\r
++\r
++/*****************************************************************************\r
++*\r
++* mv_showFrameCounts - shows current GOOD/BAD Frame counts\r
++*/\r
++void\r
++mv_showFrameCounts(int phyUnit)\r
++{\r
++    UINT16 rxCounter;\r
++    UINT16 txCounter;\r
++    UINT32 phyBase;\r
++    UINT32 switchPortAddr;\r
++\r
++    if (!mv_validPhyId(phyUnit)) {\r
++        return;\r
++    }\r
++\r
++    phyBase = MV_PHYBASE(phyUnit);\r
++    switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
++\r
++    rxCounter = phyRegRead(phyBase, switchPortAddr, MV_RX_COUNTER);\r
++\r
++    txCounter = phyRegRead(phyBase, switchPortAddr, MV_TX_COUNTER);\r
++\r
++    PRINTF("port%d %s frames: receive: %05d   transmit: %05d\n",\r
++           phyUnit,\r
++           (countingGoodFrames ? "good" : "error"),\r
++           rxCounter,\r
++           txCounter);\r
++}\r
++#endif\r
+diff -urN linux-2.4.32.new/arch/mips/ar531x/mvPhy.h linux-2.4.32.new-eth/arch/mips/ar531x/mvPhy.h\r
+--- linux-2.4.32.new/arch/mips/ar531x/mvPhy.h  1970-01-01 01:00:00.000000000 +0100\r
++++ linux-2.4.32.new-eth/arch/mips/ar531x/mvPhy.h      2005-12-25 11:54:39.775382608 +0000\r
+@@ -0,0 +1,160 @@\r
++/*\r
++ * This file is subject to the terms and conditions of the GNU General Public\r
++ * License.  See the file "COPYING" in the main directory of this archive\r
++ * for more details.\r
++ *\r
++ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
++ */\r
++\r
++/*\r
++ * mvPhy.h - definitions for the ethernet PHY -- Marvell 88E6060\r
++ * All definitions in this file are operating system independent!\r
++ */\r
++\r
++#ifndef MVPHY_H\r
++#define MVPHY_H\r
++\r
++/*****************/\r
++/* PHY Registers */\r
++/*****************/\r
++#define MV_PHY_CONTROL                 0\r
++#define MV_PHY_STATUS                  1\r
++#define MV_PHY_ID1                     2\r
++#define MV_PHY_ID2                     3\r
++#define MV_AUTONEG_ADVERT              4\r
++#define MV_LINK_PARTNER_ABILITY        5\r
++#define MV_AUTONEG_EXPANSION           6\r
++#define MV_NEXT_PAGE_TRANSMIT          7\r
++#define MV_LINK_PARTNER_NEXT_PAGE      8\r
++#define MV_PHY_SPECIFIC_CONTROL_1     16\r
++#define MV_PHY_SPECIFIC_STATUS        17\r
++#define MV_PHY_INTERRUPT_ENABLE       18\r
++#define MV_PHY_INTERRUPT_STATUS       19\r
++#define MV_PHY_INTERRUPT_PORT_SUMMARY 20\r
++#define MV_RECEIVE_ERROR_COUNTER      21\r
++#define MV_LED_PARALLEL_SELECT        22\r
++#define MV_LED_STREAM_SELECT_LEDS     23\r
++#define MV_PHY_LED_CONTROL            24\r
++#define MV_PHY_MANUAL_LED_OVERRIDE    25\r
++#define MV_VCT_CONTROL                26\r
++#define MV_VCT_STATUS                 27\r
++#define MV_PHY_SPECIFIC_CONTROL_2     28\r
++\r
++/* MV_PHY_CONTROL fields */\r
++#define MV_CTRL_SOFTWARE_RESET                    0x8000\r
++#define MV_CTRL_AUTONEGOTIATION_ENABLE            0x1000\r
++\r
++/* MV_PHY_ID1 fields */\r
++#define MV_PHY_ID1_EXPECTATION                    0x0141 /* OUI >> 6 */\r
++\r
++/* MV_PHY_ID2 fields */\r
++#define MV_OUI_LSB_MASK                           0xfc00\r
++#define MV_OUI_LSB_EXPECTATION                    0x0c00\r
++#define MV_OUI_LSB_SHIFT                              10\r
++#define MV_MODEL_NUM_MASK                         0x03f0\r
++#define MV_MODEL_NUM_SHIFT                             4\r
++#define MV_REV_NUM_MASK                           0x000f\r
++#define MV_REV_NUM_SHIFT